Files
ModelForge/docker-compose.production.yml
T

76 lines
3.8 KiB
YAML

# ITWorx ModelForge — production overlay.
#
# The authoritative production deployment is:
#
# docker compose -f docker-compose.yml -f docker-compose.production.yml up -d
#
# The base file leaves MODELFORGE_ENV at its "development" default and builds images from the
# working tree. It still requires separate database secrets; this overlay additionally turns on
# every production startup rule and requires immutable release identities.
#
# Every secret here uses the ${VAR:?message} form, so Compose refuses to render the project at all
# when one is missing. Failing before the first container starts is the cheapest possible failure.
services:
postgres:
environment:
POSTGRES_DB: ${MODELFORGE_POSTGRES_DB:?set the production database name}
POSTGRES_USER: ${MODELFORGE_POSTGRES_ADMIN_USER:-postgres}
POSTGRES_PASSWORD: ${MODELFORGE_POSTGRES_ADMIN_PASSWORD:?generate a bootstrap-only admin password; see docs/CONFIGURATION.md}
MODELFORGE_MIGRATION_DB_PASSWORD: ${MODELFORGE_MIGRATION_DB_PASSWORD:?generate a migration-owner password}
MODELFORGE_RUNTIME_DB_PASSWORD: ${MODELFORGE_RUNTIME_DB_PASSWORD:?generate a distinct runtime password}
healthcheck:
test:
- CMD-SHELL
- pg_isready -U ${MODELFORGE_POSTGRES_ADMIN_USER:-postgres} -d ${MODELFORGE_POSTGRES_DB}
# PostgreSQL needs to write its data directory and its own runtime sockets, so it is not
# read-only, but it has no reason to keep any capability beyond the ones it drops privileges
# with.
security_opt:
- no-new-privileges:true
restart: unless-stopped
redis:
security_opt:
- no-new-privileges:true
restart: unless-stopped
api:
image: ${MODELFORGE_API_IMAGE:-modelforge-api:${MODELFORGE_VERSION:?set an exact release version, for example 1.2.1}}
build:
context: ./backend
args:
MODELFORGE_VERSION: ${MODELFORGE_VERSION:-0.0.0}
MODELFORGE_COMMIT: ${MODELFORGE_COMMIT:-}
MODELFORGE_BUILT_AT: ${MODELFORGE_BUILT_AT:-}
environment:
# The single setting that turns on every production rule in startup validation. Without it a
# production deployment silently runs under development semantics.
MODELFORGE_ENV: production
MODELFORGE_DATABASE_URL: ${MODELFORGE_RUNTIME_DATABASE_URL:?set a URL for only the modelforge_runtime role}
MODELFORGE_OPERATOR_API_KEY: ${MODELFORGE_OPERATOR_API_KEY:?generate an operator API key; see docs/CONFIGURATION.md}
MODELFORGE_BACKUP_ENCRYPTION_KEY: ${MODELFORGE_BACKUP_ENCRYPTION_KEY:?generate a backup encryption key; without it no backup can be produced}
MODELFORGE_CORS_ORIGINS: ${MODELFORGE_CORS_ORIGINS:?set the exact console origin; a wildcard is refused in production}
# Remote model code is never executed in production. Stated here as well as enforced at
# startup, so the deployment reads the same way the platform behaves.
MODELFORGE_ALLOW_REMOTE_CODE: "false"
MODELFORGE_RESTORE_ALLOW_PRODUCTION_TARGET: "false"
MODELFORGE_BUILD_IMAGE_DIGEST: ${MODELFORGE_API_IMAGE_DIGEST:-}
restart: unless-stopped
migrate:
image: ${MODELFORGE_API_IMAGE:-modelforge-api:${MODELFORGE_VERSION:?set an exact release version, for example 1.2.1}}
environment:
MODELFORGE_ENV: production
MODELFORGE_MIGRATION_DATABASE_URL: ${MODELFORGE_MIGRATION_DATABASE_URL:?set a URL for only the non-superuser modelforge owner role}
web:
image: ${MODELFORGE_WEB_IMAGE:-modelforge-web:${MODELFORGE_VERSION:?set an exact release version, for example 1.2.1}}
build:
context: ./frontend
args:
VITE_API_BASE_URL: ${VITE_API_BASE_URL:?set the API base URL the console is served against}
MODELFORGE_VERSION: ${MODELFORGE_VERSION:-0.0.0}
MODELFORGE_COMMIT: ${MODELFORGE_COMMIT:-}
MODELFORGE_BUILT_AT: ${MODELFORGE_BUILT_AT:-}
restart: unless-stopped