Deploying Mox Mail Server with Traefik and Docker Compose: A Lightweight Mailcow Alternative
Table of Contents ๐
This guide provides a straightforward method for deploying Mox, a modern and resource-efficient mail server, and integrating it into an existing Traefik stack. Mox is an excellent all-in-one alternative to more complex solutions like Mailcow, as it bundles services like SMTP, IMAP, webmail, and spam filtering into a single, easy-to-manage application. By leveraging our Traefik and CrowdSec setup, you can secure its web administration interface right from the start.
Mox aims to simplify self-hosted email, making it accessible for users who want to maintain control over their digital communications without the complexity of configuring multiple services.
Changelog
| Date | Change |
|---|---|
| 2025-11-12 | Initial Version: Guide created for integrating Mox with the Traefik v3 stack. |
1. Prerequisites
This tutorial assumes you have a fully operational Traefik v3 and CrowdSec environment. This setup is essential for routing, TLS, and security.
| โ ๏ธ HARD REQUIREMENT |
The following steps will not work correctly without the Traefik stack running as described in the prerequisite guide.
|
You will also need:
- A domain name for your mail server.
- The ability to add and modify DNS records (specifically
AandMXrecords) for your domain. sudoor root access to your server.
2. Directory Structure
First, weโll create a dedicated directory for the Mox configuration and data. This keeps your project isolated and organized.
sudo mkdir -p /opt/containers/mox
cd /opt/containers/mox
3. Configuration
We will now create the necessary environment, Docker Compose, and Dockerfile.
3.1. Environment File (.env)
This file will store variables specific to your setup.
sudo tee .env > /dev/null << 'EOF'
TZ=Europe/Berlin
DOMAIN_NAME=your-domain.com
MOX_ADMIN_EMAIL=admin@your-domain.com
EOF
Be sure to replace your-domain.com with your actual domain and adjust the timezone if necessary.
3.2. Dockerfile (Build from Source)
To ensure we are running the latest, most secure version directly from the developer, we will build the Mox image ourselves instead of using a community-maintained image.
| โน๏ธ WHY BUILD FROM SOURCE? |
Building the image directly from the official GitHub repository guarantees you have the latest stable release with no third-party modifications. |
Create the Dockerfile in your /opt/containers/mox directory:
sudo tee Dockerfile > /dev/null << 'EOF'
# Stage 1: Build the Go binary
FROM golang:1.22-alpine AS builder
RUN apk add --no-cache git
RUN git clone https://github.com/mjl-/mox.git /src/mox
WORKDIR /src/mox
# Build a smaller, optimized binary without debug symbols
RUN go build -trimpath -ldflags="-s -w" ./cmd/mox
# Stage 2: Create the final, minimal image
FROM alpine:latest
RUN apk add --no-cache ca-certificates
COPY --from=builder /src/mox/mox /usr/local/bin/mox
# Create a dedicated, non-root user for the service
RUN adduser -D -h /data mox
USER mox
WORKDIR /data
VOLUME /data
EXPOSE 25 465 587 993 80
ENTRYPOINT ["mox"]
EOF
3.3. Docker Compose (docker-compose.yml)
This file defines the Mox service and tells Traefik how to route traffic to it.
sudo tee docker-compose.yml > /dev/null << 'EOF'
version: "3.9"
services:
mox:
build: .
container_name: mox
restart: unless-stopped
environment:
- TZ=${TZ}
volumes:
- ./data:/data
networks:
- proxy
healthcheck:
test: ["CMD", "mox", "version"]
interval: 60s
timeout: 10s
retries: 3
labels:
- "traefik.enable=true"
- "traefik.http.routers.mox.rule=Host(`mail.${DOMAIN_NAME}`)"
- "traefik.http.routers.mox.entrypoints=websecure"
- "traefik.http.routers.mox.tls.certresolver=tls_resolver"
- "traefik.http.services.mox.loadbalancer.server.port=80"
- "traefik.http.services.mox.loadbalancer.server.scheme=http"
- "traefik.http.routers.mox.middlewares=security-headers@file,crowdsec-bouncer@docker"
networks:
proxy:
external: true
EOF
Configuration Explained:
build: .: Tells Docker Compose to build an image from the localDockerfile.- Security: The container runs as a dedicated, non-privileged user (
mox) for enhanced security. healthcheck:Periodically checks if the Mox service is running correctly, providing a clear status indocker ps.loadbalancer.server.port=80&scheme=http: Traefik handles public HTTPS and communicates with Mox internally via standard HTTP, centralizing TLS management.middlewares=...crowdsec-bouncer@docker: Secures the web UI with our CrowdSec bouncer.
4. DNS Configuration
For your mail server to be reachable, you need to configure your domainโs DNS records.
A Record: Point the subdomain for Mox to your serverโs IP address.
mail.your-domain.com. A <your_server_ip>MX Record: After setup, set an MX record to direct email for your domain to the Mox server.
your-domain.com. MX 10 mail.your-domain.com.
| ๐ก SPF, DKIM, AND DMARC RECORDS |
When you complete the Mox setup wizard, it will display the necessary DNS |
5. Launch and Set Up Mox
With the configuration in place, you can now build and start the container.
Build and Start the Service:
# From within the /opt/containers/mox directory sudo docker compose up -d --buildThe
--buildflag is important for the first launch and whenever you want to update Mox.Access the Admin Wizard: Navigate to your Mox admin interface in a web browser:
https://mail.your-domain.com/adminOn your first visit, Mox presents an interactive setup wizard to guide you through the initial configuration.
6. Updating Mox
Because we are building the image from the source code, updating is a simple process of rebuilding the image and restarting the container.
cd /opt/containers/mox
# Pull the latest source code and rebuild the image
sudo docker compose build --pull --no-cache
# Restart the container with the new image
sudo docker compose up -d --force-recreate --remove-orphans
The latest Mox version will be automatically pulled from GitHub during the build step.
7. Maintenance and Backups
A key advantage of Mox is its simplicity in maintenance.
Built-in Backups
Mox includes a command to back up its entire configuration and mail data into a single file.
# Execute this command to create a backup inside the container
sudo docker exec -it mox mox backup /data/backup.tgz
You can then copy this file out of the container volume for off-site storage.
Volume Backup
For a complete backup strategy, you should also regularly back up the entire ./data volume using tools like rsync or restic.
8. Resource Profile
Mox is exceptionally efficient, making it a great choice for servers with limited resources.
- RAM: Typically idles around 200-300 MB and rarely exceeds 500 MB under load.
- CPU: CPU usage is minimal, usually under 1%.
- Performance: On small VPS systems (1 vCPU / 1 GB RAM), Mox remains highly responsive even under a light daily mail load (e.g., 100-200 messages per day).
Conclusion
You have successfully deployed Mox using a secure, best-practice approach. By building the image from the official source and leveraging Traefik for proper TLS termination, you have a modern, resource-efficient, and secure solution for self-hosting your own email. This setup gives you full control over your data with minimal maintenance overhead.
Note: Mox is under active development by Marten van Leeuwen. Check the Mox Releases page for the latest changelog before rebuilding your image.


