CPI Documentation
Deployment

Deployment

Docker, CI/CD pipeline, and production infrastructure for the CPI platform.

Infrastructure Overview

ComponentTechnologyURL
Admin DashboardReact SPA (nginx)cpi.lovinka.com
APINestJS (Node.js)api.cpi.lovinka.com
DocumentationFumadocs (Next.js)docs.cpi.lovinka.com
MQTT BrokerMosquittomqtt.cpi.lovinka.com:8883/8885
DatabasePostgreSQL 16 + TimescaleDBInternal
CacheRedis 7Internal

All services run as Docker containers on a Hetzner Cloud VPS behind an nginx reverse proxy with Let's Encrypt SSL.

Docker Images

Images are built and pushed to GitHub Container Registry (GHCR):

ImageSource
ghcr.io/lefteq/cpi-apiapps/api/Dockerfile
ghcr.io/lefteq/cpi-adminapps/admin/Dockerfile
ghcr.io/lefteq/cpi-docsapps/docs/Dockerfile

All images use multi-stage builds:

  1. Prunerturbo prune isolates the workspace
  2. Installer — install deps and build
  3. Runner — minimal production image

CI/CD Pipeline

CI (ci.yml)

Triggered on push to main and pull requests:

  1. Lint, Typecheck & Build — runs on all PRs and pushes
  2. Build & Push Docker Images — only on main push, pushes to GHCR
  3. Docker Build Validation — on PRs, validates Docker builds without pushing

Deploy (deploy.yml)

Manual dispatch workflow:

  1. Generates .env file on VPS from GitHub secrets
  2. Pulls Docker images from GHCR
  3. Restarts services with docker compose up -d
  4. Runs health checks against production URLs

Production Docker Compose

The production stack (docker/docker-compose.prod.yml) includes:

  • cpi-postgres — TimescaleDB with persistent volume
  • cpi-redis — Redis with password auth
  • cpi-mosquitto — MQTT broker with TLS certificates
  • cpi-api — NestJS API (depends on postgres + redis + mosquitto)
  • cpi-admin — React SPA served by nginx
  • cpi-docs — Next.js documentation site

Database Migrations

Migrations run automatically on API container startup (migrationsRun: true). No manual migration step needed during deployment.

Migration files are in apps/api/src/database/migrations/.

Always ensure the migration files are included in the Docker image. TypeORM will fail to start if migrations are missing.

Environment Variables

Key environment variables for production:

VariableDescription
DATABASE_URLPostgreSQL connection string
REDIS_HOST, REDIS_PASSWORDRedis connection
JWT_SECRETWeb API JWT signing key
MQTT_JWT_SECRETMQTT JWT signing key (separate from web)
MQTT_USERNAME, MQTT_PASSWORDInternal MQTT credentials
HMAC_ENCRYPTION_KEYAES-256 key for HMAC secret encryption at rest
ADMIN_URLCORS origin for admin dashboard
SMTP_*Email notification settings

Health Checks

ServiceEndpoint
APIGET /api/v1/health
AdminGET / (200 OK)
DocsGET /docs (200 OK)
PostgreSQLpg_isready
Redisredis-cli ping

Local Development

pnpm docker:up      # Start infrastructure
pnpm dev:apps        # Start API + Admin
pnpm dev:docs        # Start documentation site

See Getting Started for full setup instructions.

On this page