Files
2026-09-17 13:39:16 +01:00

114 lines
4.0 KiB
YAML

---
version: "3.8"
services:
app:
image: ${CONTAINER_REGISTRY:-pentacent/keila}:${APP_VERSION:-0.30.3}
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "10"
environment:
- URL_HOST=${DOMAIN}
- URL_SCHEMA=https
- URL_PORT=443
- PORT=4000
- URL_PATH
- LOG_LEVEL
# Keila serves user uploads itself unless USER_CONTENT_BASE_URL points somewhere else. Serving untrusted files from your own origin is worth avoiding if you have a spare hostname.
- USER_CONTENT_DIR=/opt/app/uploads
- USER_CONTENT_BASE_URL
# The root admin account, created on the FIRST boot only. Its password is the keila_password secret.
- KEILA_USER
- DISABLE_REGISTRATION
- DISABLE_SENDER_CREATION
- DISABLE_UPDATE_CHECKS
- DISABLE_TZDATA_UPDATES
- DISABLE_PRECEDENCE_HEADER
- ENABLE_QUOTAS
- MESSAGE_RETENTION_DAYS
- DB_SCHEMA
- DB_ENABLE_SSL
- DB_VERIFY_SSL_HOST
# System mail only: registration, password reset and other transactional messages. Newsletter delivery is configured per project in the web UI and stored in the database, not here. Keila halts at boot if MAILER_SMTP_HOST or MAILER_SMTP_FROM_EMAIL is missing.
- MAILER_TYPE
- MAILER_SMTP_HOST
- MAILER_SMTP_FROM_EMAIL
- MAILER_SMTP_USER
- MAILER_SMTP_PORT
- MAILER_SMTP_AUTH_METHOD
- MAILER_SMTP_TLS_MODE
secrets:
- secret_key_base
- hashid_salt
- keila_password
- mailer_smtp_password
volumes:
- uploads:/opt/app/uploads
networks:
- proxy
- internal
entrypoint: ["/docker-entrypoint.sh", "/opt/app/bin/keila", "start"]
configs:
- source: app_entrypoint
target: /docker-entrypoint.sh
mode: 0555
deploy:
restart_policy:
# Swarm has no `depends_on: condition: service_healthy`, so on a cold start the app exits until the db accepts connections. That is the intended behaviour; it settles within a few restarts.
condition: on-failure
labels:
# how long abra waits for the deploy to converge, as needs headroom for the migrations Keila runs on boot
- "coop-cloud.${STACK_NAME}.timeout=${TIMEOUT:-300}"
- "backupbot.backup=${ENABLE_BACKUPS:-true}"
- "traefik.enable=true"
- "traefik.http.services.${STACK_NAME}.loadbalancer.server.port=4000"
- "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}"
- "coop-cloud.${STACK_NAME}.version=0.1.0+0.30.3"
healthcheck:
# The image is Alpine-based, so this is busybox wget. There is no dedicated health route; / redirects to the login page, which is enough to prove the endpoint is serving.
test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1:4000/"]
interval: 30s
timeout: 10s
retries: 10
start_period: 60s
volumes:
uploads:
networks:
proxy:
external: true
internal:
configs:
app_entrypoint:
name: ${STACK_NAME}_app_entrypoint_${APP_ENTRYPOINT_VERSION:-v1}
file: entrypoint.sh.tmpl
template_driver: golang
secrets:
secret_key_base:
external: true
name: ${STACK_NAME}_secret_key_base_${SECRET_SECRET_KEY_BASE_VERSION:-v1}
# Set explicitly rather than letting Keila derive it from SECRET_KEY_BASE, so rotating the key base later does not invalidate every public Hashid in existing campaign and form URLs.
hashid_salt:
external: true
name: ${STACK_NAME}_hashid_salt_${SECRET_HASHID_SALT_VERSION:-v1}
# Password for the KEILA_USER root account. Only read on the first boot.
keila_password:
external: true
name: ${STACK_NAME}_keila_password_${SECRET_KEILA_PASSWORD_VERSION:-v1}
mailer_smtp_password:
external: true
name: ${STACK_NAME}_mailer_smtp_password_${SECRET_MAILER_SMTP_PASSWORD_VERSION:-v1}