Mailhog fails to send messages from PHP script, localhost, docker, Ubuntu

120 views Asked by At

My PHP script fails to send messages to Mailhog client. I'm using the Slim PHP framework. Here's what I've tried:-

Container is up and running with sendmail path set:

enter image description here

docker exec -it php cat /usr/local/etc/php/conf.d/local.ini
error_reporting=E_ALL
sendmail_path="mhsendmail --smtp-addr=mailhog:1025"

Sendmail installed locally sudo apt-get install sendmail

docker-compose.yaml

version: '3'
services:

  #PHP Service
  php:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: php
    restart: unless-stopped
    tty: true
    environment:
      SERVICE_NAME: php
      SERVICE_TAGS: dev
    working_dir: /var/www
    volumes:
      - ./:/var/www
      - ./docker/php/local.ini:/usr/local/etc/php/conf.d/local.ini
    networks:
      - app-network

  #Mailhog
  mailhog:
    container_name: mailhog
    image: mailhog/mailhog
    ports:
      - "1025:1025"
      - "8025:8025"
    networks:
      - app-network

Dockerfile

FROM php:8.1-fpm

# Copy composer.lock and composer.json
# COPY composer.lock composer.json /var/www/

# Set working directory
WORKDIR /var/www

# Install dependencies
RUN apt-get update && apt-get install -y \
    build-essential \
    libpng-dev \
    libjpeg62-turbo-dev \
    libfreetype6-dev \
    locales \
    libzip-dev \
    zip \
    jpegoptim optipng pngquant gifsicle \
    vim \
    unzip \
    git \
    curl

# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

# Install extensions
RUN docker-php-ext-install mysqli pdo pdo_mysql && docker-php-ext-enable pdo_mysql
RUN docker-php-ext-configure gd --with-freetype --with-jpeg
RUN docker-php-ext-install gd

# Install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer


RUN groupadd -g 1000 www
RUN useradd -u 1000 -ms /bin/bash -g www www

# Copy existing application directory contents
COPY . /var/www

# Copy existing application directory permissions
COPY --chown=www:www . /var/www

# Change current user to www
USER www

# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["php-fpm"]

In my PHP script:

$to = '[email protected]';
    $subject = 'Hello from Ubuntu!';
    $message = 'This is a Mailhog test';
    $headers = "From: [email protected]\r\n";

    if (mail($to, $subject, $message, $headers)) {
        echo "SUCCESS";
    } else {
        echo "ERROR";
    }

Upon hitting my endpoint, the script returns ERROR? Any ideas?

1

There are 1 answers

0
cookie On

Use PHPMailer as this has integrated SMTP support – send without a local mail server. Full code here:-

<?php
require __DIR__ . '/../vendor/autoload.php';

use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Slim\Factory\AppFactory;
use PHPMailer\PHPMailer\PHPMailer;

$app = AppFactory::create();


$app->post('/send-email', function (RequestInterface $request, ResponseInterface $response) {

    $data = $request->getParsedBody();

    $recipient = $data['recipient'];
    $subject = $data['subject'];
    $body = $data['body'];
    $recipientName = $data['recipient_name'];

    $mail = new PHPMailer(true);

    try {
        //Server settings
        $mail->isSMTP();
        $mail->Host       = 'mailhog'; // Set the SMTP server to send through
        $mail->SMTPAuth   = true; // Enable SMTP authentication
        $mail->Username   = ''; // SMTP username
        $mail->Password   = ''; // SMTP password
        $mail->Port       = 1025; // TCP port to connect to, use 465 for `PHPMailer::ENCRYPTION_SMTPS` above

        //Recipients
        $mail->setFrom('[email protected]', 'Mailer');
        $mail->addAddress($recipient, $recipientName); // Add a recipient

        // Content
        $mail->isHTML(true); // Set email format to HTML
        $mail->Subject = $subject;
        $mail->Body    = $body;
        $mail->AltBody = 'This is the body in plain text for non-HTML mail clients';

        $mail->send();
        $response->getBody()->write(json_encode(['message' => 'Email sent successfully']));

        return $response->withHeader('Content-Type', 'application/json')->withStatus(200);

    } catch (Exception $e) {
        $response->getBody()->write(json_encode(['error' => $mail->ErrorInfo]));

        return $response->withHeader('Content-Type', 'application/json')->withStatus(500);
    }
});

$app->run();