Closed jgillich closed 7 years ago
There are multiple reasons for this. Some are opinions more than technical arguments, but developping Mailu as a set of images was the result of many experiments.
When using a single image, modularity is less of an option. For instance, if you want to be able to switch between Webmails, you basically have two solutions left: intalling/uninstalling packages, which completely defeats the purpose of having self-contained Docker images, or embedding all options in a single (bloated) container.
On the contrary, multiple images and multiple containers allow for more flexible architectures, some might want to disable the reverse proxy, others might want switch between antivirus, etc.
There are arguments for both sides regarding updates. A single container is easier to upgrade: simply pull the latest image. On the opposite, you cannot upgrade and recreate a single container while maintaining service for the rest. Also, when using multiple containers, upgrades tend to be smaller (this is a false argument since we rebuild all containers everytime for now, but might become significant in the future).
From a security or architectural point of view, having multiple containers running separate services, each with access to the minimal dataset is a tremendous improvement in terms of security and incident management.
If a vulnerability is fonud in Roundcube for instance:
Of course, the same kind of behaviour could be accomplished with user permissions, but separate containers make it a lot easier to design and audit.
Again about modularity, but from a different point of view. A great project design should properly separate concerns and use standard communication between components. Having a single container might lead developpers to easy solutions that involve non-standard communications.
For instance, I would like to avoid Postfix calling directly dovecot-lda
, which is great but would prevent anyone from using another LDA. Same goes for antivirus, antispam, etc.
There are still some aspects that I dislike about the way things are organized, but at least separate containers constrain developers enough to prevent the most obvious kinds of cross-cutting and modularity issues.
Logging is a crucial component of any application or system. If you go for a single container, producing logs on standard output is not an option: logs from various applications would be mixed and separating them on your log management system would become a burden.
So you would go for file-based logging. If you are running Mailu on a single host with a local file-based log management system, this might be ok, but otherwise, you would probably prefer to leverage the power of Docker logging abstractions. For instance, I log everything to Splunk and ELK, where having separate containers makes it way easier to segregate messages and parse them properly.
Regarding your proposition of providing a separate all-in-one image, I see a couple shortcomings that would probably require some thinking and some work:
CMD
entries in a single DockerfileModularity: With a all in one image, you could still dynamically enable and disable service via environment variables. Everything would have to be in a single container that is true, but dependencies are shared so the difference wouldn't be that much, especially since there are currently multiple base images in use.
Updates: That is a good point, with everything in a single container updating would mean everything would go down. But email was built with that in mind, so it shouldn't matter to anyone except those with lots and lots of users.
Isolation: 100% agree, but again, that's mostly a concern for larger installs, for my personal use a single container is good enough.
Logs: Good point, for log management apps it's a lot easier to pull the logs out of the built in logging.
I think the argument is mostly between people like me that run a mail server for themselves and have less than 10 users, and people that run mail for a huge company with lots of users.
Multiple CMD
entries would of course not work, something like supervisord or s6 would handle launching the individual apps.
Modularity: agreed about the multiple base images that needs to be addressed.
Updates: agreed as well, it would not be too much of an issue for very small setups.
Isolation: I believe that's a concern for anyone, but sure it is less of an issue if security or stability is not your priority.
If you find a proper way to reliably automate the build of a single image (without duplicating code of course) with a very basic setup and address the logging issue, I am not opposed to offer this as a separate solution for tiny setups.
I still prefer spending my time optimizing the current setup in terms of disk space and memory, which are the main concerns here.
FWIW, part of my motivation for this is that I've moved everything to Hyper, which currently only supports volumes and not host mounts, and only lets you assign an IP address to a single container. These are of course Hyper limitations, but for the reasons I mentioned a single image is preferable to me anyway.
I think a good first step would be to move all images to alpine, that benefits both use cases. No need to rush anything, I'm not fully convinced of this idea either.
I have to say, this project looks awesome! However, one thing I've always liked about poste.io is the fact that it runs everything in a single container, although some people surely disagree.
But lets say all images would be based on the same Alpine image and would use paths that didn't conflict, we could simply
cat
all of them to a single Dockerfile and use supervisord to launch the individual start scripts. That way it would be possible to provide both separated images and a all in one image for people that want it.Let me know what you think.