Skip to content

Commit

Permalink
Docker setup: add MTA container
Browse files Browse the repository at this point in the history
It can run either Mailpit for local mail delivery (intended for
development environments) or Postfix for delivery to a remote
mail server (intended for acceptance test and production environments).
  • Loading branch information
stsnel committed Jan 16, 2025
1 parent ee68517 commit 747b903
Show file tree
Hide file tree
Showing 15 changed files with 414 additions and 4 deletions.
47 changes: 47 additions & 0 deletions .github/workflows/build-push-image-mta.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
name: "Build EPOS-MSL MTA image and push it to registry"

on:
push:
branches:
- 'development'
- 'dev-update-docker'
paths:
- '.github/workflows/build-push-image-mta.yml'
- 'docker/images/mta/**'

jobs:
push-image:
if: github.repository == 'utrechtuniversity/epos-msl'
runs-on: ubuntu-22.04
permissions:
contents: read
packages: write

steps:
- name: Extract branch name
shell: bash
run: echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT
id: extract_branch

- name: Check out EPOS-MSL catalog repository
uses: actions/checkout@v4
with:
path: epos-msl
repository: UtrechtUniversity/epos-msl
ref: ${{ steps.extract_branch.outputs.branch }}

- name: Authenticate to the container registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: epos-msl/docker/images/mta
file: epos-msl/docker/images/mta/Dockerfile
push: true
tags: ghcr.io/utrechtuniversity/epos-msl-cat-mta:latest
12 changes: 12 additions & 0 deletions docker/.env
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,15 @@ MYSQL_ROOT_PASSWORD=testtest
MSLAPI_DB_PASSWORD=testtest

FAST_API_TOKEN=notokenspecified

# MTA role can be either "mailpit" or "postfix"
MTA_ROLE=mailpit

POSTFIX_RELAYHOST_FQDN=notspecified
POSTFIX_RELAYHOST_PORT=25
POSTFIX_RELAYHOST_USERNAME=changeme
POSTFIX_RELAYHOST_PASSWORD=changeme
POSTFIX_RELAYHOST_AUTH_ENABLED=yes
POSTFIX_RELAYHOST_TLS_ENABLED=yes
POSTFIX_MYHOSTNAME=changeme
POSTFIX_ORIGIN=changeme
2 changes: 1 addition & 1 deletion docker/build-local-images.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ set -e

cd images

for image in ckan nginx solr msl-api
for image in ckan nginx solr msl-api mta
do cd "$image"
echo "Building image $image ..."
./build.sh
Expand Down
19 changes: 19 additions & 0 deletions docker/docker-compose-separate-msl-api.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,11 @@ services:
environment:
- EPOS_MSL_HOST=${EPOS_MSL_HOST}
- EPOS_MSL_HOST_PORT=${EPOS_MSL_HOST_PORT}
- MTA_ROLE=${MTA_ROLE}
ports:
- "${EPOS_MSL_HOST_IP}:${EPOS_MSL_HOST_PORT}:443"
sysctls:
net.ipv4.ip_unprivileged_port_start: 0
volumes:
- nginx_config:/etc/nginx/conf.d
- nginx_certificates:/etc/certificates
Expand Down Expand Up @@ -115,3 +118,19 @@ services:
redis:
container_name: redis
image: redis:6.2

mta:
container_name: mta
image: ghcr.io/utrechtuniversity/epos-msl-cat-mta:latest
environment:
- MTA_ROLE=${MTA_ROLE}
- POSTFIX_RELAYHOST_FQDN=${POSTFIX_RELAYHOST_FQDN}
- POSTFIX_RELAYHOST_PORT=${POSTFIX_RELAYHOST_PORT}
- POSTFIX_RELAYHOST_USERNAME=${POSTFIX_RELAYHOST_USERNAME}
- POSTFIX_RELAYHOST_PASSWORD=${POSTFIX_RELAYHOST_PASSWORD}
- POSTFIX_RELAYHOST_AUTH_ENABLED=${POSTFIX_RELAYHOST_AUTH_ENABLED}
- POSTFIX_RELAYHOST_TLS_ENABLED=${POSTFIX_RELAYHOST_TLS_ENABLED}
- POSTFIX_MYHOSTNAME=${POSTFIX_MYHOSTNAME}
- POSTFIX_ORIGIN=${POSTFIX_ORIGIN}
sysctls:
net.ipv4.ip_unprivileged_port_start: 0
19 changes: 19 additions & 0 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,11 @@ services:
environment:
- EPOS_MSL_HOST=${EPOS_MSL_HOST}
- EPOS_MSL_HOST_PORT=${EPOS_MSL_HOST_PORT}
- MTA_ROLE=${MTA_ROLE}
ports:
- "${EPOS_MSL_HOST_IP}:${EPOS_MSL_HOST_PORT}:443"
sysctls:
net.ipv4.ip_unprivileged_port_start: 0
volumes:
- nginx_config:/etc/nginx/conf.d
- nginx_certificates:/etc/certificates
Expand Down Expand Up @@ -103,3 +106,19 @@ services:
redis:
container_name: redis
image: redis:6.2

mta:
container_name: mta
image: ghcr.io/utrechtuniversity/epos-msl-cat-mta:latest
environment:
- MTA_ROLE=${MTA_ROLE}
- POSTFIX_RELAYHOST_FQDN=${POSTFIX_RELAYHOST_FQDN}
- POSTFIX_RELAYHOST_PORT=${POSTFIX_RELAYHOST_PORT}
- POSTFIX_RELAYHOST_USERNAME=${POSTFIX_RELAYHOST_USERNAME}
- POSTFIX_RELAYHOST_PASSWORD=${POSTFIX_RELAYHOST_PASSWORD}
- POSTFIX_RELAYHOST_AUTH_ENABLED=${POSTFIX_RELAYHOST_AUTH_ENABLED}
- POSTFIX_RELAYHOST_TLS_ENABLED=${POSTFIX_RELAYHOST_TLS_ENABLED}
- POSTFIX_MYHOSTNAME=${POSTFIX_MYHOSTNAME}
- POSTFIX_ORIGIN=${POSTFIX_ORIGIN}
sysctls:
net.ipv4.ip_unprivileged_port_start: 0
48 changes: 48 additions & 0 deletions docker/images/mta/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# This is an image for running the MSL-API application, that is part of the EPOS-MSL catalog

# See CKAN docs on installation from Docker Compose on usage
FROM ubuntu:noble
MAINTAINER Yoda team

ENV MAILPIT_VERSION=v1.21.8

# Need bash to get nvm/npm to work with default init files
SHELL ["/bin/bash", "-o", "pipefail", "-c"]

# Set timezone
ENV TZ=UTC
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# Setting the locale
ENV LC_ALL=en_US.UTF-8
RUN apt-get update
RUN apt-get install --no-install-recommends -y locales
RUN sed -i "/$LC_ALL/s/^# //g" /etc/locale.gen
RUN dpkg-reconfigure --frontend=noninteractive locales
RUN update-locale LANG=${LC_ALL}

# Install common dependencies
RUN apt -y install curl golang git && \
curl https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash && \
source /root/.nvm/nvm.sh && \
nvm install v18

### Install Mailpit
RUN cd / && \
source /root/.nvm/nvm.sh && \
git clone -c advice.detachedHead=false https://github.com/axllent/mailpit.git && \
cd mailpit && \
git checkout ${MAILPIT_VERSION} && \
npm install && \
npm run package && \
CGO_ENABLED=0 go build -ldflags "-s -w -X github.com/axllent/mailpit/config.Version=${VERSION}" -o /mailpit.bin

### Install Postfix
RUN apt -y install postfix sasl2-bin mailutils
ADD main.cf /etc/postfix/main.cf
ADD master.cf /etc/postfix/master.cf

# Run
ADD mta-entrypoint.sh /mta-entrypoint.sh
RUN chmod +x /mta-entrypoint.sh
CMD ["/mta-entrypoint.sh"]
2 changes: 2 additions & 0 deletions docker/images/mta/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/sh
docker build -t ghcr.io/utrechtuniversity/epos-msl-cat-mta:latest . $*
54 changes: 54 additions & 0 deletions docker/images/mta/main.cf
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# See /usr/share/postfix/main.cf.dist for a commented, more complete version


# Debian specific: Specifying a file name will cause the first
# line of that file to be used as the name. The Debian default
# is /etc/mailname.
myorigin = $mydomain

smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
biff = no

# appending .domain is the MUA's job.
append_dot_mydomain = no

# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h

readme_directory = no

# See http://www.postfix.org/COMPATIBILITY_README.html -- default to 3.6 on
# fresh installs.
compatibility_level = 3.6



# TLS parameters
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_tls_security_level=may

smtp_tls_CApath=/etc/ssl/certs
smtp_tls_security_level=may
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

smtp_use_tls = INSERT_POSTFIX_RELAYHOST_TLS_ENABLED
smtp_sasl_auth_enable = INSERT_POSTFIX_RELAYHOST_AUTH_ENABLED
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = INSERT_POSTFIX_SMTP_SASL_SECURITY_OPTIONS
smtp_sasl_tls_security_options = INSERT_POSTFIX_SMTP_SASL_TLS_SECURITY_OPTIONS

smtpd_data_restrictions = reject_unauth_pipelining
smtpd_discard_ehlo_keywords = chunking, silent-discard

smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
myhostname = INSERT_POSTFIX_MYHOSTNAME
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mydestination =
relayhost = [INSERT_POSTFIX_RELAYHOST_FQDN]:INSERT_POSTFIX_RELAYHOST_PORT
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all
140 changes: 140 additions & 0 deletions docker/images/mta/master.cf
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#
# Postfix master process configuration file. For details on the format
# of the file, see the master(5) manual page (command: "man 5 master" or
# on-line: http://www.postfix.org/master.5.html).
#
# Do not forget to execute "postfix reload" after editing this file.
#
# ==========================================================================
# service type private unpriv chroot wakeup maxproc command + args
# (yes) (yes) (no) (never) (100)
# ==========================================================================
smtp inet n - y - - smtpd
#smtp inet n - y - 1 postscreen
#smtpd pass - - y - - smtpd
#dnsblog unix - - y - 0 dnsblog
#tlsproxy unix - - y - 0 tlsproxy
# Choose one: enable submission for loopback clients only, or for any client.
#127.0.0.1:submission inet n - y - - smtpd
#submission inet n - y - - smtpd
# -o syslog_name=postfix/submission
# -o smtpd_tls_security_level=encrypt
# -o smtpd_sasl_auth_enable=yes
# -o smtpd_tls_auth_only=yes
# -o local_header_rewrite_clients=static:all
# -o smtpd_reject_unlisted_recipient=no
# Instead of specifying complex smtpd_<xxx>_restrictions here,
# specify "smtpd_<xxx>_restrictions=$mua_<xxx>_restrictions"
# here, and specify mua_<xxx>_restrictions in main.cf (where
# "<xxx>" is "client", "helo", "sender", "relay", or "recipient").
# -o smtpd_client_restrictions=
# -o smtpd_helo_restrictions=
# -o smtpd_sender_restrictions=
# -o smtpd_relay_restrictions=
# -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
# -o milter_macro_daemon_name=ORIGINATING
# Choose one: enable submissions for loopback clients only, or for any client.
#127.0.0.1:submissions inet n - y - - smtpd
#submissions inet n - y - - smtpd
# -o syslog_name=postfix/submissions
# -o smtpd_tls_wrappermode=yes
# -o smtpd_sasl_auth_enable=yes
# -o local_header_rewrite_clients=static:all
# -o smtpd_reject_unlisted_recipient=no
# Instead of specifying complex smtpd_<xxx>_restrictions here,
# specify "smtpd_<xxx>_restrictions=$mua_<xxx>_restrictions"
# here, and specify mua_<xxx>_restrictions in main.cf (where
# "<xxx>" is "client", "helo", "sender", "relay", or "recipient").
# -o smtpd_client_restrictions=
# -o smtpd_helo_restrictions=
# -o smtpd_sender_restrictions=
# -o smtpd_relay_restrictions=
# -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
# -o milter_macro_daemon_name=ORIGINATING
#628 inet n - y - - qmqpd
pickup unix n - y 60 1 pickup
cleanup unix n - y - 0 cleanup
qmgr unix n - n 300 1 qmgr
#qmgr unix n - n 300 1 oqmgr
tlsmgr unix - - y 1000? 1 tlsmgr
rewrite unix - - y - - trivial-rewrite
bounce unix - - n - 0 discard
defer unix - - y - 0 bounce
trace unix - - y - 0 bounce
verify unix - - y - 1 verify
flush unix n - y 1000? 0 flush
proxymap unix - - n - - proxymap
proxywrite unix - - n - 1 proxymap
smtp unix - - y - - smtp
relay unix - - y - - smtp
-o syslog_name=postfix/$service_name
# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5
showq unix n - y - - showq
error unix - - y - - error
retry unix - - y - - error
discard unix - - y - - discard
local unix - n n - - local
virtual unix - n n - - virtual
lmtp unix - - y - - lmtp
anvil unix - - y - 1 anvil
scache unix - - y - 1 scache
postlog unix-dgram n - n - 1 postlogd
#
# ====================================================================
# Interfaces to non-Postfix software. Be sure to examine the manual
# pages of the non-Postfix software to find out what options it wants.
#
# Many of the following services use the Postfix pipe(8) delivery
# agent. See the pipe(8) man page for information about ${recipient}
# and other message envelope options.
# ====================================================================
#
# maildrop. See the Postfix MAILDROP_README file for details.
# Also specify in main.cf: maildrop_destination_recipient_limit=1
#
#maildrop unix - n n - - pipe
# flags=DRXhu user=vmail argv=/usr/bin/maildrop -d ${recipient}
#
# ====================================================================
#
# Recent Cyrus versions can use the existing "lmtp" master.cf entry.
#
# Specify in cyrus.conf:
# lmtp cmd="lmtpd -a" listen="localhost:lmtp" proto=tcp4
#
# Specify in main.cf one or more of the following:
# mailbox_transport = lmtp:inet:localhost
# virtual_transport = lmtp:inet:localhost
#
# ====================================================================
#
# Cyrus 2.1.5 (Amos Gouaux)
# Also specify in main.cf: cyrus_destination_recipient_limit=1
#
#cyrus unix - n n - - pipe
# flags=DRX user=cyrus argv=/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user}
#
# ====================================================================
#
# Old example of delivery via Cyrus.
#
#old-cyrus unix - n n - - pipe
# flags=R user=cyrus argv=/cyrus/bin/deliver -e -m ${extension} ${user}
#
# ====================================================================
#
# See the Postfix UUCP_README file for configuration details.
#
uucp unix - n n - - pipe
flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
#
# Other external delivery methods.
#
#ifmail unix - n n - - pipe
# flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient)
#bsmtp unix - n n - - pipe
# flags=Fq. user=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $recipient
#scalemail-backend unix - n n - 2 pipe
# flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store ${nexthop} ${user} ${extension}
#mailman unix - n n - - pipe
# flags=FRX user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py ${nexthop} ${user}
Loading

0 comments on commit 747b903

Please sign in to comment.