UNPKG

@underpostnet/underpost

Version:

Underpost Platform — end-to-end CI/CD and application-delivery toolchain CLI. Covers bare metal, Kubernetes, K3s, kubeadm, LXD, container/image orchestration, secrets, databases, cron jobs, monitoring, SSH, runners, PWA + Workbox delivery, and release orc

225 lines (215 loc) 8.04 kB
# Production-style Docker Compose stack mirroring the Kubernetes development # environment defined under manifests/{mongodb,valkey,deployment/dd-default-development}. # # Mapping summary (K8s -> Compose): # StatefulSet mongodb (replSet rs0, keyFile auth) -> mongodb + mongodb-keyfile-init + mongodb-rs-init # StatefulSet valkey-service -> valkey-service # Deployment dd-default-development-blue -> app # HTTPProxy default.net / www.default.net (Contour) -> proxy (nginx reverse proxy) # Service type LoadBalancer / NodePort -> published host ports via the proxy # Secret mongodb-secret / mongodb-keyfile -> .env values + generated keyfile volume # PVC mongodb-storage / volumeClaimTemplates -> named volumes name: dd-default-development services: # --- MongoDB ------------------------------------------------------------- # Mirrors manifests/mongodb/statefulset.yaml: replSet rs0, keyFile cluster # auth, --auth, bind to all interfaces. Single-node replica set for local dev. # # Bootstrap follows src/db/mongo/MongoBootstrap.js rather than the image's # MONGO_INITDB_ROOT_USERNAME auto-init (whose temp server + keyFile combination # is unreliable). The generated entrypoint (docker/mongodb/entrypoint.sh) # generates the keyfile, starts mongod, and bootstraps the replica set + root # user over the loopback localhost exception. The healthcheck gates readiness # on an authenticated writable primary. mongodb: image: ${MONGO_IMAGE:-mongo:latest} container_name: dd-mongodb entrypoint: ['bash', '/docker-init/entrypoint.sh'] environment: MONGO_INITDB_ROOT_USERNAME: ${MONGO_INITDB_ROOT_USERNAME:?set MONGO_INITDB_ROOT_USERNAME in docker/compose.env} MONGO_INITDB_ROOT_PASSWORD: ${MONGO_INITDB_ROOT_PASSWORD:?set MONGO_INITDB_ROOT_PASSWORD in docker/compose.env} DB_REPLICA_SET: ${DB_REPLICA_SET:-rs0} volumes: - ./docker/mongodb:/docker-init:ro - mongodb-keyfile:/opt/keyfile - mongodb-data:/data/db networks: - dd-internal expose: - '27017' ports: - '${MONGO_HOST_PORT:-27017}:27017' healthcheck: test: - CMD-SHELL - > mongosh --quiet -u "$$MONGO_INITDB_ROOT_USERNAME" -p "$$MONGO_INITDB_ROOT_PASSWORD" --authenticationDatabase admin --eval "db.hello().isWritablePrimary" | grep -q true interval: 10s timeout: 5s retries: 20 start_period: 60s restart: unless-stopped # --- Valkey -------------------------------------------------------------- # Mirrors manifests/valkey/statefulset.yaml. valkey-service: image: ${VALKEY_IMAGE:-valkey/valkey:latest} container_name: dd-valkey command: ['valkey-server', '--port', '6379', '--bind', '0.0.0.0', '--protected-mode', 'no'] volumes: - valkey-data:/data networks: - dd-internal expose: - '6379' # NodePort equivalent (manifests/valkey/valkey-nodeport.yaml nodePort 32079). ports: - '${VALKEY_NODEPORT:-32079}:6379' healthcheck: test: ['CMD', 'valkey-cli', '-p', '6379', 'ping'] interval: 10s timeout: 5s retries: 10 start_period: 10s restart: unless-stopped # --- Application --------------------------------------------------------- # Mirrors manifests/deployment/dd-default-development/deployment.yaml # (dd-default-development-blue). Connection targets use Docker service # discovery instead of hardcoded localhost. app: image: ${APP_IMAGE:-underpost/underpost-engine}:${APP_TAG:-v3.2.70} container_name: dd-app # The start command is supplied by the generated override docker/compose.app.yml # (see `underpost docker-compose --generate --deploy-id <id>`), keeping this # file deployment-agnostic. environment: NODE_ENV: ${NODE_ENV:-development} DB_PROVIDER: ${DB_PROVIDER:-mongoose} DB_HOST: ${DB_HOST:-mongodb://mongodb:27017} DB_NAME: ${DB_NAME:-default} DB_REPLICA_SET: ${DB_REPLICA_SET:-rs0} DB_AUTH_SOURCE: ${DB_AUTH_SOURCE:-admin} DB_USER: ${MONGO_INITDB_ROOT_USERNAME:?} DB_PASSWORD: ${MONGO_INITDB_ROOT_PASSWORD:?} VALKEY_HOST: ${VALKEY_HOST:-valkey-service} VALKEY_PORT: ${VALKEY_PORT:-6379} networks: - dd-internal expose: - '4001' - '4002' - '4003' - '4004' # Direct access to the LoadBalancer-equivalent ports (manifest 4001-4004). ports: - '${APP_PORT_4001:-4001}:4001' - '${APP_PORT_4002:-4002}:4002' - '${APP_PORT_4003:-4003}:4003' - '${APP_PORT_4004:-4004}:4004' healthcheck: test: ['CMD-SHELL', "timeout 2 bash -c '</dev/tcp/127.0.0.1/4001' || exit 1"] interval: 15s timeout: 5s retries: 5 start_period: 60s depends_on: mongodb: condition: service_healthy valkey-service: condition: service_healthy restart: unless-stopped # --- Reverse proxy / NodePort-equivalent load balancer ------------------- # Mirrors manifests/deployment/dd-default-development/proxy.yaml (Contour # HTTPProxy) using nginx with websocket upgrade support. proxy: image: ${PROXY_IMAGE:-nginx:stable-alpine} container_name: dd-proxy volumes: - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro networks: - dd-internal ports: - '${PROXY_HTTP_PORT:-80}:80' healthcheck: test: ['CMD', 'wget', '-q', '-O', '-', 'http://127.0.0.1/healthz'] interval: 15s timeout: 5s retries: 5 start_period: 10s depends_on: app: condition: service_started restart: unless-stopped # --- Monitoring: Prometheus ---------------------------------------------- # Mirrors manifests/prometheus/deployment.yaml. Scrapes the app's /metrics # endpoint (prom-client) over the internal network. Config is generated by # `underpost docker-compose --generate` into docker/prometheus/prometheus.yml. prometheus: image: ${PROMETHEUS_IMAGE:-prom/prometheus:latest} container_name: dd-prometheus command: - --config.file=/etc/prometheus/prometheus.yml - --storage.tsdb.path=/prometheus volumes: - ./docker/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro - prometheus-data:/prometheus networks: - dd-internal expose: - '9090' ports: - '${PROMETHEUS_PORT:-9090}:9090' healthcheck: test: ['CMD', 'wget', '-q', '-O', '-', 'http://127.0.0.1:9090/-/healthy'] interval: 15s timeout: 5s retries: 5 start_period: 15s depends_on: app: condition: service_started restart: unless-stopped # --- Monitoring: Grafana ------------------------------------------------- # Mirrors manifests/grafana/deployment.yaml. Prometheus datasource is # pre-provisioned (generated) so dashboards work out of the box. grafana: image: ${GRAFANA_IMAGE:-grafana/grafana:latest} container_name: dd-grafana environment: GF_SECURITY_ADMIN_USER: ${GRAFANA_ADMIN_USER:-admin} GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_ADMIN_PASSWORD:-admin} GF_USERS_ALLOW_SIGN_UP: 'false' volumes: - ./docker/grafana/provisioning:/etc/grafana/provisioning:ro - grafana-data:/var/lib/grafana networks: - dd-internal expose: - '3000' ports: - '${GRAFANA_PORT:-3000}:3000' healthcheck: test: ['CMD', 'wget', '-q', '-O', '-', 'http://127.0.0.1:3000/api/health'] interval: 15s timeout: 5s retries: 5 start_period: 15s depends_on: prometheus: condition: service_started restart: unless-stopped networks: dd-internal: name: dd-internal driver: bridge volumes: mongodb-data: name: dd-mongodb-data mongodb-keyfile: name: dd-mongodb-keyfile valkey-data: name: dd-valkey-data prometheus-data: name: dd-prometheus-data grafana-data: name: dd-grafana-data