Programster's Blog

Tutorials focusing on Linux, programming, and open-source

Deploy Mailtrain With Docker

This tutorial will show you how to deploy a minimal Mailtrain quickly and easily with the help of Docker-compose. This tutorial will deliberately not be deploying MongoDB, ZoneMTA, or Redis to keep things much simpler, and reduce our memory requirements.

Related Posts

Prerequisites

Steps

Copy and paste the following YAML file to a file called docker-compose.yml on your server.

version: "3.8"
services:
  mailtrain:
    image: mailtrain/mailtrain:v2.20210609.0
    ports:
    - 3000:3000
    - 3003:3003
    - 3004:3004
    restart: unless-stopped
    container_name: mailtrain
    volumes:
    - type: volume
      target: /app/server/files
      source: mailtrain-files
    environment:
    - ADMIN_PASSWORD=setAstrongAlphanumericPa55wordH3re
    - PORT_TRUSTED=3000
    - PORT_SANDBOX=3003
    - PORT_PUBLIC=3004
    - URL_BASE_TRUSTED=http://trusted.mailtrain.mydomain.com:3000
    - URL_BASE_SANDBOX=http://sandbox.mailtrain.mydomain.com:3003
    - URL_BASE_PUBLIC=http://public.mailtrain.mydomain.com:3004
    - WWW_PROXY=0
    - WITH_REDIS=0
    - WWW_SECRET=xxxxxxChangeThisxxxxxxxx
    - WITH_ZONE_MTA=0
    - MYSQL_HOST=db
    - MYSQL_DATABASE=mailtrain
    - MYSQL_USER=mailtrain
    - MYSQL_PASSWORD=MysqlPasswordGoesHere
    depends_on:
    - db
  db:
    image: mariadb:10.6
    restart: unless-stopped
    container_name: db
    volumes:
    - type: volume
      target: /var/lib/mysql
      source: db-data
    environment:
    - MARIADB_RANDOM_ROOT_PASSWORD=1
    - MARIADB_DATABASE=mailtrain
    - MARIADB_USER=mailtrain
    - MARIADB_PASSWORD=MysqlPasswordGoesHere
volumes:
  mailtrain-files:
    driver: local
  db-data:
    driver: local

Be sure to change the value for WWW_SECRET, MysqlPasswordGoesHere, and setAstrongAlphanumericPa55wordH3re to something else. Also be sure to change mydomain.com to whatever your domain is.

Ports Remapping And Proxy

I believe it's a much better setup if one sets up an Nginx reverse proxy to listen on ports 80/443 for the three different domains, and redirect the traffic to the server on ports 3000, 3003, and 3004. This way one does not need to remember to specify the port in the URL when accessing the services in the browser.
If you do this, then you would need to take the ports out of the URLs, and also set WWW_PROXY to 1 like so:

version: "3.8"
services:
  mailtrain:
    image: mailtrain/mailtrain:v2.20210609.0
    ports:
    - 3000:3000
    - 3003:3003
    - 3004:3004
    restart: unless-stopped
    container_name: mailtrain
    volumes:
    - type: volume
      target: /app/server/files
      source: mailtrain-files
    environment:
    - ADMIN_PASSWORD=setAstrongAlphanumericPa55wordH3re
    - PORT_TRUSTED=3000
    - PORT_SANDBOX=3003
    - PORT_PUBLIC=3004
    - URL_BASE_TRUSTED=http://trusted.mailtrain.mydomain.com
    - URL_BASE_SANDBOX=http://sandbox.mailtrain.mydomain.com
    - URL_BASE_PUBLIC=http://public.mailtrain.mydomain.com
    - WWW_PROXY=1
    - WITH_REDIS=0
    - WWW_SECRET=xxxxxxChangeThisxxxxxxxx
    - WITH_ZONE_MTA=0
    - MYSQL_HOST=db
    - MYSQL_DATABASE=mailtrain
    - MYSQL_USER=mailtrain
    - MYSQL_PASSWORD=MysqlPasswordGoesHere
    depends_on:
    - db
  db:
    image: mariadb:10.6
    restart: unless-stopped
    container_name: db
    volumes:
    - type: volume
      target: /var/lib/mysql
      source: db-data
    environment:
    - MARIADB_RANDOM_ROOT_PASSWORD=1
    - MARIADB_DATABASE=mailtrain
    - MARIADB_USER=mailtrain
    - MARIADB_PASSWORD=MysqlPasswordGoesHere
volumes:
  mailtrain-files:
    driver: local
  db-data:
    driver: local

Then, you would need to configure your proxy with a site configuration (/etc/nginx/sites-enabled/my-site-name) similar to below (changing the internal IP, SSL certificate path, and domain names accordingly)

server {
    listen 80;

    server_name trusted.mailtrain.mydomain.com;

    access_log  /var/log/nginx/access.log;

    location / {
        proxy_pass  http://192.168.0.7:3000/;
        include     /etc/nginx/proxy.conf;
    }
}

server {
    listen 443 default_server ssl;

    ssl on;

    server_name webrtc.programster.org;

    access_log  /var/log/nginx/access.log;

    ssl_certificate      ssl/trusted.mailtrain.mydomain.com/site.crt;
    ssl_certificate_key  ssl/trusted.mailtrain.mydomain.com/private.pem;

    ssl_protocols        SSLv3 TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers RC4:HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    keepalive_timeout    60;
    ssl_session_cache    shared:SSL:10m;
    ssl_session_timeout  10m;

    proxy_set_header Connection '';
    proxy_http_version 1.1;
    chunked_transfer_encoding off;
    proxy_buffering off;
    proxy_cache off;

    location / {
        proxy_pass      http://192.168.0.7:3000/;
        include         /etc/nginx/proxy.conf;
    }
}

Deploy!

Now all you need to do is run the following command:

docker-compose up -d

Wait a few seconds and your mailtrain server will be deployed. You should be able to log into it using the trusted URL, and using the following credentials:

  • admin
  • (password you set in ADMIN_PASSWORD of your docker-compose file.

Taking It Further

Important Note

There is a bug in mailtrain that if you do not set the ADMIN_PASSWORD environment variable, the the default admin password will reset back to test every time your container restarts. Also, you cannot work around this by deleting the default admin user within the system. It won't allow you to delete that user.

References

Last updated: 18th February 2024
First published: 16th August 2018

This blog is created by Stuart Page

I'm a freelance web developer and technology consultant based in Surrey, UK, with over 10 years experience in web development, DevOps, Linux Administration, and IT solutions.

Need support with your infrastructure or web services?

Get in touch