Files
Project-SDE-WP-Suite/docker-compose.yml
Cody Schaefer 7ef1fcdd96 Add Micron asset picker to work package creator
Adds an optional read-only Micron asset catalog lookup for the WP creator, with searchable asset IDs, CSV import, and graceful fallback to manual asset entry when the catalog is absent or unreachable. This includes the backend /api/assets endpoint, SQL Server connector configuration, Docker network changes for outbound access, and UI updates/documentation to make the catalog read-only and clearly distinguish Micron-vetted assets from manual entries.
2026-08-18 14:56:55 -05:00

119 lines
4.5 KiB
YAML

services:
webserver:
build:
context: .
dockerfile: nginx/Dockerfile
container_name: nginx_webserver
volumes:
- nginx_logs:/var/log/nginx
restart: unless-stopped
depends_on:
api:
condition: service_started
networks:
- proxy # external — reachable by your reverse proxy / traefik
- internal # needs a path to the api container
api:
build: .
container_name: wp_api
environment:
# Preferred: the API builds its own connection string from these and
# encodes the password automatically (no manual URL-encoding needed).
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_HOST: db
# Optional full-URL override (must be URL-encoded if used).
DATABASE_URL: ${DATABASE_URL:-}
# Signs login session cookies. REQUIRED — compose fails fast if it's unset,
# and the API refuses to start in production without it (see server/auth.py).
AUTH_SECRET_KEY: ${AUTH_SECRET_KEY:?set AUTH_SECRET_KEY in .env (see server/.env.example)}
AUTH_SESSION_HOURS: ${AUTH_SESSION_HOURS:-12}
# Optional — SMTP password for WP-assignment emails. Email is off by
# default and enabled from the Admin console; this is the only email
# secret and it is never stored in the DB. Leave unset until configured.
SMTP_PASSWORD: ${SMTP_PASSWORD:-}
# Optional — read-only SQL Server connection to the Micron asset catalog,
# which backs the asset picker in the work package creator. Leave unset and
# the picker cleanly falls back to manual entry (see server/assets_db.py).
# Use a db_datareader login: the app only ever SELECTs.
MICRON_DB_URL: ${MICRON_DB_URL:-}
restart: unless-stopped
depends_on:
db:
condition: service_healthy # waits for postgres to accept connections
networks:
- internal
# Reaching the Micron database means leaving this compose project, and
# `internal` is deliberately egress-free. `outbound` is attached to the api
# container ONLY — the database and backup containers stay sealed. Detach it
# again if you are not using the Micron asset picker.
- outbound
db:
image: postgres:16-alpine
container_name: wp_db
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- pgdata:/var/lib/postgresql/data
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
interval: 10s
timeout: 5s
retries: 5
networks:
- internal
# Scheduled pg_dump backups. Writes gzipped, timestamped dumps to ./backups on
# the host (sync that folder offsite from the host — this container has no
# internet egress). See scripts/db-backup.sh and DEPLOYMENT.md § Backups.
backup:
build:
context: .
dockerfile: scripts/backup.Dockerfile # postgres client + openssl
container_name: wp_db_backup
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
PGHOST: db
BACKUP_DIR: /backups
BACKUP_KEEP: ${BACKUP_KEEP:-14} # keep the newest N dumps
BACKUP_INTERVAL_SECONDS: ${BACKUP_INTERVAL_SECONDS:-86400} # 86400 = daily
# Set BACKUP_ENC_PASSPHRASE in .env to encrypt dumps at rest (AES-256).
# Required once the DB holds customer IP. Keep the passphrase off this host.
BACKUP_ENC_PASSPHRASE: ${BACKUP_ENC_PASSPHRASE:-}
volumes:
- ./scripts:/scripts:ro
- ./backups:/backups
restart: unless-stopped
depends_on:
db:
condition: service_healthy
networks:
- internal
volumes:
pgdata:
nginx_logs:
networks:
proxy:
name: proxy
external: true
internal:
internal: true # no route off the host for anything on this network alone
outbound:
# An ordinary bridge network, i.e. one that HAS a default gateway. `internal`
# above removes the gateway entirely, which blocks not just the internet but
# the LAN and the VPN too — so the api container needs this second network to
# reach the Micron asset database. Attached to `api` alone: `db` and `backup`
# remain on `internal` only and still have no way off the host.
# Detach it from api if you are not using the Micron asset picker.
driver: bridge