phpdockernginxdockerfilemsmtp

docker msmtp php nginx and failing email sends (via php)


I've put together a docker image that runs nginx, php, and msmtp. I can send myself emails from within the container interactively but when I try to send emails from a php script, it fails. I am struggling to figure out why as I can't get the logging to pipe correctly either but that's a separate issue at this point. I really just need to get the emails sent so I can tie this little mini project off. Any help is massively appreciated. Also, the php is working fine, no errors to speak of.

Dockerfile

# Configure msmtp
ENV SYSCONFDIR=/etc/msmtp
RUN mkdir ${SYSCONFDIR}
RUN touch ${SYSCONFDIR}/msmtp.conf
RUN ln -s ${SYSCONFDIR}/msmtp.conf /etc/msmtprc

docker-compose

...
volumes:
    - /home/addohm/cdc/v2/config/msmtp.conf:/etc/msmtp/msmtp.conf:ro
...

msmtp.conf

# Set default values for all following accounts.
defaults
logfile          ~/msmtp.log

# Gmail
account        gmail
host           smtp.gmail.com
port           465
tls_starttls   off
from           username@gmail.com
user           username
password       plain-text-password

# Office
account         office
host            smtp.office365.com
port            587
auth            on
tls             on
tls_starttls    on
tls_certcheck   on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
from            user@office.com
user            user@office.com
password        password

# Set a default account
account default: office

contact.html

<!-- Contact Form -->
<form class="row g-3" action="send_email.php" method="POST">
  <div class="col-md-6">
    <label for="name" class="form-label">Name</label>
    <input type="text" class="form-control" id="name" name="name" required>
  </div>
  <div class="col-md-6">
    <label for="email" class="form-label">Email</label>
    <input type="email" class="form-control" id="email" name="email" required>
  </div>
  <div class="col-12">
    <label for="message" class="form-label">Message</label>
    <textarea class="form-control" id="message" name="message" rows="5" required></textarea>
  </div>
  <div class="col-12 text-center">
    <button type="submit" class="btn btn-primary">Send Message</button>
  </div>
</form>

send_email.php

<?php
// Check if the form is submitted
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    // Get form data
    $name = htmlspecialchars($_POST['name']);
    $email = htmlspecialchars($_POST['email']);
    $message = htmlspecialchars($_POST['message']);

    // Set the recipient email address
    $to = "user@office.com"; // Replace with your email address

    // Set the email subject
    $subject = "New Contact Form Submission from $name";

    // Build the email content
    $email_content = "Name: $name\n";
    $email_content .= "Email: $email\n\n";
    $email_content .= "Message:\n$message\n";

    // Set the email headers
    $headers = "From: $name <$email>\r\n";
    $headers .= "Reply-To: $email\r\n";

    // Send the email
    if (mail($to, $subject, $email_content, $headers)) {
        // Email sent successfully
        echo "<p>Thank you for contacting us, $name! We will get back to you soon.</p>";
    } else {
        // Email failed to send
        echo "<p>Oops! Something went wrong. Please try again later.</p>";
    }
} else {
    // If the form is not submitted, redirect to the contact page
    header("Location: contacts.html");
    exit();
}
?>

I am well aware that logs might help but truth be told I spent the entire day trying to get proper logs out of my image but I've been breaking things more than anything else.


Solution

  • I figured it out. The mail function is finacky after passing anything more than 3 parameters in. It is supposed to accept more (e.g. email headers) but it just doesn't seem to work.