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.
113 lines
3.7 KiB
YAML
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 |