mirror of
https://github.com/karatektus/pl_mail.git
synced 2026-10-25 01:54:10 +00:00
Compose files keep only a short header; the reasoning lives in docs/install. truenas.compose.yaml is gone (the TrueNAS catalog app replaces it) and so is compose.prod.yaml (compose.yaml already runs the published prod image). compose.override.yaml.dist becomes compose.dev.yaml, passed with -f, so there is no untracked copy that compose loads on its own. Docs, CODESTYLE, CONTRIBUTING and the entrypoint's error text follow. Every remaining file resolves to the same `docker compose config` as before. Closes #30 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
162 lines
4.6 KiB
YAML
162 lines
4.6 KiB
YAML
# plMail on the published image: web, worker and Postgres.
|
|
# Secrets are generated on first start; see docs/install/docker.md.
|
|
|
|
x-app-image: &app-image ghcr.io/karatektus/pl_mail:latest
|
|
|
|
x-app-env: &app-env
|
|
APP_ENV: prod
|
|
APP_SECRET: ${APP_SECRET:-}
|
|
APP_ENCRYPTION_KEY: ${APP_ENCRYPTION_KEY:-}
|
|
DATABASE_URL: ${DATABASE_URL:-}
|
|
POSTGRES_USER: ${POSTGRES_USER:-app}
|
|
POSTGRES_DB: ${POSTGRES_DB:-app}
|
|
POSTGRES_VERSION: ${POSTGRES_VERSION:-18}
|
|
MESSENGER_TRANSPORT_DSN: ${MESSENGER_TRANSPORT_DSN:-doctrine://default?auto_setup=0}
|
|
MERCURE_URL: ${MERCURE_URL:-http://mercure/.well-known/mercure}
|
|
MERCURE_PUBLIC_URL: ${MERCURE_PUBLIC_URL:-https://localhost/.well-known/mercure}
|
|
MERCURE_COOKIE_NAME: ${MERCURE_COOKIE_NAME:-}
|
|
OIDC_ISSUER: ${OIDC_ISSUER:-}
|
|
OIDC_CLIENT_ID: ${OIDC_CLIENT_ID:-}
|
|
OIDC_CLIENT_SECRET: ${OIDC_CLIENT_SECRET:-}
|
|
OIDC_BUTTON_LABEL: ${OIDC_BUTTON_LABEL:-}
|
|
OIDC_SCOPES: ${OIDC_SCOPES:-openid email profile}
|
|
OIDC_AUTO_CREATE: ${OIDC_AUTO_CREATE:-false}
|
|
OIDC_REQUIRE_VERIFIED_EMAIL: ${OIDC_REQUIRE_VERIFIED_EMAIL:-true}
|
|
|
|
x-app-storage: &app-storage
|
|
- app_secrets:/app/var/secrets
|
|
- app_attachments:/app/var/attachments
|
|
- app_raw:/app/var/raw
|
|
- app_uploads:/app/var/uploads
|
|
|
|
services:
|
|
secrets-init:
|
|
image: *app-image
|
|
restart: "no"
|
|
entrypoint: ["generate-secrets"]
|
|
environment:
|
|
APP_SECRET: ${APP_SECRET:-}
|
|
APP_ENCRYPTION_KEY: ${APP_ENCRYPTION_KEY:-}
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-}
|
|
MERCURE_JWT_SECRET: ${MERCURE_JWT_SECRET:-}
|
|
volumes:
|
|
- app_secrets:/app/var/secrets
|
|
|
|
php:
|
|
image: *app-image
|
|
restart: unless-stopped
|
|
environment:
|
|
<<: *app-env
|
|
SERVER_NAME: ${SERVER_NAME:-localhost, :443}, php:80
|
|
MAILER_DSN: ${MAILER_DSN:-null://null}
|
|
APP_CONTAINER_NAME: web
|
|
volumes:
|
|
- caddy_data:/data
|
|
- caddy_config:/config
|
|
- app_secrets:/app/var/secrets
|
|
- app_attachments:/app/var/attachments
|
|
- app_raw:/app/var/raw
|
|
- app_uploads:/app/var/uploads
|
|
ports:
|
|
- target: 80
|
|
published: ${HTTP_PORT:-80}
|
|
protocol: tcp
|
|
- target: 443
|
|
published: ${HTTPS_PORT:-443}
|
|
protocol: tcp
|
|
- target: 443
|
|
published: ${HTTP3_PORT:-443}
|
|
protocol: udp
|
|
depends_on:
|
|
secrets-init:
|
|
condition: service_completed_successfully
|
|
database:
|
|
condition: service_healthy
|
|
|
|
worker:
|
|
image: *app-image
|
|
restart: unless-stopped
|
|
command: php bin/console app:work
|
|
init: true
|
|
stop_grace_period: 30s
|
|
environment:
|
|
<<: *app-env
|
|
APP_CONTAINER_NAME: worker
|
|
networks:
|
|
default:
|
|
aliases: [mercure]
|
|
volumes:
|
|
- mercure_data:/data
|
|
- mercure_config:/config
|
|
- app_secrets:/app/var/secrets
|
|
- app_attachments:/app/var/attachments
|
|
- app_raw:/app/var/raw
|
|
- app_uploads:/app/var/uploads
|
|
healthcheck:
|
|
disable: true
|
|
depends_on:
|
|
secrets-init:
|
|
condition: service_completed_successfully
|
|
database:
|
|
condition: service_healthy
|
|
|
|
database:
|
|
image: postgres:${POSTGRES_VERSION:-18}-alpine
|
|
environment:
|
|
POSTGRES_DB: ${POSTGRES_DB:-app}
|
|
POSTGRES_USER: ${POSTGRES_USER:-app}
|
|
POSTGRES_PASSWORD_FILE: /run/plmail/postgres_password
|
|
depends_on:
|
|
secrets-init:
|
|
condition: service_completed_successfully
|
|
healthcheck:
|
|
test: ["CMD", "pg_isready", "-d", "${POSTGRES_DB:-app}", "-U", "${POSTGRES_USER:-app}"]
|
|
interval: 5s
|
|
timeout: 5s
|
|
retries: 30
|
|
start_period: 60s
|
|
volumes:
|
|
- database_data:/var/lib/postgresql
|
|
- app_secrets:/run/plmail:ro
|
|
command:
|
|
- "postgres"
|
|
- "-c"
|
|
- "shared_preload_libraries=pg_stat_statements"
|
|
- "-c"
|
|
- "pg_stat_statements.track=top"
|
|
|
|
ntfy:
|
|
image: binwiederhier/ntfy
|
|
profiles: [push]
|
|
restart: unless-stopped
|
|
command: serve
|
|
environment:
|
|
NTFY_BASE_URL: ${NTFY_BASE_URL:-http://${SERVER_NAME:-localhost}:${NTFY_PORT:-8090}}
|
|
NTFY_LISTEN_HTTP: ':80'
|
|
NTFY_CACHE_FILE: /var/lib/ntfy/cache.db
|
|
NTFY_AUTH_FILE: /var/lib/ntfy/auth.db
|
|
NTFY_AUTH_DEFAULT_ACCESS: ${NTFY_AUTH_DEFAULT_ACCESS:-read-write}
|
|
NTFY_VISITOR_REQUEST_LIMIT_BURST: '60'
|
|
NTFY_VISITOR_REQUEST_LIMIT_REPLENISH: '5s'
|
|
ports:
|
|
- "${NTFY_PORT:-8090}:80"
|
|
volumes:
|
|
- ntfy_data:/var/lib/ntfy
|
|
healthcheck:
|
|
test: ["CMD", "wget", "-qO-", "http://localhost/v1/health"]
|
|
timeout: 5s
|
|
retries: 5
|
|
start_period: 20s
|
|
|
|
volumes:
|
|
app_secrets:
|
|
app_attachments:
|
|
app_raw:
|
|
app_uploads:
|
|
caddy_data:
|
|
caddy_config:
|
|
database_data:
|
|
mercure_data:
|
|
mercure_config:
|
|
ntfy_data:
|