services:
  app:
    build:
      context: .
    container_name: mailhub-app
    restart: unless-stopped
    env_file:
      - .env
    environment:
      PORT: 3000
      DATA_DIR: /data
      POSTFIX_LOG_FILE: /data/postfix-logs/mail.log
      MAIL_ACCESS_BACKEND: dovecot
      MAILDIR_ROOT: /data/maildir
      DOVECOT_AUTH_ENABLED: "true"
      DOVECOT_AUTH_HOST: 0.0.0.0
      DOVECOT_AUTH_PORT: 3001
      DOVECOT_AUTH_SECRET_FILE: /run/secrets/dovecot_auth_secret
    ports:
      - "127.0.0.1:${APP_PORT:-3025}:3000"
      - "${SUBMISSION_BIND:-0.0.0.0}:25:25"
      - "${SUBMISSION_BIND:-0.0.0.0}:465:465"
      - "${SUBMISSION_BIND:-0.0.0.0}:587:587"
      - "${SUBMISSION_BIND:-0.0.0.0}:${SUBMISSION_ALT_PORT:-2525}:2525"
    expose:
      - "3001"
    volumes:
      - ./data:/data
      - ./certs:/certs:ro
    secrets:
      - dovecot_auth_secret
    networks:
      - mailhub
      - dovecot_internal
    depends_on:
      postfix:
        condition: service_started
    healthcheck:
      test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:3000/healthz').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 15s

  dovecot:
    image: dovecot/dovecot:2.4.4
    container_name: mailhub-dovecot
    restart: unless-stopped
    hostname: ${MAIL_HOSTNAME:-mailhub.local}
    environment:
      SUBMISSION_TLS_CERT: ${SUBMISSION_TLS_CERT:-/certs/mailhub.example.com.crt}
      SUBMISSION_TLS_KEY: ${SUBMISSION_TLS_KEY:-/certs/mailhub.example.com.key}
    ports:
      - "${IMAP_BIND:-0.0.0.0}:143:31143"
      - "${IMAP_BIND:-0.0.0.0}:993:31993"
      - "${POP3_BIND:-0.0.0.0}:110:31110"
      - "${POP3_BIND:-0.0.0.0}:995:31995"
    volumes:
      - ./data/maildir:/srv/vmail
      - ./certs:/certs:ro
      - ./docker/dovecot/auth.conf:/etc/dovecot/conf.d/auth.conf:ro
      - ./docker/dovecot/ssl.conf:/etc/dovecot/conf.d/ssl.conf:ro
      - ./docker/dovecot/mailhub.conf:/etc/dovecot/conf.d/zz-mailhub.conf:ro
      - ./docker/dovecot/auth.lua:/etc/dovecot/auth.lua:ro
    secrets:
      - dovecot_auth_secret
    networks:
      - dovecot_internal
      - dovecot_public
    depends_on:
      app:
        condition: service_healthy
    read_only: true
    tmpfs:
      - /tmp:mode=1777
      - /run/dovecot:mode=1777
    security_opt:
      - no-new-privileges:true
    healthcheck:
      test: ["CMD-SHELL", "test -r /run/secrets/dovecot_auth_secret && test -s /run/secrets/dovecot_auth_secret && test -w /srv/vmail && doveadm service status imap-login pop3-login"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 15s

  postfix:
    build:
      context: ./docker/postfix
    container_name: mailhub-postfix
    restart: unless-stopped
    env_file:
      - .env
    environment:
      POSTFIX_LOG_FILE: /var/log/mailhub/mail.log
    hostname: ${MAIL_HOSTNAME:-mailhub.local}
    volumes:
      - ./data/postfix-logs:/var/log/mailhub
    networks:
      - mailhub
    healthcheck:
      test: ["CMD-SHELL", "postfix status >/dev/null 2>&1 || exit 1"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 20s

secrets:
  dovecot_auth_secret:
    file: ./data/secrets/dovecot_auth_secret

networks:
  mailhub:
  dovecot_internal:
    internal: true
  dovecot_public:
