# 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