services: app: build: context: . dockerfile: Dockerfile restart: unless-stopped container_name: '${APP_NAME}-app' ports: - "10080:80" environment: SERVER_NAME: ${SERVER_NAME:-:80} APP_ENV: prod APP_SECRET: ${APP_SECRET} DATABASE_URL: >- postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?serverVersion=${POSTGRES_VERSION}&charset=utf8 POSTGRES_URL: db POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB} MERCURE_URL: http://localhost/.well-known/mercure MERCURE_PUBLIC_URL: https://${APP_PUBLIC_HOSTNAME:-localhost}/.well-known/mercure MERCURE_JWT_SECRET: ${MERCURE_JWT_SECRET} MERCURE_JWT_TOKEN: ${MERCURE_JWT_TOKEN} MERCURE_SUBSCRIBER_JWT: ${MERCURE_SUBSCRIBER_JWT} MAILER_DSN: smtp://mail:25?verify_peer=0 RECAPTCHA_SITE_KEY: ${RECAPTCHA_SITE_KEY} RECAPTCHA_SECRET_KEY: ${RECAPTCHA_SECRET_KEY} WEBAUTHN_RP_ID: ${WEBAUTHN_RP_ID:-localhost} WEBAUTHN_ORIGIN: ${WEBAUTHN_ORIGIN:-https://localhost} MINIO_ROOT_USER: ${MINIO_ROOT_USER} MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD} MINIO_ENDPOINT: http://minio:9000 MINIO_PUBLIC_URL: ${MINIO_PUBLIC_URL:-http://localhost:9000} volumes: - app_var:/app/var - caddy_data:/data - caddy_config:/config depends_on: db: condition: service_healthy mail: condition: service_started minio: image: minio/minio:RELEASE.2025-09-07T16-13-09Z-cpuv1 restart: unless-stopped container_name: '${APP_NAME}-minio' command: server /data --console-address ":9001" ports: - "9000:9000" - "9001:9001" environment: MINIO_ROOT_USER: ${MINIO_ROOT_USER} MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD} volumes: - minio_data:/data healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] interval: 5s timeout: 5s retries: 10 start_period: 10s minio_init: image: minio/minio:RELEASE.2025-09-07T16-13-09Z-cpuv1 restart: "no" container_name: '${APP_NAME}-minio-init' depends_on: minio: condition: service_healthy environment: MINIO_ROOT_USER: ${MINIO_ROOT_USER} MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD} volumes: - ./docker/minio-init.sh:/minio-init.sh:ro entrypoint: ["/bin/sh", "/minio-init.sh"] mail: image: boky/postfix:latest restart: unless-stopped container_name: '${APP_NAME}-mail' hostname: postfix.mail.${MAIL_DOMAIN:-localhost} environment: ALLOWED_SENDER_DOMAINS: ${MAIL_DOMAIN:-localhost} HOSTNAME: postfix.mail.${MAIL_DOMAIN:-localhost} POSTFIX_myhostname: postfix.mail.${MAIL_DOMAIN:-localhost} POSTFIX_mynetworks: "127.0.0.0/8 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16" POSTFIX_smtpd_tls_security_level: none RELAYHOST: ${MAIL_RELAYHOST:-} RELAYHOST_AUTH: ${MAIL_RELAYHOST_AUTH:-} RELAYHOST_PASSWORD: ${MAIL_RELAYHOST_PASSWORD:-} volumes: - postfix_spool:/var/spool/postfix db: image: postgres:${POSTGRES_VERSION:-18}-alpine restart: unless-stopped container_name: '${APP_NAME}-db' environment: POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB} volumes: - postgres_data:/var/lib/postgresql/data healthcheck: test: [ "CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}" ] interval: 5s timeout: 3s retries: 10 start_period: 10s ports: - "15432:5432" volumes: app_var: postgres_data: caddy_data: caddy_config: postfix_spool: minio_data: