Skip to main content

Building an Image

Last updated July 2025

Building the Momentum container

Use a Dockerfile to build a Momentum container image.

NOTE: Momentum requires a valid license and working configuration to run. You can either include them into your container image or attach them later to the container at runtime (like in the example below, where they will be found in the mounted /opt/msys/ecelerity/etc/ tree).

Example:

FROM rockylinux:9 

# Install dependencies and utilities
RUN dnf update -y && \
    dnf install -y bzip2 epel-release iproute iputils net-tools openssl perl procps-ng sudo unbound && \
    dnf clean all && rm -rf /var/cache/dnf

# Copy and unpack the bundle into the container
ARG version=5.0.0.xxxxx
ADD momentum-mta-bundle-${version}.rhel9.x86_64.tar.gz /var/tmp/

# Install as per the Momentum Installation Guide
RUN cd /var/tmp/momentum-mta-${version} && \
    ./setrepodir && \
    dnf install -y --config momentum.repo --enablerepo=momentum msys-role-mta msys-ecelerity-mobility msys-ecelerity-engagement-proxy && \
    dnf clean all && rm -rf /var/cache/dnf && \
    rm -rf /var/tmp/momentum-mta-bundle-${version}.rhel9.x86_64.tar.gz momentum-mta-${version}

# Setup initial configuration as per the same Momentum Installation Guide
RUN sudo -u ecuser mkdir -p /opt/msys/ecelerity/etc/conf/default && \
    cd /opt/msys/ecelerity/etc/sample-configs/default && \
    sudo -u ecuser cp ecelerity.conf ecelerity-cluster.conf common.conf /opt/msys/ecelerity/etc/conf/default

# Environment variables for the gimli (heartbeat) monitor
ENV GIMLI_QUIET=1 \
    GIMLI_DETACH=0 \
    GIMLI_PID_FILE=/var/run/ecelerity.monitor.pid \
    GIMLI_TRACE_DIR=/var/log/ecelerity/traces

# Paths that could be (bind-)mounted
VOLUME ["/opt/msys/ecelerity/etc/conf/default", "/var/log/ecelerity", "/var/spool/ecelerity"]

# Ports that could be exposed
EXPOSE 25 2025

# Start the MTA service in the foreground inside the container
CMD ["/opt/msys/gimli/bin/monitor", "/opt/msys/ecelerity/sbin/run.ecelerity"]

To build the Docker image from the above Dockerfile:

  1. Copy the Momentum MTA bundle to the same directory as the Dockerfile.
  2. Run the following command in that directory:
docker build --tag momentum-mta:$VERSION --build-arg version=$VERSION .

where $VERSION is the version of the Momentum MTA bundle you are using (e.g., 5.0.0.12345).

Persistence of data

By default, all files in a container do NOT persist when the container exits. On the other hand, Momentum stores state data (e.g. spooled messages) in the filesystem, and a restart of the service would take it back from the saved state. Momentum also generates some files for post-processing, such as logs and traces.

To ensure that these files persist across container restarts, you should use bind mounts to persist the following (but not limited to) directories in the container:

  • /var/spool/ecelerity: directory that keeps the spool files for emails not yet delivered.
  • /var/log/ecelerity: directory that stores the logs and traces generated by Momentum.

Optionally, you can also mount the configuration directory:

  • /opt/msys/ecelerity/etc/conf/default: directory that contains the configuration files for Momentum, such as ecelerity.conf.

Exposing listeners

Momentum listens on several ports for different purposes. When running in a container, you can expose these ports to the host system using Docker's port mapping feature. For a more comprehensive explanation of that, see Docker's documentation.

Bridge mode

By default, Docker runs containers in "bridge" mode, which means that the container has its own network namespace and can communicate with the host through a virtual bridge. The host addresses aren't visible inside the container, and you must use port mapping to expose the necessary ports for traffic sent to the host to reach Momentum.

To expose the ports, you use the -p option when running the container.

Host mode

Alternatively, you can run the container in "host" mode, which makes the host interfaces transparent to the container, i.e., allows the container to share the host's network stack. In this case, you do not need to map ports, as the container will listen on the same ports as the host.

Was this page helpful?