Skip to content

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 — ProductionVPS 2 — Development
Containerpartizap-frontend-prodpartizap-frontend-dev
Port30013000
Docker Compose/opt/partizap-frontend/docker-compose.prod.yml/opt/partizap-frontend/docker-compose.dev.yml
Domainpartizap.rudev.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: 512M

Development (/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: 512M

Nginx 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)

VariableValueProtectedMasked
GITLAB_TOKENPersonal access tokenYesYes

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:

  1. npm ci && npm run build — build Nuxt
  2. docker build — create image
  3. docker save — export image as tar
  4. Transfer image to target VPS
  5. docker load — import image on target
  6. docker 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 -d

Deploy 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 -d

Rebuild 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 -d

View logs

bash
docker logs partizap-frontend-prod -f --tail 50   # VPS 1
docker logs partizap-frontend-dev -f --tail 50     # VPS 2