Mailgun Logger - Simple Persistence For Mailgun

Updated 11/12/2020: fixed docker-compose.yml

For every project we need email functionality for, be it transactional or inbound, we choose Mailgun as our service provider. Over the years we tried different services but found this one to serve our every need. They have excellent support, a pretty neat dashboard and decent logging. For the most part, it has everything we need - except for the occasional noisy senders on our shared IPs.

Data retention

There is only one small downside: data retention is expensive. We do not need it very often, but when we do encounter a bug or an email that seemingly didn’t arrive, three days just isn’t enough. Sometimes we just want to look back a week and see the chain of events linked to a specific email.

Mailgun Logger

To tackle this problem we decided to build a very simple Phoenix application that stores and archives events from Mailgun. Through their API, we regularly fetch all events from a Mailgun account in a MySQL db. This allows use to go back for weeks or months and search for activity by email, event type, subject or other parameters. The application can have multiple Mailgun domains/accounts linked across the US and EU API.

The application has very minimal styling and the following pages:

  • account admin page, to enter various accounts using the API keys that you can generate at Mailgun,
  • events listing page,
  • event detail page, with interlinking for message chains.

It also features a minimal search. We kept this dead easy by design since we have no intention to recreate the excellent interface Mailgun offers us. All we wanted was to be able to go back further and know wether an email got deliver or not.


You can run this locally or set it up very easily on a small VPS using the Docker image.

With the following docker-compose.yml:

version: "3"

    image: mysql
      - webnet
      - MYSQL_PASSWORD=logger
      - MYSQL_USER=logger
      - MYSQL_DATABASE=mailgun_logger
      - db_data:/var/lib/mysql

    image: jackjoe/mailgun_logger
      - db
    entrypoint: ["./wait-for", "db:3306", "--", "./"]
      - "5050:5050"
      - webnet
      - ML_DB_USER=logger
      - ML_DB_PASSWORD=logger
      - ML_DB_NAME=mailgun_logger
      - ML_DB_HOST=db

    external: false

  db_data: {}


$ docker-compose up


$ docker run -d -p 5050:5050 \
  -e "ML_DB_USER=username" \
  -e "ML_DB_PASSWORD=password" \
  -e "ML_DB_NAME=mailgun_logger" \
  -e "ML_DB_HOST=my_db_host" \
  --name mailgun_logger jackjoe/mailgun_logger

Then head over to


The full source code, instructions and a ready to use Docker image can be found in the source code and readme over at Github.

Please contribute!

Need help?

Need someone to set this up for your company? We can help your bussiness with custom software development and other services. Contact us and let’s talk about a plan of action!