Skip to content

Docker Architecture

This page is derived from docker-compose.yml and docker-compose.prod.yml; it contains no guessed information.

Services (docker-compose.yml)

Service Container name Image / build Ports (host) Volumes Network Restart
mongo ${COMPOSE_PROJECT_NAME:-iqvflex}-mongo mongo:7 127.0.0.1:${MONGO_PORT:-27017}:27017 mongo_data:/data/db, mongo_config:/data/configdb iqv_network unless-stopped
backend ${COMPOSE_PROJECT_NAME:-iqvflex}-backend build: ./iqvflex/backend (Dockerfile) 127.0.0.1:${BACKEND_PORT:-3001}:3001 — iqv_network unless-stopped
frontend ${COMPOSE_PROJECT_NAME:-iqvflex}-frontend build: ./dashboard (Dockerfile) ${FRONTEND_PORT:-8080}:80 — iqv_network unless-stopped

The mongo service only runs with the managed-mongo profile (profiles: ['managed-mongo']); when using an external MongoDB, clear COMPOSE_PROFILES in .env and the service never starts (required: false keeps the compose file valid regardless).

Environment variable usage

Variables passed to the backend (summary): NODE_ENV, PORT, CORS_ORIGIN, MONGODB_URI (falls back to the compose-managed MongoDB if unset), MONGODB_DATABASE, MONGODB_ERP_MAPPING_COLLECTION, MONGODB_ERP_USERS_COLLECTION, MONGODB_AUTH_SOURCE, MONGODB_APP_NAME, ERP_AUTH_SECRET (required), ERP_AUTH_TOKEN_TTL_SECONDS, GO_API_BASE_URL (required), GO_API_TIMEOUT_MS, GO_API_CLIENT_ID, GO_API_CLIENT_SECRET, GO_API_TOKEN_PATH.

The frontend image receives the VITE_API_BASE_URL build-arg; left empty in a Docker deployment (the SPA reaches the backend through the nginx proxy on the same origin).

Healthchecks

Service Check Interval / start_period / retries
mongo mongosh --quiet --eval "db.adminCommand('ping').ok" 15s / 40s / 5
backend Node's own fetch against http://127.0.0.1:3001/health → data.status === 'ok' 15s / 40s / 5
frontend wget against http://127.0.0.1/__nginx_health 15s / 10s / 5

frontend depends on backend being service_healthy, and backend (when the profile is enabled) depends on mongo being service_healthy (depends_on: condition: service_healthy).

Network and logging

All services run on a single bridge network (iqv_network). All services share the json-file log driver (max-size: 10m, max-file: 5) to prevent disk exhaustion.

Hardened production override (docker-compose.prod.yml)

docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

(install.sh --profile prod / install.ps1 -Profile prod applies this automatically.) Differences:

  • mongo and backend ports are never exposed externally (ports: !override []).
  • The backend root filesystem is read-only (read_only: true), only /tmp is writable (tmpfs).
  • no-new-privileges:true on backend and frontend.
  • Memory limits: mongo 2g, backend 1g, frontend 512m.
  • All services use restart: always.

The single entry point is always nginx (frontend service, host port FRONTEND_PORT, default 8080).