This commit is contained in:
KARMACOMA 2025-12-27 03:14:53 +01:00
parent fb3087f897
commit 0fe5927a0d
2 changed files with 87 additions and 88 deletions

View file

@ -1,38 +1,37 @@
services:
mailserver:
image: ghcr.io/docker-mailserver/docker-mailserver:latest
container_name: mailserver
# Provide the FQDN of your mail server here (Your DNS MX record should point to this value)
hostname: mail.karmacoma.dev
ports:
- "25:25"
- "465:465"
- "587:587"
- "993:993"
volumes:
- ./docker-data/dms/mail-data/:/var/mail/
- ./docker-data/dms/mail-state/:/var/mail-state/
- ./docker-data/dms/mail-logs/:/var/log/mail/
- ./docker-data/dms/config/:/tmp/docker-mailserver/
- /etc/localtime:/etc/localtime:ro
environment:
- ENABLE_RSPAMD=1
- ENABLE_CLAMAV=1
- ENABLE_FAIL2BAN=1
cap_add:
- NET_ADMIN # For Fail2Ban to work
restart: always
version: "3.9"
webmail:
image: ghcr.io/the-djmaze/snappymail:latest
container_name: webmail
depends_on:
- mailserver
ports:
- "8080:80"
environment:
# Log to stdout so container logs are visible in Coolify and docker logs
- SNAPPYMAIL_LOG_TO_STDOUT=1
volumes:
- ./docker-data/snappymail/:/snappymail/data/
services:
poste:
image: analogic/poste.io:latest
container_name: poste
restart: unless-stopped
hostname: ${POSTE_HOSTNAME}
environment:
# Traefik handles TLS termination; keep poste in HTTP mode on an internal port
- HTTPS=OFF
- HTTP_PORT=8080
- HTTPS_PORT=8443
- TZ=${TZ:-UTC}
- DISABLE_CLAMAV=${DISABLE_CLAMAV:-false}
- DISABLE_RSPAMD=${DISABLE_RSPAMD:-false}
ports:
- "25:25" # SMTP
- "465:465" # SMTPS
- "587:587" # Submission
- "110:110" # POP3
- "143:143" # IMAP
- "993:993" # IMAPS
- "995:995" # POP3S
- "4190:4190" # ManageSieve
volumes:
- poste-data:/data
networks:
- poste-mail
volumes:
poste-data:
networks:
poste-mail:
driver: bridge
${TRAEFIK_NETWORK:-coolify-overlay}:
external: true

106
readme.md
View file

@ -1,63 +1,63 @@
# Mail Stack on Coolify with OIDC Webmail
# Poste.io behind Traefik (Coolify)
This stack pairs **docker-mailserver** with **SnappyMail** as a modern webmail UI that can sit behind your OIDC provider. Deploy it through Coolify with this repository.
Self-hosted poste.io with HTTP(S) served by Traefik (managed by Coolify) and mail protocols exposed directly to the host.
## Components
- docker-mailserver: SMTP/IMAP server with spam/AV/Fail2Ban enabled.
- SnappyMail: lightweight webmail with OAuth2/OIDC login support.
## Network scheme (per poste.io docs)
- Mail ports (SMTP/IMAP/POP3/Sieve) are published directly on the host so clients and remote MTAs reach the real server IP.
- HTTP(S) for the admin UI and webmail is terminated by Traefik and forwarded internally to poste.io on port 8080 (poste runs with `HTTPS=OFF`).
- Set Docker `userland-proxy` to `false` to avoid losing real client IPs when publishing mail ports (poste.io warns about open relay risk when proxying mail ports).
## Prerequisites
- DNS: `MX` record to `mail.your-domain.tld`, plus `A`/`AAAA` for both `mail.your-domain.tld` and `webmail.your-domain.tld`.
- TLS: issue certificates (Coolify can request via Traefik/Lets Encrypt if you publish through it).
- SMTP ports 25/465/587 and IMAP 993 open to the internet.
- An OIDC provider (e.g., Authentik, Keycloak, Azure AD) with a client ready to configure.
- Domain with A/AAAA record for `POSTE_HOSTNAME` (e.g., `mail.example.com`) pointing to the server public IP.
- MX record pointing to `POSTE_HOSTNAME`.
- Optional but recommended: PTR (rDNS) matching `POSTE_HOSTNAME`.
- DNS access to add SPF/TXT, DKIM (after initial setup), and DMARC records.
- Coolify with its Traefik stack running and an external Docker network available (default name `coolify-overlay`).
## Configure Docker for real client IPs
Create or update `/etc/docker/daemon.json`:
```json
{
"userland-proxy": false
}
```
Restart Docker (`sudo systemctl restart docker`). This keeps source IPs visible to poste.io while using published ports.
## Environment variables
Create `.env` next to `docker-compose.yml` (adjust values):
```
POSTE_HOSTNAME=mail.example.com
TZ=UTC
TRAEFIK_NETWORK=coolify-overlay
TRAEFIK_CERTRESOLVER=coolify
DISABLE_CLAMAV=false
DISABLE_RSPAMD=false
```
## Deploy with Coolify
1. **Create an application from this repo** in Coolify and choose “Docker Compose”.
2. **Volumes**: Coolify will create them from the compose file paths. Ensure the persistent paths below map to durable storage:
- `./docker-data/dms/mail-data/`, `./docker-data/dms/mail-state/`, `./docker-data/dms/mail-logs/`, `./docker-data/dms/config/`
- `./docker-data/snappymail/`
3. **Environment**: adjust `hostname` for the mailserver and expose any extra docker-mailserver envs you need (aliases, relays, etc.).
4. **Networking**: publish ports 25/465/587/993 for mail delivery. Expose port 8080 from the `webmail` service to the internet (ideally behind HTTPS via Coolify/Traefik). If you front it with Traefik, set the appropriate labels and disable the direct `ports` stanza.
5. **Deploy** the stack. Coolify will start `mailserver` and `webmail` containers.
1) Ensure the Traefik network exists (default `coolify-overlay`). If not, create it: `docker network create coolify-overlay`.
2) Import this `docker-compose.yml` into a Coolify “Docker Compose” app. Set the environment variables above in Coolify.
3) Attach the app to Coolifys Traefik network (`TRAEFIK_NETWORK`). Coolify will inject the network automatically when selected.
4) Deploy. Traefik will request a certificate via `TRAEFIK_CERTRESOLVER` and route `https://POSTE_HOSTNAME` to poste.io on port 8080.
## Bootstrap docker-mailserver
Run these once after the containers are healthy (from the host or via Coolify shell):
If running outside Coolify, you can still deploy with `docker compose up -d` after creating the network.
```bash
docker compose exec mailserver setup email add user@your-domain.tld "SuperSecretPassword"
docker compose exec mailserver setup alias add postmaster@your-domain.tld user@your-domain.tld
```
## Exposed ports (host)
- 25 SMTP, 465 SMTPS, 587 Submission
- 110 POP3, 995 POP3S
- 143 IMAP, 993 IMAPS
- 4190 ManageSieve
Add DNS TXT records for SPF/DKIM/DMARC using docker-mailserver guidance, then reload:
## First-time setup
1) Wait for containers to start: `docker compose ps`.
2) Open `https://POSTE_HOSTNAME` to reach the admin UI (proxied by Traefik). Complete the poste.io onboarding (admin mailbox + password, DKIM key generation, etc.).
3) Add generated DKIM TXT record and ensure SPF and DMARC records are present.
4) Test SMTP/IMAP with your client against the host IP/hostname.
```bash
docker compose exec mailserver setup reload
```
## Configure SnappyMail for IMAP/SMTP
1. Open the admin panel at `https://webmail.your-domain.tld/?admin` (default admin password is shown on first run; change it immediately).
2. Set **IMAP** host to `mailserver`, port `993`, security **SSL/TLS**.
3. Set **SMTP** host to `mailserver`, port `587`, security **STARTTLS**, authentication **Use user credentials**.
4. Save and test with one of the mail accounts you created above.
## Enable OIDC in SnappyMail
SnappyMail supports OAuth2/OIDC providers. Configure it in the admin UI:
1. In **Admin → Domains/Auth → OAuth**, add a **Custom / Generic OIDC** provider.
2. When prompted, SnappyMail shows a **Redirect URI**; copy this exact value into your OIDC client configuration.
3. In your OIDC provider, create a public/confidential client with these basics:
- **Grant type**: Authorization Code with PKCE (preferred) or standard code.
- **Scopes**: `openid email profile`.
- **Redirect URI**: the one SnappyMail displayed.
4. Back in SnappyMail, fill the provider fields:
- **Authorization endpoint** and **Token endpoint** from your IdP.
- **UserInfo endpoint** (for email/subject mapping).
- **Client ID/Secret** matching the client you created.
- **Login attribute mapping**: map email/subject to the mailbox name (e.g., `email``user@your-domain.tld`).
5. Save and test “Login with <provider>”. Successful OIDC login should drop you into the mailbox without prompting for a separate password.
## Operating tips
- Back up `./docker-data/` regularly; it holds mail, state, and SnappyMail config.
- Use Coolify health checks to surface container issues; restart policies are already defined in the compose file.
- For HTTPS, prefer running `webmail` behind Coolifys Traefik with automatic certificates instead of exposing port 8080 directly.
- If you rotate OIDC credentials, update them in SnappyMail admin immediately to avoid login failures.
## Notes
- Poste.io still handles STARTTLS on mail ports directly; Traefik is only for HTTP(S).
- If you need Lets Encrypt inside poste.io instead of Traefik, remove `HTTPS=OFF` and forward `/.well-known` from Traefik, but avoid port conflicts with Traefiks 80/443.
- Keep an eye on spam/relay checks in the poste.io admin UI to confirm real client IPs are detected.