11 KiB
MotoVaultPro GitLab CI/CD Deployment Guide
Complete guide for deploying MotoVaultPro using GitLab CI/CD with shell executor runners.
Table of Contents
- Prerequisites
- GitLab Runner Setup
- CI/CD Variables Configuration
- Secrets Architecture
- Pipeline Overview
- Deployment Process
- Rollback Procedure
- Troubleshooting
Prerequisites
Server Requirements
- Linux server with Docker Engine installed
- Docker Compose v2 (plugin version)
- GitLab Runner installed and registered
- Git installed
- curl installed (for health checks)
GitLab Requirements
- GitLab 18.6+ (tested with 18.6.2)
- Project with CI/CD enabled
- Protected
mainbranch - Maintainer access for CI/CD variable configuration
GitLab Runner Setup
1. Verify Runner Registration
sudo gitlab-runner verify
Expected output should show your runner as active with shell executor.
2. Verify Docker Permissions
The gitlab-runner user must have Docker access:
# Add gitlab-runner to docker group (if not already done)
sudo usermod -aG docker gitlab-runner
# Verify access
sudo -u gitlab-runner docker info
sudo -u gitlab-runner docker compose version
3. Verify Deployment Directory
Ensure the deployment directory exists and is accessible:
# Create deployment directory
sudo mkdir -p /opt/motovaultpro
sudo chown gitlab-runner:gitlab-runner /opt/motovaultpro
# Clone repository (first time only)
sudo -u gitlab-runner git clone <repository-url> /opt/motovaultpro
CI/CD Variables Configuration
Navigate to Settings > CI/CD > Variables in your GitLab project.
Secrets (File Type Variables)
These variables use GitLab's File type, which writes the value to a temporary file and provides the path as the environment variable. This replicates the Kubernetes secrets pattern used by the application.
| Variable Name | Type | Protected | Masked | Description |
|---|---|---|---|---|
POSTGRES_PASSWORD |
File | Yes | Yes | PostgreSQL database password |
AUTH0_CLIENT_SECRET |
File | Yes | Yes | Auth0 client secret for backend |
GOOGLE_MAPS_API_KEY |
File | Yes | Yes | Google Maps API key |
GOOGLE_MAPS_MAP_ID |
File | Yes | No | Google Maps Map ID |
Configuration Variables
| Variable Name | Type | Protected | Masked | Value |
|---|---|---|---|---|
VITE_AUTH0_DOMAIN |
Variable | No | No | motovaultpro.us.auth0.com |
VITE_AUTH0_CLIENT_ID |
Variable | No | No | Your Auth0 client ID |
VITE_AUTH0_AUDIENCE |
Variable | No | No | https://api.motovaultpro.com |
Note: DEPLOY_PATH is automatically set in .gitlab-ci.yml using GIT_CLONE_PATH for a stable path.
Setting Up a File Type Variable
- Go to Settings > CI/CD > Variables
- Click Add variable
- Enter the variable key (e.g.,
POSTGRES_PASSWORD) - Enter the secret value in the Value field
- Set Type to File
- Enable Protect variable (recommended)
- Enable Mask variable (for sensitive data)
- Click Add variable
Secrets Architecture
MotoVaultPro uses a Kubernetes-style secrets pattern where secrets are mounted as files at /run/secrets/ inside containers.
How It Works
- GitLab stores secrets as File type CI/CD variables
- During pipeline execution, GitLab writes each secret to a temporary file
- The
inject-secrets.shscript copies these files tosecrets/app/directory - Docker Compose mounts these files to
/run/secrets/in containers - Application code reads secrets from the filesystem (not environment variables)
Secret Files
secrets/app/
postgres-password.txt -> /run/secrets/postgres-password
auth0-client-secret.txt -> /run/secrets/auth0-client-secret
google-maps-api-key.txt -> /run/secrets/google-maps-api-key
google-maps-map-id.txt -> /run/secrets/google-maps-map-id
Security Benefits
- Secrets never appear as environment variables (not visible in
envorprintenv) - File permissions (600) restrict access
- Masked variables prevent accidental log exposure
- Protected variables only available on protected branches
Pipeline Overview
The CI/CD pipeline consists of four stages:
Stage 1: Validate
Verifies deployment prerequisites:
- Docker is accessible
- Docker Compose is available
- Deployment directory exists
Stage 2: Build
Builds Docker images:
- Pulls latest code from repository
- Builds all service images with
--no-cache
Stage 3: Deploy
Deploys the application:
- Injects secrets from GitLab variables
- Stops existing services gracefully
- Pulls base images
- Starts database services (PostgreSQL, Redis)
- Runs database migrations
- Starts all services
Stage 4: Verify
Validates deployment health:
- Checks all containers are running
- Tests backend health endpoint
- Reports deployment status
Pipeline Diagram
[Validate] -> [Build] -> [Deploy] -> [Verify]
| | | |
Check Build Inject Health
prereqs images secrets checks
|
Migrate
|
Start
services
Deployment Process
Automatic Deployment
Deployments are triggered automatically when:
- Code is pushed to the
mainbranch - A merge request is merged into
main
Manual Deployment
To trigger a manual deployment:
- Go to CI/CD > Pipelines
- Click Run pipeline
- Select the
mainbranch - Click Run pipeline
Deployment Steps (What Happens)
-
Secrets Injection
inject-secrets.shcopies GitLab File variables tosecrets/app/- Permissions are set to 600 for security
-
Service Shutdown
- Existing containers are stopped gracefully (30s timeout)
- Volumes are preserved
-
Database Startup
- PostgreSQL and Redis start first
- 15-second wait for database readiness
-
Migrations
- Backend container runs database migrations
- Ensures schema is up-to-date
-
Full Service Startup
- All services start via
docker compose up -d - Traefik routes traffic automatically
- All services start via
-
Health Verification
- Container status checks
- Backend health endpoint validation
Rollback Procedure
Automatic Rollback
If the verify stage fails, the pipeline will report failure but services remain running. Manual intervention is required.
Manual Rollback
Use the rollback script:
# SSH to server
ssh user@server
# Run rollback to previous commit
cd /opt/motovaultpro
./scripts/rollback.sh HEAD~1
# Or rollback to specific tag/commit
./scripts/rollback.sh v1.0.0
Rollback Script Details
The script performs:
- Stops all current services
- Checks out the specified version
- Rebuilds images
- Starts services
Emergency Recovery
If rollback fails:
cd /opt/motovaultpro
# Stop everything
docker compose down
# Check git history
git log --oneline -10
# Checkout known working version
git checkout <commit-hash>
# Rebuild and start
docker compose build
docker compose up -d
# Verify
docker compose ps
Troubleshooting
Pipeline Fails at Validate Stage
Symptom: DEPLOY_PATH not found
Solution:
# Create directory on runner server
sudo mkdir -p /opt/motovaultpro
sudo chown gitlab-runner:gitlab-runner /opt/motovaultpro
Pipeline Fails at Build Stage
Symptom: Docker build errors
Solutions:
- Check Dockerfile syntax
- Verify network connectivity for npm/package downloads
- Check disk space:
df -h - Clear Docker cache:
docker system prune -a
Pipeline Fails at Deploy Stage
Symptom: Secrets injection fails
Solutions:
- Verify CI/CD variables are configured correctly
- Check variable types are set to File for secrets
- Ensure variables are not restricted to specific environments
Symptom: Migration fails
Solutions:
- Check database connectivity
- Verify PostgreSQL is healthy:
docker logs mvp-postgres - Run migrations manually:
docker compose exec mvp-backend npm run migrate
Pipeline Fails at Verify Stage
Symptom: Container not running
Solutions:
- Check container logs:
docker logs <container-name> - Verify secrets are correctly mounted
- Check for port conflicts
Symptom: Health check fails
Solutions:
- Wait longer (service might be starting)
- Check backend logs:
docker logs mvp-backend - Verify database connection
Services Start But Application Doesn't Work
Check secrets are mounted:
docker compose exec mvp-backend ls -la /run/secrets/
Check configuration:
docker compose exec mvp-backend cat /app/config/production.yml
Check network connectivity:
docker network ls
docker network inspect motovaultpro_backend
Viewing Logs
# All services
docker compose logs -f
# Specific service
docker compose logs -f mvp-backend
# Last 100 lines
docker compose logs --tail 100 mvp-backend
Maintenance
Updating Secrets
- Update the CI/CD variable in GitLab
- Trigger a new pipeline (push or manual)
- The new secrets will be injected during deployment
Database Backups
Backups should be configured separately. Recommended approach:
# Manual backup
docker compose exec mvp-postgres pg_dump -U postgres motovaultpro > backup.sql
# Automated backup (add to cron)
0 2 * * * cd /opt/motovaultpro && docker compose exec -T mvp-postgres pg_dump -U postgres motovaultpro > /backups/mvp-$(date +\%Y\%m\%d).sql
Monitoring
Consider adding:
- Prometheus metrics (Traefik already configured)
- Health check alerts
- Log aggregation
Quick Reference
Common Commands
# View pipeline status
# GitLab UI: CI/CD > Pipelines
# SSH to server
ssh user@your-server
# Navigate to project
cd /opt/motovaultpro
# View running containers
docker compose ps
# View logs
docker compose logs -f
# Restart a service
docker compose restart mvp-backend
# Run migrations manually
docker compose exec mvp-backend npm run migrate
# Access database
docker compose exec mvp-postgres psql -U postgres motovaultpro
# Health check
curl http://localhost:3001/health
Important Paths
| Path | Description |
|---|---|
$CI_BUILDS_DIR/motovaultpro |
Application root (stable clone path) |
$CI_BUILDS_DIR/motovaultpro/secrets/app/ |
Secrets directory |
$CI_BUILDS_DIR/motovaultpro/data/documents/ |
Document storage |
$CI_BUILDS_DIR/motovaultpro/config/ |
Configuration files |
Note: CI_BUILDS_DIR is typically /opt/gitlab-runner/builds for shell executors.
Container Names
| Container | Purpose |
|---|---|
mvp-traefik |
Reverse proxy, TLS termination |
mvp-frontend |
React SPA |
mvp-backend |
Node.js API |
mvp-postgres |
PostgreSQL database |
mvp-redis |
Redis cache |