Deploying a Mailu App
Introduction
Mailu is an open-source mail server suite (Postfix, Dovecot, Rspamd, and web admin) packaged for containerized deployments. Deploying Mailu with a Dockerfile on Klutch.sh provides reproducible builds, managed secrets, and persistent storage for mail data, DKIM keys, and configuration—all orchestrated from klutch.sh/app. This guide covers installation, repository prep, a production-ready Dockerfile, deployment steps, Nixpacks overrides, sample SMTP usage, and production best practices.
Prerequisites
- A Klutch.sh account (create one)
- A GitHub repository containing your Mailu configuration (GitHub is the only supported git source)
- Docker familiarity and mail server administration basics
- Domain DNS control (MX, SPF, DKIM, DMARC records and reverse DNS)
- Storage for mailboxes, queue, DKIM keys, and logs
For onboarding, see the Quick Start.
Architecture and ports
- Mailu web/admin serves HTTP; set the internal container port to
80for the UI/API. - Mail protocols use TCP ports: SMTP
25/465/587, IMAP143/993, POP3110/995. Expose these via separate Klutch.sh TCP apps (external port8000mapped to the internal protocol port). - Persistent storage is required for mail data and DKIM keys.
Repository layout
mailu/├── Dockerfile # Must be at repo root for auto-detection├── config/ # Optional overrides├── data/ # Mail and state (mount as volume)└── .env.example # Template only; no secretsKeep secrets out of Git; store them in Klutch.sh environment variables.
Installation (local) and starter commands
Smoke-test Mailu locally:
docker run --rm -p 80:80 -p 25:25 -p 587:587 \ -e MAILU_SECRET_KEY=$(openssl rand -hex 16) \ -e HOSTNAME=mail.example.com \ -e DOMAIN=example.com \ -e TZ=UTC \ -v $(pwd)/data:/data \ -v $(pwd)/config:/overrides \ mailu/mailu:2.0Optional helper start.sh for portability and Nixpacks fallback:
#!/usr/bin/env bashset -euo pipefailexec /start.pyMake it executable with chmod +x start.sh.
Dockerfile for Mailu (production-ready)
Place this Dockerfile at the repo root; Klutch.sh auto-detects it (no Docker selection in the UI):
FROM mailu/mailu:2.0
WORKDIR /app
# Optional: copy custom overridesCOPY config /overrides
EXPOSE 80 25 465 587 110 995 143 993CMD ["/start.py"]Notes:
- Pin the image tag (e.g.,
mailu/mailu:2.0) for reproducible behavior. - Only expose the ports you actually need in Klutch.sh; set HTTP for the web UI (80) and separate TCP apps for mail protocols.
Environment variables (Klutch.sh)
Set these in the Klutch.sh app settings (Secrets tab) before deploying:
PORT=80MAILU_SECRET_KEY=<secure-hex>(required)HOSTNAME=mail.example.comDOMAIN=example.comTZ=UTCADMIN=<admin@example.com>PASSWORD=<strong-admin-password>TLS_FLAVOR=letsencrypt(ormail,cert)LOG_LEVEL=INFO
If you deploy without the Dockerfile and need Nixpacks overrides:
NIXPACKS_BUILD_CMD="echo Mailu uses prebuilt image"NIXPACKS_START_CMD=/start.pyNIXPACKS_JDK_VERSION=17(not required for Mailu, provided for completeness)
Attach persistent volumes
In Klutch.sh storage settings, add mount paths and sizes (no names required):
/data— required for mail data, queue, and state./overrides— optional for custom configuration and templates.
Ensure these paths are writable inside the container.
Deploy Mailu on Klutch.sh (Dockerfile workflow)
- Push your repository (with the Dockerfile at the root) to GitHub.
- Open klutch.sh/app, create a project, and add an app.
- Connect the GitHub repository; Klutch.sh automatically detects the Dockerfile.
- Choose HTTP traffic for the Mailu admin/UI and set the internal port to
80. - Add the environment variables above (secret key, hostname, domain, TLS flavor, admin credentials, and any
NIXPACKS_*overrides if you temporarily deploy without the Dockerfile). - Attach persistent volumes for
/data(and/overridesif used), selecting sizes that fit your mailbox and config needs. - Deploy. The Mailu UI will be reachable at
https://example-app.klutch.sh; attach a custom domain if desired.
For SMTP/IMAP/POP3, create separate Klutch.sh TCP apps with internal ports 25, 465, 587, 143, 993, 110, or 995 as needed, reachable externally at example-app.klutch.sh:8000.
Sample SMTP test
Use openssl to send a quick SMTP command (replace placeholders):
openssl s_client -starttls smtp -crlf -connect example-app.klutch.sh:8000 <<'EOF'EHLO example.comAUTH LOGINBASE64_USERNAMEBASE64_PASSWORDMAIL FROM:<you@example.com>RCPT TO:<you@example.com>DATASubject: Test from Mailu on Klutch.sh
Hello from Mailu on Klutch.sh..QUITEOFHealth checks and production tips
- Probe the web UI (
/) for basic health; use SMTP/IMAP checks via monitoring tools for protocol health. - Enforce HTTPS at the edge; forward HTTP to port 80 internally.
- Pin image tags and upgrade intentionally; back up data before updates.
- Monitor disk usage on
/dataand resize volumes before they fill. - Maintain DNS records (MX, SPF, DKIM, DMARC) and reverse DNS for deliverability.
- Rotate admin credentials regularly; store them only in Klutch.sh secrets.
Mailu on Klutch.sh combines reproducible Docker builds with managed secrets, durable mail storage, and flexible HTTP/TCP routing. With the Dockerfile at the repo root and ports set appropriately (80 for UI, TCP apps for mail protocols), you can run a self-hosted mail suite without extra YAML or workflow overhead.