142 lines
5.2 KiB
YAML
142 lines
5.2 KiB
YAML
services:
|
|
migrate:
|
|
build:
|
|
context: .
|
|
dockerfile: backend/Dockerfile
|
|
restart: "no"
|
|
command:
|
|
- uv
|
|
- run
|
|
- --frozen
|
|
- --package
|
|
- backend
|
|
- alembic
|
|
- upgrade
|
|
- head
|
|
environment:
|
|
DATABASE_URL: ${DATABASE_URL:?DATABASE_URL is required}
|
|
|
|
web:
|
|
build:
|
|
context: .
|
|
dockerfile: frontend/Dockerfile
|
|
restart: unless-stopped
|
|
# Architecture §2.2: this is the only service exposed to the host. The
|
|
# default.conf file is mounted as a template; scripts/nginx-entrypoint.sh
|
|
# parses ${RUSTFS_ENDPOINT} and writes the rendered config to
|
|
# /etc/nginx/conf.d/default.conf before exec'ing nginx.
|
|
ports:
|
|
- "${GATEWAY_PORT:-8888}:80"
|
|
environment:
|
|
RUSTFS_ENDPOINT: ${RUSTFS_ENDPOINT:?RUSTFS_ENDPOINT is required}
|
|
depends_on:
|
|
backend:
|
|
condition: service_healthy
|
|
runtime:
|
|
condition: service_healthy
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1/ >/dev/null"]
|
|
interval: 10s
|
|
timeout: 3s
|
|
retries: 12
|
|
start_period: 10s
|
|
|
|
backend:
|
|
build:
|
|
context: .
|
|
dockerfile: backend/Dockerfile
|
|
restart: unless-stopped
|
|
# No host port: architecture §2.2 — only Nginx is externally reachable.
|
|
# No local-FS volume: backend stores everything in RustFS (RUSTFS_*).
|
|
environment:
|
|
DATABASE_URL: ${DATABASE_URL:?DATABASE_URL is required}
|
|
SERVICE_NAME: model-platform-backend
|
|
JWT_SECRET: ${JWT_SECRET:?JWT_SECRET is required}
|
|
DEMO_AUTH_ENABLED: ${DEMO_AUTH_ENABLED:-false}
|
|
RUNTIME_API_URL: http://runtime:8000
|
|
RUSTFS_ENDPOINT: ${RUSTFS_ENDPOINT:?RUSTFS_ENDPOINT is required}
|
|
RUSTFS_ACCESS_KEY: ${RUSTFS_ACCESS_KEY:?RUSTFS_ACCESS_KEY is required}
|
|
RUSTFS_SECRET_KEY: ${RUSTFS_SECRET_KEY:?RUSTFS_SECRET_KEY is required}
|
|
RUSTFS_WORKSPACE_BUCKET: ${RUSTFS_WORKSPACE_BUCKET:-workspaces}
|
|
RUSTFS_VERSION_BUCKET: ${RUSTFS_VERSION_BUCKET:-versions}
|
|
RUSTFS_RUN_LOG_BUCKET: ${RUSTFS_RUN_LOG_BUCKET:-run-logs}
|
|
READINESS_TARGETS: ${MYSQL_HOST:?MYSQL_HOST is required}:${MYSQL_PORT:-3306},${RUSTFS_HOST:?RUSTFS_HOST is required}:${RUSTFS_PORT:-9000},runtime:8000
|
|
depends_on:
|
|
migrate:
|
|
condition: service_completed_successfully
|
|
runtime:
|
|
condition: service_healthy
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "curl -fsS http://127.0.0.1:8000/health/ready >/dev/null"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 18
|
|
start_period: 20s
|
|
|
|
runtime:
|
|
build:
|
|
context: .
|
|
dockerfile: runtime/Dockerfile
|
|
restart: unless-stopped
|
|
cap_add:
|
|
- SYS_ADMIN
|
|
devices:
|
|
- /dev/fuse:/dev/fuse
|
|
security_opt:
|
|
- apparmor:unconfined
|
|
# No host port: architecture §2.2 — only Nginx is externally reachable.
|
|
environment:
|
|
DATABASE_URL: ${DATABASE_URL:?DATABASE_URL is required}
|
|
SERVICE_NAME: runtime-manager
|
|
WORKSPACES_ROOT: /workspace/workspaces
|
|
PUBLIC_BASE_URL: http://runtime
|
|
REMOTE_BUCKET: rustfs:${RUSTFS_WORKSPACE_BUCKET:-workspaces}
|
|
RCLONE_CONFIG_RUSTFS_TYPE: s3
|
|
RCLONE_CONFIG_RUSTFS_PROVIDER: Other
|
|
RCLONE_CONFIG_RUSTFS_ACCESS_KEY_ID: ${RUSTFS_ACCESS_KEY:?RUSTFS_ACCESS_KEY is required}
|
|
RCLONE_CONFIG_RUSTFS_SECRET_ACCESS_KEY: ${RUSTFS_SECRET_KEY:?RUSTFS_SECRET_KEY is required}
|
|
RCLONE_CONFIG_RUSTFS_ENDPOINT: ${RUSTFS_ENDPOINT:?RUSTFS_ENDPOINT is required}
|
|
RCLONE_CONFIG_RUSTFS_ENV_AUTH: "false"
|
|
RCLONE_CONFIG_RUSTFS_FORCE_PATH_STYLE: "true"
|
|
RCLONE_CONFIG_RUSTFS_REGION: other
|
|
depends_on:
|
|
migrate:
|
|
condition: service_completed_successfully
|
|
healthcheck:
|
|
test:
|
|
- CMD-SHELL
|
|
- grep -q ' /workspace/workspaces .* - fuse.rclone ' /proc/self/mountinfo && curl -fsS http://127.0.0.1:8000/api/v1/health >/dev/null
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 18
|
|
start_period: 30s
|
|
|
|
schedule:
|
|
build:
|
|
context: .
|
|
dockerfile: schedule/Dockerfile
|
|
restart: unless-stopped
|
|
# No host port: architecture §2.2 — only Nginx is externally reachable.
|
|
# No local-FS volume: schedule executes nodes via tempfile.TemporaryDirectory
|
|
# under Python's default temp dir (cleaned per-run); artifacts live in RustFS.
|
|
environment:
|
|
DATABASE_URL: ${DATABASE_URL:?DATABASE_URL is required}
|
|
SERVICE_NAME: schedule-executor
|
|
BACKEND_API_URL: http://backend:8000
|
|
RUSTFS_ENDPOINT: ${RUSTFS_ENDPOINT:?RUSTFS_ENDPOINT is required}
|
|
RUSTFS_ACCESS_KEY: ${RUSTFS_ACCESS_KEY:?RUSTFS_ACCESS_KEY is required}
|
|
RUSTFS_SECRET_KEY: ${RUSTFS_SECRET_KEY:?RUSTFS_SECRET_KEY is required}
|
|
RUSTFS_WORKSPACE_BUCKET: ${RUSTFS_WORKSPACE_BUCKET:-workspaces}
|
|
RUSTFS_VERSION_BUCKET: ${RUSTFS_VERSION_BUCKET:-versions}
|
|
RUSTFS_RUN_LOG_BUCKET: ${RUSTFS_RUN_LOG_BUCKET:-run-logs}
|
|
READINESS_TARGETS: ${MYSQL_HOST:?MYSQL_HOST is required}:${MYSQL_PORT:-3306},${RUSTFS_HOST:?RUSTFS_HOST is required}:${RUSTFS_PORT:-9000},backend:8000
|
|
depends_on:
|
|
backend:
|
|
condition: service_healthy
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "curl -fsS http://127.0.0.1:8000/health/ready >/dev/null"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 18
|
|
start_period: 20s
|