You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker环境Nginx+PHP+msmtp交互发信正常但PHP脚本发信失败求助

PHP通过msmtp发信失败排查方案

问题描述

构建了运行Nginx、PHP和msmtp的Docker镜像,容器内通过交互式方式发送邮件正常,但PHP脚本调用mail()函数发信失败。PHP本身运行正常,暂未解决日志配置问题,优先解决脚本发信问题。

现有配置文件

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.yml

...
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
";
    $email_content .= "Email: $email

";
    $email_content .= "Message:
$message
";

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

    // 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();
}
?>

解决步骤

1. 配置PHP使用msmtp作为sendmail程序

PHP默认调用系统sendmail,需指定为msmtp。在Dockerfile中添加:

# 配置PHP使用msmtp
RUN echo "sendmail_path = /usr/bin/msmtp -t" >> /usr/local/etc/php/php.ini

若使用PHP-FPM,可在FPM的pool配置中添加php_admin_value[sendmail_path] = /usr/bin/msmtp -t确保生效。

2. 修复msmtp日志路径权限问题

当前msmtp.conf中logfile ~/msmtp.log指向交互式用户家目录,但PHP运行用户www-data无访问/写入权限。修改如下:

  • 更新msmtp.conf日志路径:
    logfile /var/log/msmtp.log
    
  • 在Dockerfile中创建日志文件并设置权限:
    RUN touch /var/log/msmtp.log && chown www-data:www-data /var/log/msmtp.log
    

3. 确保msmtp配置文件权限正确

挂载的msmtp.conf需让www-data有读取权限,同时满足msmtp的安全要求(无其他用户写入权限):

# 在宿主机执行调整权限
chmod 644 /home/addohm/cdc/v2/config/msmtp.conf

4. 修正PHP邮件头换行格式

邮件标准要求头信息使用\r\n作为换行符,修改PHP脚本的headers部分:

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

5. 验证www-data用户的发信权限

进入容器,切换到www-data用户手动测试msmtp:

docker exec -it <容器名> /bin/bash
su - www-data -s /bin/bash
# 发送测试邮件
echo -e "To: user@office.com\nSubject: Test from www-data\n\nTest message content" | msmtp -t

若命令失败,根据错误提示排查配置文件读取权限、SMTP认证等问题。


内容的提问来源于stack exchange,提问作者addohm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 15:56:02