summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMalfurious <m@lfurio.us>2024-06-08 14:55:47 -0400
committerMalfurious <m@lfurio.us>2024-06-09 14:16:42 -0400
commitf70fb0720d2a643905ba8263253b16b973f6bc36 (patch)
tree27c057db3858b8d4f0c3c730dab905fd4b1efb0e
parent26dab860bd733e4f110fc837e1f3d8c682248502 (diff)
downloadmailnode-f70fb0720d2a643905ba8263253b16b973f6bc36.tar.gz
mailnode-f70fb0720d2a643905ba8263253b16b973f6bc36.zip
Create docker image and services
As hinted by the previous commit, the mailnode system is built in a single docker image for simplicity. Defining multiple Dockerfiles would lead to many redundant tasks and be harder to maintain. So a common image for all services is built. However, the compose file spawns a unique container for each service, and communication occurs via the filesystem, through volumes. Note also that some fields in docker-compose.yml are required to be set by the end-user. The mail system is oriented around virtual users, so that nobody needs their own unix system account. However, best security practice is to create a dedicated user to own the mails - this user shouldn't be used for any other purpose. For this, the Dockerfile creates the user "vmailbox". The reason for declaring port exposure for TCP/80 is to enable automated TLS encryption with nginx-proxy-acme. This port is not actually opened by the compose file. Signed-off-by: Malfurious <m@lfurio.us>
-rw-r--r--Dockerfile42
-rw-r--r--docker-compose.yml57
2 files changed, 99 insertions, 0 deletions
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..7eafaf1
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,42 @@
+FROM debian
+
+ARG HOSTNAME
+ARG VIRTUAL_DOMAINS
+ENV DEBIAN_FRONTEND=noninteractive
+
+# Create system users with fixed, well-known UID/GIDs
+RUN useradd \
+ --uid 2000 --system \
+ --shell /usr/sbin/nologin \
+ --home-dir /var/mail/vhost \
+ --skel /dev/null --create-home \
+ vmailbox
+
+RUN useradd \
+ --uid 2001 --system \
+ --shell /usr/sbin/nologin \
+ --home-dir /var/spool/postfix \
+ postfix
+
+# Install packages
+RUN apt update \
+ && apt full-upgrade --yes \
+ && apt install --yes \
+ dovecot-core \
+ dovecot-imapd \
+ postfix \
+ && apt clean
+
+# Install files
+COPY dovecot /etc/dovecot/
+COPY postfix /etc/postfix/
+COPY userconfig /etc/userconfig/
+
+RUN find /etc/dovecot /etc/postfix -type f | xargs sed -i \
+ "s/ENV_HOSTNAME/${HOSTNAME}/g; s/ENV_VIRTUAL_DOMAINS/${VIRTUAL_DOMAINS}/g"
+
+EXPOSE 25
+EXPOSE 80
+EXPOSE 465
+EXPOSE 993
+# CMD set by docker-compose.yml
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..a636181
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,57 @@
+services:
+
+ postfix:
+ image: "mailnode"
+ pull_policy: "never"
+ build:
+ context: "."
+ args:
+ # CONFIGURE ME!
+ # The FQDN this mail server identifies itself as
+ HOSTNAME: "YOUR-DOMAIN.example"
+ # All domain names this server accepts mail for (space separated)
+ VIRTUAL_DOMAINS: "YOUR-DOMAIN.example"
+
+ restart: "always"
+ volumes:
+ - "certs:/etc/certs"
+ - "mail:/var/mail"
+ - "postfix:/var/spool/postfix"
+ ports:
+ - "25:25"
+ - "465:465"
+ command: ["/etc/postfix/entrypoint.sh"]
+
+ dovecot:
+ image: "mailnode"
+ pull_policy: "never"
+
+ restart: "always"
+ volumes:
+ - "certs:/etc/certs"
+ - "mail:/var/mail"
+ - "postfix:/var/spool/postfix"
+ ports:
+ - "993:993"
+ networks:
+ - "nginx-proxy-network"
+ environment:
+ # CONFIGURE ME!
+ # We expect to utilize nginxproxy (proxy-docker) to create our TLS
+ # certificates. This also allows other web services to operate on the
+ # same host. Set the domain (common name) to generate certs for below
+ # (typically the same value used for HOSTNAME above).
+ VIRTUAL_HOST: "YOUR-DOMAIN.example"
+ LETSENCRYPT_HOST: "YOUR-DOMAIN.example"
+ command: ["/usr/sbin/dovecot", "-F"]
+
+volumes:
+ certs:
+ external: true
+ name: "proxy-docker_certs"
+ mail:
+ postfix:
+
+networks:
+ nginx-proxy-network:
+ external: true