Some checks are pending
CI / Lint bridge (Biome) (push) Waiting to run
CI / Type-check bridge (push) Blocked by required conditions
CI / Tests unit bridge (push) Blocked by required conditions
CI / Tests integration bridge (push) Blocked by required conditions
CI / Security scan (push) Waiting to run
CI / Docker build + healthcheck (push) Blocked by required conditions
E2E Playwright / Playwright e2e (chromium) (push) Waiting to run
- compose.yml: expose BASEROW_USER_EMAIL/PASSWORD, DOCMOST_APP_SECRET,
DOCMOST_JWT_ISSUER on bridge service (required for user JWT + admin)
- compose.prod.yml: switch to acadedoc:${ACADEDOC_VERSION} image with
pull_policy=never, point Traefik routers at *.stark.a3n.fr, attach to
admin_proxy external network, add bridge service block with dual router
(public bridge.stark.a3n.fr + same-origin /bridge prefix on doc), SMTP
env vars, CPU caps and reservations on all services, healthchecks on
baserow / redis / bridge
137 lines
4.4 KiB
YAML
137 lines
4.4 KiB
YAML
# compose.prod.yml — overrides pour env production
|
|
# Usage : docker compose -f compose.yml -f compose.prod.yml up -d
|
|
# Reseau externe : admin_proxy (Traefik)
|
|
|
|
services:
|
|
docmost:
|
|
image: acadedoc:${ACADEDOC_VERSION:-local}
|
|
pull_policy: never
|
|
restart: always
|
|
environment:
|
|
APP_URL: ${DOCMOST_URL:?DOCMOST_URL requis sur prod}
|
|
LOG_LEVEL: warn
|
|
MAIL_DRIVER: smtp
|
|
SMTP_HOST: ${SMTP_HOST}
|
|
SMTP_PORT: ${SMTP_PORT}
|
|
SMTP_USERNAME: ${SMTP_USERNAME}
|
|
SMTP_PASSWORD: ${SMTP_PASSWORD}
|
|
SMTP_SECURE: "false"
|
|
MAIL_FROM_ADDRESS: ${MAIL_FROM_ADDRESS}
|
|
MAIL_FROM_NAME: ${MAIL_FROM_NAME}
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.docker.network=admin_proxy"
|
|
- "traefik.http.routers.docmost-prod.rule=Host(`doc.stark.a3n.fr`)"
|
|
- "traefik.http.routers.docmost-prod.entrypoints=websecure"
|
|
- "traefik.http.routers.docmost-prod.tls.certresolver=letsencrypt"
|
|
- "traefik.http.services.docmost-prod.loadbalancer.server.port=3000"
|
|
ports: !reset []
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
memory: 2G
|
|
cpus: "1.5"
|
|
reservations:
|
|
memory: 512M
|
|
healthcheck:
|
|
test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:3000').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
|
|
interval: 30s
|
|
timeout: 5s
|
|
retries: 3
|
|
start_period: 30s
|
|
|
|
baserow:
|
|
restart: always
|
|
environment:
|
|
BASEROW_PUBLIC_URL: ${BASEROW_URL:?BASEROW_URL requis sur prod}
|
|
BASEROW_EXTRA_ALLOWED_HOSTS: baserow
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.docker.network=admin_proxy"
|
|
- "traefik.http.routers.baserow-prod.rule=Host(`baserow.stark.a3n.fr`)"
|
|
- "traefik.http.routers.baserow-prod.entrypoints=websecure"
|
|
- "traefik.http.routers.baserow-prod.tls.certresolver=letsencrypt"
|
|
- "traefik.http.services.baserow-prod.loadbalancer.server.port=80"
|
|
ports: !reset []
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
memory: 3G
|
|
cpus: "2.0"
|
|
reservations:
|
|
memory: 1G
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "curl -fsS http://localhost/_health/ || exit 1"]
|
|
interval: 30s
|
|
timeout: 5s
|
|
retries: 5
|
|
start_period: 60s
|
|
|
|
bridge:
|
|
restart: always
|
|
environment:
|
|
BASEROW_WEBHOOK_SECRET: ${BASEROW_WEBHOOK_SECRET:?BASEROW_WEBHOOK_SECRET requis (>= 16 chars)}
|
|
LOG_LEVEL: warn
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.docker.network=admin_proxy"
|
|
# Router public : webhooks Baserow + appels machine-to-machine (token brg_*).
|
|
- "traefik.http.routers.bridge-prod.rule=Host(`bridge.stark.a3n.fr`)"
|
|
- "traefik.http.routers.bridge-prod.entrypoints=websecure"
|
|
- "traefik.http.routers.bridge-prod.tls.certresolver=letsencrypt"
|
|
- "traefik.http.routers.bridge-prod.service=bridge-prod"
|
|
# Router same-origin sur le doc : appels SPA front. Le cookie authToken
|
|
# de Docmost est host-only sur doc.stark.a3n.fr donc on ne peut PAS
|
|
# router cross-subdomain. Le strip /bridge laisse passer /api/v1/* tel
|
|
# que le bridge l'attend.
|
|
- "traefik.http.routers.bridge-on-doc.rule=Host(`doc.stark.a3n.fr`) && PathPrefix(`/bridge`)"
|
|
- "traefik.http.routers.bridge-on-doc.entrypoints=websecure"
|
|
- "traefik.http.routers.bridge-on-doc.tls.certresolver=letsencrypt"
|
|
- "traefik.http.routers.bridge-on-doc.middlewares=bridge-strip"
|
|
- "traefik.http.routers.bridge-on-doc.service=bridge-prod"
|
|
- "traefik.http.middlewares.bridge-strip.stripprefix.prefixes=/bridge"
|
|
- "traefik.http.services.bridge-prod.loadbalancer.server.port=4000"
|
|
ports: !reset []
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
memory: 512M
|
|
cpus: "0.5"
|
|
reservations:
|
|
memory: 128M
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:4000/api/health | grep -q '\"status\":\"ok\"' || exit 1"]
|
|
interval: 30s
|
|
timeout: 5s
|
|
retries: 3
|
|
start_period: 20s
|
|
|
|
docmost-db:
|
|
restart: always
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
memory: 1G
|
|
cpus: "1.0"
|
|
reservations:
|
|
memory: 256M
|
|
|
|
docmost-redis:
|
|
restart: always
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
memory: 256M
|
|
cpus: "0.5"
|
|
reservations:
|
|
memory: 64M
|
|
healthcheck:
|
|
test: ["CMD", "redis-cli", "ping"]
|
|
interval: 10s
|
|
timeout: 3s
|
|
retries: 5
|
|
|
|
networks:
|
|
default:
|
|
external: true
|
|
name: admin_proxy
|