Files
Docker-Swarm-Services/proxcenter-compose.yml

164 lines
5.8 KiB
YAML

# ============================================
# ProxCenter Community Edition — Docker Swarm Stack
# ============================================
# Deploy (do NOT run until volumes/secrets exist):
# set -a; . ./proxcenter.env; set +a
# docker stack deploy -c proxcenter-compose.yml proxcenter
#
# Alternative if you prefer to render with docker compose first:
# docker compose --env-file proxcenter.env -f proxcenter-compose.yml config \
# | docker stack deploy -c - proxcenter
#
# Prerequisites — create external volumes before first deploy:
# docker volume create proxcenter_data
# docker volume create postgres_data
#
# Named volumes in Swarm are node-local by default. Both services are
# pinned to a labeled node so proxcenter_data and postgres_data stay on
# the same host. Label the intended primary Swarm node before deploying:
# docker node update --label-add proxcenter.storage=true <NODE_NAME>
# If you use a distributed volume driver (NFS/Longhorn/etc.), remove or
# change the placement constraints.
#
# Optional: use Docker Secrets instead of env vars for sensitive values.
# Create secrets before deploying, then uncomment the secrets: blocks:
# printf 'your-app-secret' | docker secret create app_secret -
# printf 'your-nextauth-secret' | docker secret create nextauth_secret -
# Then in the frontend service, swap the APP_SECRET / NEXTAUTH_SECRET
# env vars for APP_SECRET_FILE / NEXTAUTH_SECRET_FILE and uncomment
# the secrets: section on the service and at the bottom of this file.
# ============================================
services:
# ========================================
# Frontend (Next.js + WebSocket Proxy)
# ========================================
frontend:
image: ghcr.io/adminsyspro/proxcenter-frontend:${VERSION:-latest}
ports:
- "3020:3000"
environment:
- NODE_ENV=production
# Build the Postgres connection string from individual vars so
# POSTGRES_PASSWORD only needs to be set once (not duplicated in DATABASE_URL).
- DATABASE_URL=postgresql://${POSTGRES_USER:-proxcenter}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-proxcenter}?schema=public
- APP_SECRET=${APP_SECRET}
- NEXTAUTH_SECRET=${NEXTAUTH_SECRET}
- NEXTAUTH_URL=${NEXTAUTH_URL:-http://localhost:3000}
- APP_URL=${APP_URL:-http://localhost:3000}
# Docker Secrets alternative — comment out APP_SECRET / NEXTAUTH_SECRET above
# and uncomment these if you prefer file-based secrets:
# - APP_SECRET_FILE=/run/secrets/app_secret
# - NEXTAUTH_SECRET_FILE=/run/secrets/nextauth_secret
volumes:
- ${DockerData}/proxcenter/frontend_data:/app/data
# secrets:
# - app_secret
# - nextauth_secret
networks:
- proxcenter
# depends_on is intentionally omitted: it is ignored by docker stack deploy.
# Swarm relies on healthcheck + restart_policy to handle startup ordering.
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:3000/api/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
deploy:
replicas: 1
placement:
constraints:
# Keep the node-local proxcenter_data volume on the intended primary node.
- node.platform.os == linux
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 5
window: 120s
update_config:
parallelism: 1
delay: 10s
order: start-first
failure_action: rollback
rollback_config:
parallelism: 1
delay: 5s
# ========================================
# Postgres (application database)
# ========================================
postgres:
image: postgres:16-alpine
environment:
- POSTGRES_USER=${POSTGRES_USER:-proxcenter}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=${POSTGRES_DB:-proxcenter}
- POSTGRES_INITDB_ARGS=--encoding=UTF8 --locale=C
volumes:
- ${DockerData}/proxcenter/postgres_data:/var/lib/postgresql/data
# Port is intentionally not published. Postgres is reachable only
# over the internal overlay network. Uncomment to expose for debugging:
# ports:
# - "127.0.0.1:5432:5432"
networks:
- proxcenter
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-proxcenter} -d ${POSTGRES_DB:-proxcenter}"]
interval: 10s
timeout: 5s
retries: 5
start_period: 20s
deploy:
replicas: 1
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 5
window: 120s
update_config:
parallelism: 1
delay: 10s
# stop-first so the old container releases its data dir before the new one starts
order: stop-first
failure_action: rollback
rollback_config:
parallelism: 1
delay: 5s
placement:
constraints:
# Keep the node-local postgres_data volume on the intended primary node.
- node.platform.os == linux
# ========================================
# Networks
# ========================================
networks:
proxcenter:
driver: overlay
attachable: true
# ========================================
# Volumes (must be created externally)
# ========================================
# docker volume create proxcenter_data
# docker volume create postgres_data
volumes:
proxcenter_data:
external: true
postgres_data:
external: true
# ========================================
# Secrets (uncomment after creating them)
# ========================================
# printf 'your-app-secret' | docker secret create app_secret -
# printf 'your-nextauth-secret' | docker secret create nextauth_secret -
#
# secrets:
# app_secret:
# external: true
# nextauth_secret:
# external: true