Appearance
Frontend CI/CD: Nuxt Deployment from GitLab
Updated: 2026-03-10 (migrated from PM2 to Docker, two-VPS architecture)
Overview
The Nuxt frontend lives in its own GitLab repo (root/partizap-frontend) and runs as Docker containers on both VPS servers. Nginx proxies / to the Nuxt container and /api/* to PHP-FPM.
Architecture
| VPS 1 — Production | VPS 2 — Development | |
|---|---|---|
| Container | partizap-frontend-prod | partizap-frontend-dev |
| Port | 3001 | 3000 |
| Docker Compose | /opt/partizap-frontend/docker-compose.prod.yml | /opt/partizap-frontend/docker-compose.dev.yml |
| Domain | partizap.ru | dev.partizap.ru |
Docker Compose Configs
Production (/opt/partizap-frontend/docker-compose.prod.yml on VPS 1)
yaml
services:
frontend:
image: partizap-frontend-prod:latest
container_name: partizap-frontend-prod
restart: unless-stopped
ports:
- "3001:3000"
environment:
- NUXT_API_BASE_SERVER=https://partizap.ru/api
- NUXT_PUBLIC_CENTRIFUGO_URL=wss://partizap.ru/connection/websocket
deploy:
resources:
limits:
memory: 512MDevelopment (/opt/partizap-frontend/docker-compose.dev.yml on VPS 2)
yaml
services:
frontend:
image: partizap-frontend-dev:latest
container_name: partizap-frontend-dev
restart: unless-stopped
ports:
- "3000:3000"
environment:
- NUXT_API_BASE_SERVER=https://dev.partizap.ru/api
- NUXT_PUBLIC_CENTRIFUGO_URL=wss://dev.partizap.ru/connection/websocket
deploy:
resources:
limits:
memory: 512MNginx Config
Production (VPS 1, partizap.ru) — proxy to container on port 3001:
nginx
location / {
proxy_pass http://127.0.0.1:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}Development (VPS 2, dev.partizap.ru) — proxy to container on port 3000:
nginx
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}GitLab CI/CD
Required Variables (GitLab > Settings > CI/CD > Variables)
| Variable | Value | Protected | Masked |
|---|---|---|---|
GITLAB_TOKEN | Personal access token | Yes | Yes |
Frontend Deploy Process
The frontend CI/CD pipeline builds a Docker image, exports it, transfers to the target VPS, and restarts the container.
The frontend repo (root/partizap-frontend, project ID 2) has its own .gitlab-ci.yml. The deploy steps:
npm ci && npm run build— build Nuxtdocker build— create imagedocker save— export image as tar- Transfer image to target VPS
docker load— import image on targetdocker compose up -d— restart container
Deploy to dev (VPS 2, local)
Since the runner and dev environment are on the same VPS 2:
bash
docker compose -f /opt/partizap-frontend/docker-compose.dev.yml up -dDeploy to prod (VPS 1, via SSH)
Runner on VPS 2 transfers the image to VPS 1 via SSH:
bash
docker save partizap-frontend-prod:latest | ssh serpens@192.168.0.4 'docker load'
ssh serpens@192.168.0.4 'cd /opt/partizap-frontend && docker compose -f docker-compose.prod.yml up -d'Manual Operations
Rebuild and restart (dev)
bash
# On VPS 2
cd /opt/partizap-frontend
docker compose -f docker-compose.dev.yml down
docker compose -f docker-compose.dev.yml up -dRebuild and restart (prod)
bash
# On VPS 1
cd /opt/partizap-frontend
docker compose -f docker-compose.prod.yml down
docker compose -f docker-compose.prod.yml up -dView logs
bash
docker logs partizap-frontend-prod -f --tail 50 # VPS 1
docker logs partizap-frontend-dev -f --tail 50 # VPS 2