Files
ghost/compose.yml
autonomic-bot ae43ffe340 fix(healthcheck): raise app start_period 1m->15m (slow fresh-DB migration)
Ghost's fresh-DB first boot runs a full schema migration (dozens of CREATE
TABLEs, each a separate MySQL round-trip; ~6-9min on a small/slow node). The
1m start_period + 10x30s retries (~6min grace) is too tight there: swarm marks
the still-migrating task unhealthy and kills it mid-migration, leaving a stale
migrations_lock row so every later task deadlocks (MigrationsAreLockedError).

start_period only widens the startup grace window: a healthy check still marks
the task healthy immediately, so fast hosts are unaffected. It cannot be exposed
as an env var (abra validates the literal compose 'duration' format BEFORE env
substitution, rejecting ${VAR} / "${VAR:-1m}" with FATA 'Does not match format
duration'), so a literal bump is the only way to widen it.
2026-05-30 17:18:13 +01:00

113 lines
3.7 KiB
YAML

services:
app:
image: ghost:6.21.2-alpine
environment:
# see https://ghost.org/docs/config/#configuration-options
database__client: mysql
database__connection__host: ${STACK_NAME}_db
database__connection__user: root
database__connection__database: ghost
database__connection__password_FILE: /run/secrets/db_password
database__pool__min: ${DATABASE_POOL_MIN:-0}
database__pool__max: ${DATABASE_POOL_MAX:-10}
url: https://$DOMAIN
mail__transport: ${MAIL_TRANSPORT}
mail__from: ${MAIL_FROM}
mail__options__host: ${MAIL_OPTIONS_HOST}
mail__options__port: ${MAIL_OPTIONS_PORT}
mail__options__secure: ${MAIL_OPTIONS_SECURE}
mail__options__auth__user: ${MAIL_OPTIONS_AUTH_USER}
mail__options__auth__pass_FILE: /run/secrets/smtp_password
# contrary to the default mentioned in the linked documentation, this image defaults to NODE_ENV=production (so development mode needs to be explicitly specified if desired)
#NODE_ENV: development
secrets:
- db_password
- smtp_password
configs:
- source: ghost_entrypoint
target: /abra-entrypoint.sh
mode: 0555
command: ["node", "current/index.js"]
entrypoint: /abra-entrypoint.sh
depends_on:
- db
networks:
- proxy
- backend
volumes:
- "ghost_content:/var/lib/ghost/content/"
deploy:
restart_policy:
condition: on-failure
labels:
- "traefik.enable=true"
- "traefik.http.services.${STACK_NAME}.loadbalancer.server.port=2368"
- "traefik.http.routers.${STACK_NAME}.rule=Host(`${DOMAIN}`${EXTRA_DOMAINS})"
- "traefik.http.routers.${STACK_NAME}.entrypoints=web-secure"
- "traefik.http.routers.${STACK_NAME}.tls.certresolver=${LETS_ENCRYPT_ENV}"
# Redirect from EXTRA_DOMAINS to DOMAIN
- "traefik.http.routers.${STACK_NAME}.middlewares=${STACK_NAME}-redirect"
- "traefik.http.middlewares.${STACK_NAME}-redirect.redirectscheme.scheme=https"
- "traefik.http.middlewares.${STACK_NAME}-redirect.redirectscheme.permanent=true"
- "backupbot.backup=true"
- "backupbot.backup.path=/var/lib/ghost/content"
- "coop-cloud.${STACK_NAME}.version=1.3.0+6.21.2-alpine"
healthcheck:
test: ["CMD", "wget", "--header=X-Forwarded-Proto: https", "--spider", "-q", "http://localhost:2368/ghost/api/admin/site"]
interval: 30s
timeout: 10s
retries: 10
start_period: 15m
db:
image: mysql:8.0
networks:
- backend
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_password
secrets:
- db_password
configs:
- source: mysql_backup
target: /mysql_backup.sh
mode: 0555
volumes:
- "mysql:/var/lib/mysql"
deploy:
labels:
- "backupbot.backup=true"
- "backupbot.backup.pre-hook=/mysql_backup.sh backup"
- "backupbot.backup.volumes.mysql.path=backup.sql.gz"
- "backupbot.restore.post-hook=/mysql_backup.sh restore"
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p\"$$(cat /run/secrets/db_password)\""]
interval: 30s
timeout: 10s
retries: 10
start_period: 1m
networks:
proxy:
external: true
backend:
volumes:
mysql:
ghost_content:
secrets:
db_password:
name: ${STACK_NAME}_db_password_${SECRET_DB_PASSWORD_VERSION}
external: true
smtp_password:
external: true
name: ${STACK_NAME}_smtp_password_${SECRET_SMTP_PASSWORD_VERSION}
configs:
ghost_entrypoint:
name: ${STACK_NAME}_ghost_entrypoint_${GHOST_ENTRYPOINT_VERSION}
file: entrypoint.sh
mysql_backup:
name: ${STACK_NAME}_mysql_backup_${MYSQL_BACKUP_VERSION}
file: mysql_backup.sh