CI / ci (push) Failing after 6m4s
Co-authored-by: orchestrator-agent <20+orchestrator-agent@code.cubecraftcreations.com>
145 lines
4.7 KiB
YAML
145 lines
4.7 KiB
YAML
# Production stack for MealQuest on 10.60.1.14 (D-018). Building, deploying
|
|
# and operating it: CTXD project mealquest, RUNBOOKS.MD "Stack unit" and
|
|
# "Routine deploy and rollback".
|
|
#
|
|
# The services use restart: "no" on purpose: Docker must not start them
|
|
# before the DOCKER-USER firewall is applied. deploy/systemd/mealquest.service
|
|
# owns start and stop and requires mealquest-firewall.service first.
|
|
#
|
|
# Configuration comes from deploy/.env (template: deploy/.env.example) and
|
|
# secrets from deploy/secrets/; neither is committed. Compose bind-mounts
|
|
# file secrets with their host owner and mode, so each file in
|
|
# deploy/secrets/ must be owned by the container user 10001:10001 with mode
|
|
# 0600 (except searxng.env, read by compose itself; see the searxng service).
|
|
name: mealquest
|
|
|
|
services:
|
|
mealquest:
|
|
build:
|
|
context: ..
|
|
dockerfile: Dockerfile
|
|
user: "10001:10001"
|
|
restart: "no"
|
|
env_file:
|
|
- path: .env
|
|
required: true
|
|
# Fixed by this file's container shape (listen port, volume, secret
|
|
# mounts); deploy/.env must not set them.
|
|
environment:
|
|
MEALQUEST_HTTP_ADDR: ":8080"
|
|
MEALQUEST_DATA_DIR: /data
|
|
MEALQUEST_SECRET_KEY_FILE: /run/secrets/secret_key
|
|
MEALQUEST_OIDC_CLIENT_SECRET_FILE: /run/secrets/oidc_client_secret
|
|
MEALQUEST_GOOGLE_CLIENT_SECRET_FILE: /run/secrets/google_client_secret
|
|
MEALQUEST_VAPID_PRIVATE_KEY_FILE: /run/secrets/vapid_private_key
|
|
MEALQUEST_SEARXNG_URL: http://searxng:8080
|
|
secrets:
|
|
- secret_key
|
|
- oidc_client_secret
|
|
- google_client_secret
|
|
- vapid_private_key
|
|
volumes:
|
|
- mealquest-data:/data
|
|
ports:
|
|
- "${MEALQUEST_BIND_ADDRESS:?set MEALQUEST_BIND_ADDRESS in deploy/.env}:8090:8080"
|
|
networks:
|
|
- mealquest
|
|
healthcheck:
|
|
test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1:8080/health"]
|
|
interval: 30s
|
|
timeout: 3s
|
|
start_period: 10s
|
|
retries: 3
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
cap_drop:
|
|
- ALL
|
|
|
|
# Litestream streams the database to the Synology NAS over SFTP
|
|
# (config: deploy/litestream.yml). The SFTP private key
|
|
# deploy/secrets/litestream_key is a dedicated keypair, owned by
|
|
# 10001:10001 with mode 0600 like the other secrets.
|
|
#
|
|
# The data volume is mounted read-write on purpose: Litestream writes its
|
|
# tracking tables into the database and checkpoints the WAL. It runs as
|
|
# the app's own user (owner of the volume) with a read-only root
|
|
# filesystem, no privilege escalation and no Linux capabilities.
|
|
#
|
|
# Restoring the database: CTXD project mealquest, RUNBOOKS.MD "Restore
|
|
# the database".
|
|
litestream:
|
|
image: litestream/litestream:0.5.17
|
|
user: "10001:10001"
|
|
restart: "no"
|
|
command: ["replicate", "-config", "/etc/litestream.yml"]
|
|
depends_on:
|
|
mealquest:
|
|
condition: service_healthy
|
|
volumes:
|
|
- mealquest-data:/data
|
|
- ./litestream.yml:/etc/litestream.yml:ro
|
|
- ./secrets/litestream_key:/etc/litestream/sftp_key:ro
|
|
networks:
|
|
- mealquest
|
|
read_only: true
|
|
tmpfs:
|
|
- /tmp
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
cap_drop:
|
|
- ALL
|
|
|
|
# SearXNG, the recipe-search sidecar (Feature 10; settings:
|
|
# deploy/searxng/settings.yml). It sits on the mealquest network only and
|
|
# publishes no port: the mealquest service reaches it at
|
|
# http://searxng:8080 and nothing outside the compose network can.
|
|
# deploy/compose.dev.yaml publishes it on 127.0.0.1 for development.
|
|
#
|
|
# The secret key comes from deploy/secrets/searxng.env as SEARXNG_SECRET.
|
|
# Compose itself reads that file (it is not mounted), so unlike the other
|
|
# secrets it is owned by overseer, mode 0600. It runs as the image's
|
|
# searxng user (977) with a read-only root filesystem.
|
|
searxng:
|
|
image: searxng/searxng:2026.10.4-d48c4b555@sha256:76b0bf285aca014c7191fc4d9234c4bfb358624ac33d8883833d496c059ec072
|
|
user: "977:977"
|
|
restart: "no"
|
|
env_file:
|
|
- path: ./secrets/searxng.env
|
|
required: true
|
|
volumes:
|
|
- ./searxng/settings.yml:/etc/searxng/settings.yml:ro
|
|
networks:
|
|
- mealquest
|
|
healthcheck:
|
|
test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1:8080/healthz"]
|
|
interval: 30s
|
|
timeout: 3s
|
|
start_period: 15s
|
|
retries: 3
|
|
read_only: true
|
|
tmpfs:
|
|
- /tmp
|
|
- /var/cache/searxng:uid=977,gid=977
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
cap_drop:
|
|
- ALL
|
|
|
|
secrets:
|
|
secret_key:
|
|
file: ./secrets/secret_key
|
|
oidc_client_secret:
|
|
file: ./secrets/oidc_client_secret
|
|
google_client_secret:
|
|
file: ./secrets/google_client_secret
|
|
vapid_private_key:
|
|
file: ./secrets/vapid_private_key
|
|
|
|
volumes:
|
|
mealquest-data:
|
|
name: mealquest-data
|
|
|
|
networks:
|
|
mealquest:
|
|
name: mealquest
|