Configuration

Docker Compose

Cleanmails runs as a three-container Docker Compose stack: the application, a reverse proxy (Caddy), and a mail server (docker-mailserver).

Services

ServiceImagePurposePorts
cleanmailsBuilt from DockerfileGo backend + React frontend8080 (internal)
caddycaddy:2-alpineReverse proxy + auto SSL80, 443
mailserverdocker-mailserver:latestPostfix + Dovecot (SMTP/IMAP)25, 587, 465, 993, 143

Caddyfile

For HTTP-only (no domain):

Caddyfile
:80 {
    reverse_proxy cleanmails:8080
}

For HTTPS with a domain:

Caddyfile
yourdomain.com {
    reverse_proxy cleanmails:8080
}

Caddy auto-provisions Let's Encrypt certificates when a domain is configured.

Volumes

VolumePurpose
cleanmails-dataApplication data
cleanmails.dbSQLite database (bind mount)
caddy-dataSSL certificates
caddy-configCaddy configuration
mail-dataMailboxes and email storage
mail-stateMail server state
mail-logsMail server logs
mail-configMail server configuration

Common Commands

bash
# Start all services
docker compose up -d

# Rebuild after update
docker compose up -d --build

# View logs
docker compose logs -f

# Stop all services
docker compose down

# Restart a single service
docker compose restart cleanmails

# Check status
docker compose ps
Docker socket mount

The Cleanmails container mounts /var/run/docker.sock to manage the mail server (create/delete mailboxes via docker exec). This is required for internal mailbox management.

Build Process

The Dockerfile uses a multi-stage build:

  1. Stage 1: Build React frontend (Node 20)
  2. Stage 2: Build Go backend (Go 1.22)
  3. Stage 3: Final Alpine image with binary + static assets

Final image size is ~50MB.