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
| Service | Image | Purpose | Ports |
|---|---|---|---|
cleanmails | Built from Dockerfile | Go backend + React frontend | 8080 (internal) |
caddy | caddy:2-alpine | Reverse proxy + auto SSL | 80, 443 |
mailserver | docker-mailserver:latest | Postfix + 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
| Volume | Purpose |
|---|---|
cleanmails-data | Application data |
cleanmails.db | SQLite database (bind mount) |
caddy-data | SSL certificates |
caddy-config | Caddy configuration |
mail-data | Mailboxes and email storage |
mail-state | Mail server state |
mail-logs | Mail server logs |
mail-config | Mail 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 psDocker 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:
- Stage 1: Build React frontend (Node 20)
- Stage 2: Build Go backend (Go 1.22)
- Stage 3: Final Alpine image with binary + static assets
Final image size is ~50MB.