DevOps

Mailhog and Nodejs example

Hello. In this tutorial, we will implement a fake SMTP server with the help of Mailhog in a nodejs application. We will use Docker to install and run Mailhog as a container.

1. Introduction

Mailhog is an email testing that offers to test an email set up with the help of a fake SMTP server. It allows to send emails to any recipients and saves them for later viewing. It offers –

  • API support
  • Authentication
  • Download attachments
  • Email capture and storage
  • Failure testing
  • Lightweight and Portable
  • Realtime updates
  • Support for SMTP extended
  • Web ui

1.1 Setting up Node.js

To set up Node.js on windows you will need to download the installer from this link. Click on the installer (also include the NPM package manager) for your platform and run the installer to start with the Node.js setup wizard. Follow the wizard steps and click on Finish when it is done. If everything goes well you can navigate to the command prompt to verify if the installation was successful as shown in Fig. 1.

Fig. 1: Verifying node and npm installation

1.2 Setting up Docker

If someone needs to go through the Docker installation, please watch this video.

2. Mailhog and Nodejs example

To set up the application, we will need to navigate to a path where our project will reside and I will be using Visual Studio Code as my preferred IDE. Let a take a quick peek at the project structure.

Fig. 2: Project structure

2.1 Running mailhog on Docker

docker-compose is a tool for running the docker applications in multiple containers. To set up the mailhog I will be using this functionality. In the project’s root directory create a file named docker-compose.yml and paste the below code into it. You’re free to change the configuration as your needs.

docker-compose.yml

services:
  mailhog:
    container_name: docker_mailhog
    image: mailhog/mailhog:latest
    logging:
      driver: none # disable saving logs
    ports:
      - "1025:1025" # smtp server
      - "8025:8025" # web ui
version: "3"

Use the docker-compose -f /docker-compose.yml up -d command to download the mailhog image from the docker hub (if not present) and start it locally as a docker container. Remember to place the path_to_file with the original path where the YAML file is residing in your project. Once the command is executed successfully in the terminal window mailhog will expose the following endpoints –

  • SMTP interface exposed on port number 1025
  • Web interface and api exposed on port number 8025
  • Open the gui in the browser by typing localhost:8025 in the search bar

Other docker-compose commands (such as stopping or removing the container) can be downloaded from the Downloads section.

Fig: 3: Mailhog container on Docker

2.2 Setting up project dependencies

Navigate to the project directory and run npm init -y to create a package.json file. This file holds the metadata relevant to the project and is used for managing the project dependencies, script, version, etc. Replace the generated file with the code given below –

package.json

{
  "name": "mailhog",
  "version": "1.0.0",
  "description": "Safe email testing with mailhog",
  "main": "index.js",
  "scripts": {
    "dev": "nodemon index.js",
    "start": "node index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "safe email",
    "mailhog",
    "nodejs",
    "express"
  ],
  "author": "geek",
  "license": "MIT",
  "devDependencies": {
    "nodemon": "^2.0.16"
  },
  "dependencies": {
    "config": "^3.3.7",
    "express": "^4.18.1",
    "nodemailer": "^6.7.5"
  }
}

Once the file is replaced trigger the below npm command in the terminal window to download the different packages required for this tutorial.

Downloading dependencies

npm install

2.3 Setting up the config json

Create a json file inside the config folder responsible to hold the configuration-related details for the application. You are free to change the values as per your requirement.

config/default.json

{
  "mailhog": {
    "host": "localhost",
    "smtp_port": 1025
  },
  "app_port": 3005
}

2.4 Setting up implementation file

Create a file in the root directory responsible to handle the application startup, setting up the nodemailer module, defining application routes, and starting the application on the port number 3005.

  • GET Endpoint – /health is responsible give the application status
  • POST Endpoint – /send is responsible to send email as per the given request body

index.js

const express = require("express");
const nodemailer = require("nodemailer");
const config = require("config");

const app = express();

app.use(express.json({ extended: false }));

// config info
const transporter = nodemailer.createTransport({
  host: config.get("mailhog.host"),
  port: config.get("mailhog.smtp_port")
});

// define routes

// @route GET /health
// @desc  Get application health
app.get("/health", (req, res) => {
  res.status(200).json({
    status: "ok",
    message: "application is healthy"
  });
});

// @route POST /send
// @desc  Send email
app.post("/send", (req, res) => {
  // console.log(req.body);
  const { to, sub, body } = req.body;

  const obj = transporter.sendMail({
    from: "My company <localhost@mailhog.local>",
    to: to,
    subject: sub,
    text: body
  });

  if (!obj) {
    res.status(500).json({
      status: "internal server error",
      message: "error sending message"
    });
  }

  res.status(201).json({
    status: "create",
    message: "message sent"
  });
});

// driver code
const port = config.get("app_port");
app.listen(port, () => {
  console.log(`Service endpoint http://localhost:${port}`);
});

3. Run the Application

To run the application navigate to the project directory and enter the following command as shown below in the terminal.

Run command

$ npm run dev

If everything goes well the application will be started successfully at the service endpoint – http://localhost:3005.

4. Demo

Open the postman or any tool of your choice and hit the /send endpoint with a request body as shown below.

Request

(http post) - Send email 
http://localhost:3005/send

request body -
{
    "to": "test@example.com",
    "sub": "Test mail",
    "body": "Hi. I am test email."
}

If everything goes well a json response with a status code of 201 will be returned. You validate the sent email open the mailhog web ui and check. The sent emails will be shown below.

Fig: 4: Sent emails

That is all for this tutorial and I hope the article served you with whatever you were looking for. Happy Learning and do not forget to share!

5. Summary

In this tutorial, we saw the mailhog and create a simple application to understand its practical implementation. You can download the source code from the Downloads section.

6. Download the Project

This was a tutorial to implement a fake SMTP server in a nodejs application.

Download
You can download the full source code of this example here: Mailhog and Nodejs example

Yatin Batra

An experience full-stack engineer well versed with Core Java, Spring/Springboot, MVC, Security, AOP, Frontend (Angular & React), and cloud technologies (such as AWS, GCP, Jenkins, Docker, K8).
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button