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
相关产品推荐
相关产品推荐

