Self-hosted service
mailcow/mailcow-dockerized avatar
mailcow/mailcow-dockerized

mailcow: dockerized is a Docker Compose mail server stack you run yourself

mailcow: dockerized - 🐮 + 🐋 = 💕

13,546 stars1,818 forksJavaScriptGPL-3.0

At a glance

What is it?
mailcow: dockerized bundles Postfix, Dovecot, Rspamd, SOGo, ClamAV, MariaDB, Redis and Unbound into one Compose project. It suits operators who want a full mail stack on their own hardware, and it is the wrong choice if you cannot own the DNS and port 25.
Who is it for?
Adopt mailcow: dockerized if you control a dedicated host, the DNS records for the domain, and inbound port 25, and you are willing to keep the Compose stack current with update.sh. Do not adopt it if you need mail without an always-on machine, if your provider blocks port 25, or if you want a single binary you can reason about end to end.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 5 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What mailcow: dockerized actually solves, and for whom

Running a mail server means running several servers that must agree with each other. SMTP, IMAP, spam filtering, virus scanning, a database, a web UI, a groupware layer and a DNS resolver all have to be configured to talk to one another, and any one of them being wrong produces the same symptom: mail that silently does not arrive. mailcow: dockerized packages that set into a single Compose project. The repository's top level shows the shape of it: docker-compose.yml, generate_config.sh, update.sh, a data directory, and helper-scripts.

The audience is narrow and specific. This is for an operator who has a host they control, wants a complete mail stack rather than a set of components to assemble, and accepts that mail is infrastructure with an ongoing cost. It is not for someone who wants mail to be somebody else's problem. The README points to the official documentation for installation and support instructions, which tells you where the project expects the operational detail to live: not in the repository root.

The licensing matters here. The README states that any part of mailcow itself is released under GNU General Public License, Version 3, and that mailcow makes use of various open-source software whose licenses you should agree with before using mailcow. The project is managed and maintained by The Infrastructure Company GmbH, and mailcow is a registered word mark of that company. That combination, a GPL-3.0 codebase plus a company behind it offering support contracts and a SAL, is the commercial context you are adopting into.

The Compose topology: Unbound, MariaDB, Redis and the rest

The docker-compose.yml in the repository defines services rather than a single image. Unbound runs at a fixed address on the internal network, with the alias unbound, and mounts ./data/conf/unbound/unbound.conf read-only into the container. MariaDB 10.11 depends on both unbound-mailcow and netfilter-mailcow, keeps its data in a named volume, and mounts ./data/conf/mysql/ read-only as configuration. Redis 7.4.11-alpine starts through a shell script at ./data/conf/redis/redis-conf.sh and is given a somaxconn sysctl of 4096.

The network addressing is worth reading closely before you deploy. Unbound takes the last octet .254 and Redis takes .249 on the mailcow-network, with the base prefix coming from an IPV4_NETWORK environment variable that defaults to 172.22.1. If that range collides with something on your host or your VPN, you change it in the environment file, not in the compose file.

Several services publish ports on the host with a loopback default. MariaDB maps to "${SQL_PORT:-127.0.0.1:13306}:3306" and Redis maps to "${REDIS_PORT:-127.0.0.1:7654}:6379". The default binds those to 127.0.0.1 only, so the database and the cache are not exposed to the internet unless you deliberately change the variable. That is a sensible default, and it is also a default people override without thinking when they want to connect a tool from another machine. The compose file is truncated in what is available here, so the web, SMTP, IMAP and filtering services are not visible in this excerpt; the topics list on the repository names Postfix, Dovecot, Rspamd, ClamAV, SOGo and olefy, which is the component set the stack is built from.

Installing mailcow: dockerized on Ubuntu and getting to first login

The README does not carry installation steps. It states plainly: "Please see the official documentation for installation and support instructions." So the authoritative sequence lives at the documentation site the README links, and the repository gives you the two scripts that drive setup and maintenance, generate_config.sh and update.sh. What follows is the shape of the workflow those files imply, not a substitute for the documentation.

Start by cloning the repository onto the host that will run the stack. The default branch is master.

bash
git clone https://github.com/mailcow/mailcow-dockerized
cd mailcow-dockerized

The configuration generator is what writes the environment file the compose file reads. It prompts for the hostname and derives the rest.

bash
./generate_config.sh

After that, the stack comes up through Compose. Expect the first run to take a while: images have to be pulled and MariaDB has to initialize its data directory.

bash
docker compose pull
docker compose up -d

There is an .env file at the repository root, and that is where values such as TZ, IPV4_NETWORK, DBROOT, DBNAME, DBUSER, DBPASS, REDISPASS and the SQL_PORT and REDIS_PORT overrides live. Read it before you start the stack rather than after. Once the services report healthy, the web UI is where you log in and create the first mailbox; the README itself does not document the login path, so take the URL and credentials from the documentation rather than from here.

Where mailcow: dockerized fails you

The hardest constraint is not in the compose file. A mail server that cannot reach the outside world on port 25 is not a mail server. Many hosting providers and most residential connections block outbound 25 by default, and no amount of container configuration fixes that. Confirm the port is open before you invest a weekend in this.

Deliverability is the second wall. Running the stack does not make your mail trusted. You need a PTR record for the host, and SPF, DKIM and DMARC for the sending domain. The repository does not automate that for you, and the documentation is where the DKIM material lives. A perfectly healthy mailcow installation whose DNS is wrong will land in spam, and the failure looks identical to a broken filter chain.

The stack is also a lot of moving parts to own. The compose excerpt here alone shows Unbound, MariaDB and Redis as separate services with their own volumes, configuration mounts and startup ordering. When something breaks, the question is which of them broke, and the answer is usually in container logs rather than in the web UI. The repository ships helper-scripts and a create_cold_standby.sh at the top level, which tells you the project expects operators to think about backup and standby explicitly rather than assuming the stack is disposable.

Finally, the README does not document rollback, and it does not document backup or restore procedure. If you need a documented, tested rollback path before you upgrade a production mail system, that is not in the repository root material; go to the documentation and confirm it exists before you rely on it.

mailcow: dockerized compared with Docker Mailserver

The obvious alternative in the same space is Docker Mailserver, and the difference is scope rather than quality. Docker Mailserver is a single container image that you configure through environment variables; the mail services live together inside it, and you supply the surrounding pieces you want. mailcow: dockerized is a multi-service Compose project with its own database, cache, resolver, web UI and groupware layer, and the configuration is spread across an environment file and mounted configuration directories under ./data/conf/.

That reframes the choice. If you want to understand every process on the box and you are comfortable writing your own configuration, the single-image approach gives you fewer places for a setting to hide. If you want a web interface for creating mailboxes, a filter chain that is already wired to a database, and an upgrade path maintained by a company, the Compose project is the one that saves you the assembly work. The trade is that you now operate MariaDB, Redis and Unbound as part of your mail server, and their failure modes become your failure modes.

Neither approach removes the DNS work. Both require you to own PTR, SPF, DKIM and DMARC, and both require port 25. The comparison is about how much of the internal wiring you want to build yourself.

Upgrades, support contracts and the GPL-3.0 boundary

Upgrades run through update.sh at the repository root. The release history shows why the cadence matters: the 2026-07 line shipped in two revisions, 2026-07a and then 2026-07b, and the 2026-09 release bundles Unbound 1.26.1, SOGo 5.12.11 and Redis 7.4.11. Component versions move, and the compose file pins them by tag, so an upgrade is a change to the images your stack runs on. The last push to the repository was on 2026-09-21.

That cadence is the real maintenance cost. You are not maintaining mailcow; you are maintaining a host that runs it, and you are expected to apply releases as they land. If you cannot commit to reading release notes and running update.sh on a schedule, the stack will drift, and mail servers do not age gracefully when their spam filter or TLS stack falls behind.

The GPL-3.0 licence applies to mailcow itself, and the README is explicit that the project bundles other open-source software whose licences you should review before use. If you plan to redistribute a modified stack or embed it in a product, read the licence and the bundled components' licences yourself; this is a description of what the repository states, not legal advice. Separately, the README offers a support contract and a SAL through Servercow for operators who want a commercial relationship rather than community support. A critical security issue, per the README, should be mailed to info at servercow.de rather than filed publicly.

Editorial conclusion

Adopt mailcow: dockerized if you control a dedicated host, the DNS records for the domain, and inbound port 25, and you are willing to keep the Compose stack current with update.sh. Do not adopt it if you need mail without an always-on machine, if your provider blocks port 25, or if you want a single binary you can reason about end to end. Before you commit, verify that your provider allows outbound port 25 and that you can set PTR, SPF, DKIM and DMARC for the sending domain, then read the compose file's port bindings to confirm nothing you need is already in use.

Frequently asked questions

What is mailcow: dockerized used for?

It is used to run a complete mail server as a Docker Compose project, covering SMTP, IMAP, spam filtering, virus scanning, a database, a cache, a resolver and a groupware layer. The repository topics name Postfix, Dovecot, Rspamd, ClamAV and SOGo as the components involved.

Is mailcow: dockerized free to use?

The README states that any part of mailcow itself is released under GNU General Public License, Version 3. It also notes that mailcow makes use of various open-source software and that you should confirm you agree with their licences before using mailcow. A paid support contract and a SAL are offered separately through Servercow.

How do I install mailcow: dockerized?

The README does not list install steps; it directs you to the official documentation for installation and support instructions. The repository provides generate_config.sh to write the environment configuration and update.sh for upgrades, with the stack started through Docker Compose.

What are the key differences between Docker Mailserver and mailcow: dockerized?

Docker Mailserver is a single container configured through environment variables, while mailcow: dockerized is a multi-service Compose project with its own MariaDB, Redis, Unbound, web UI and groupware layer. mailcow spreads configuration across an environment file and mounted directories under ./data/conf/, so you also operate the database and cache as part of the mail server.

What is mailcow: dockerized?

It is the Docker Compose packaging of mailcow, described in the README as dockerized and made up of services such as unbound-mailcow, mysql-mailcow and redis-mailcow on a shared mailcow-network. The project is managed by The Infrastructure Company GmbH and the default branch is master.

Official sources

  1. License: GPL-3.0
  2. mailcow/mailcow-dockerized on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/mailcow-mailcow-dockerized.svg)](https://hysenlabs.com/projects/mailcow-mailcow-dockerized)