loading...

Mailhog in Laradock

dendihandian profile image Dendi Handian Updated on ・3 min read

Explore Laradock Services (8 Part Series)

1) Laradock - A PHP Developer's best friend. 2) Redis in Laradock 3 ... 6 3) Mailhog in Laradock 4) PHP-Worker in Laradock 5) PHP-Worker for Scheduler in Laradock 6) RabbitMQ in Laradock 7) Elasticsearch in Laradock 8) HTTPS Local Development using Caddy in Laradock

Sending mail probably is one of the inseparable functionality when an app has registered or subscribing users. During development, we tend to use an SMTP testing server like mailtrap.io.

Mailtrap provides a free plan for a single inbox for testing and we can send mails to this inbox with a limitation of emails stored in the inbox. Somehow when we use this free plan, we also come to a limitation of how many emails can be sent within a second(s), so we can't send multiple emails at the same time and we have to make a delay/sleep for each mail process.

The answer to the above problems is mailhog. Mailhog is an SMTP testing server that runs locally in your server/machine, and Laradock has this service. Let's try this out.

Run Mailhog server and the web UI

I assume you have tried and know how to work with Laradock, if not then you can start to setup a laravel app with Laradock here.

To run the mailhog server and the web UI, simply run this docker-compose command:

docker-compose up -d mailhog

the container should be working and status is up when you check it using docker-compose ps command:

           Name                          Command               State                       Ports
---------------------------------------------------------------------------------------------------------------------
laradock_mailhog_1            MailHog Mailhog                  Up      0.0.0.0:1025->1025/tcp, 0.0.0.0:8025->8025/tcp

Setup Mailhog for Laravel App

in your laravel app's .env, add/change these parameters into like this:

MAIL_DRIVER=smtp
MAIL_HOST=mailhog
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=from@example.com
MAIL_FROM_NAME=Example

Example of sending mail in Laravel

We can create a simple artisan command to send mail, here are what you need to add to your laravel project:

app\Console\Commands\ExampleSendMailCommand.php:

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

use App\Mail\ExampleMail;
use Illuminate\Support\Facades\Mail;

class ExampleSendMailCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'example:send-mail';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command for exemplify the mail sending in laravel';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        Mail::to('example@mailinator.net')->send(new ExampleMail());
    }
}

app\Mail\ExampleMail.php:

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class ExampleMail extends Mailable implements ShouldQueue
{
    use Queueable, SerializesModels;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('mails.example');
    }
}

resources\views\mails\example.blade.php:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Example Mail Test</title>
</head>
<body>
    <h1>Hello from the other side!</h1>
</body>
</html>

add/register the command to app\Console\Kernel.php:

<?php

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

use App\Console\Commands\ExampleSendMailCommand;

class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        ExampleSendMailCommand::class,
    ];

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        // $schedule->command('inspire')
        //          ->hourly();
    }

    /**
     * Register the commands for the application.
     *
     * @return void
     */
    protected function commands()
    {
        $this->load(__DIR__.'/Commands');

        require base_path('routes/console.php');
    }
}

Finally, now enter the laradock workspace bash (if you haven't) using your favorite CLI to execute this command:

docker-compose exec --user=laradock workspace bash

go inside your laravel app root directory and execute this artisan command:

php artisan example:send-mail

If there is no error when executing the command, then let's see our inbox!

Acessing the Mailhog Web UI

The mailhog web UI should be accessible at http://localhost:8025. Your example email should be there :)

2020-03-23-16h13-12

Making email messages persistent

Mailhog store the caught messages in memory, which means when you stop container and then run again, all your messages will be gone (forever). So if you want to keep them, then you have to make it persistent by configuring the laradock/docker-compose.yml. Find the mailhog configuration in the file, and change it into like this:

...

## Mailhog ################################################
    mailhog:
      build: ./mailhog
      volumes:
        - ${DATA_PATH_HOST}/mailhog/maildir:/maildir
      command: ["-storage=maildir", "-maildir-path=/maildir"]
      ports:
        - "1025:1025"
        - "8025:8025"
      networks:
        - frontend
        - backend

...

Then restart or stop-run the container. Starting from this point, all your messages will be saved.

Have fun exploring Mailhog in Laradock!

laravel version used: 6.0 LTS

Explore Laradock Services (8 Part Series)

1) Laradock - A PHP Developer's best friend. 2) Redis in Laradock 3 ... 6 3) Mailhog in Laradock 4) PHP-Worker in Laradock 5) PHP-Worker for Scheduler in Laradock 6) RabbitMQ in Laradock 7) Elasticsearch in Laradock 8) HTTPS Local Development using Caddy in Laradock

Posted on Mar 23 by:

dendihandian profile

Dendi Handian

@dendihandian

Please teach me how to prettify database schema, implement any design patterns and do TDD in Drupal / Wordpress and how to make them not slow as ever.

Discussion

markdown guide