在DigitalOcean配置Sendmail+Gmail SMTP后PHP mail()超时报错求助
Let’s break down why you’re seeing this discrepancy—command-line Sendmail works (with delay) but PHP’s mail() throws timeouts or 504s. The root cause usually boils down to context differences between your user session and the PHP runtime, or hidden FQDN configuration issues even if you didn’t spot warning logs. Here’s how to fix it step by step:
1. Verify PHP’s Sendmail Path & Permissions
First, make sure PHP is using the correct Sendmail binary and has the right permissions to execute it:
- Run
php -i | grep sendmail_pathto check your PHP configuration. It should point to your system’s Sendmail (e.g.,/usr/sbin/sendmail -t -i). If it’s missing the-t -iflags, add them—these prevent Sendmail from waiting for extra input which can cause timeouts. - Check the permissions of the PHP runtime user (usually
www-datafor Apache/Nginx). Ensure this user can execute the Sendmail binary and access Sendmail’s config files in/etc/mail/. You can test this by switching to the PHP user:su - www-data -s /bin/bashthen running a Sendmail test command likeecho "Test message" | sendmail your-test-email@example.com.
2. Force FQDN Configuration (Even Without Log Warnings)
Delay in command-line Sendmail often hints at missing FQDN, and PHP’s runtime might be more sensitive to this than your user session. Fix it:
- Edit
/etc/hostnameand set a fully qualified domain name (e.g.,your-server.yourdomain.com). - Update
/etc/hoststo map your server’s IP to the FQDN:127.0.0.1 your-server.yourdomain.com your-server [your-server-public-ip] your-server.yourdomain.com your-server - Restart Sendmail to apply changes:
systemctl restart sendmail(useservice sendmail restartfor older systems). - After this, tail the Sendmail logs in real-time while testing PHP
mail():tail -f /var/log/mail.log(Debian/Ubuntu) or/var/log/maillog(CentOS). This might reveal hidden warnings you missed earlier.
3. Adjust PHP & Web Server Timeout Settings
A 504 Gateway Timeout usually means your web server is waiting too long for PHP to respond. Tweak these timeouts:
- In
php.ini, increasemax_execution_timefrom the default 30 seconds to 60 (or higher temporarily for testing):max_execution_time = 60. - If using PHP-FPM, edit your pool config (e.g.,
/etc/php/8.2/fpm/pool.d/www.conf) and setrequest_terminate_timeout = 60sto match the PHP execution timeout. - For Nginx, adjust
proxy_read_timeoutin your site config to at least 60 seconds; for Apache, modifyTimeoutinapache2.conf.
4. Double-Check Gmail SMTP Configuration for Sendmail
Even though command-line works, PHP’s runtime might be hitting permission issues with Sendmail’s Gmail auth config:
- Ensure your Sendmail auth info file (e.g.,
/etc/mail/authinfo) has permissions set to600(read/write only for root):chmod 600 /etc/mail/authinfo. - Confirm you’re using an app-specific password for Gmail if you have 2FA enabled—regular passwords won’t work for SMTP relay.
- Re-generate your Sendmail config to make sure all SMTP settings are applied:
m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cfthen restart Sendmail.
5. Test with a Minimal PHP Script
Isolate the issue with a simple test script to rule out complex code causing delays:
<?php $to = "your-test-email@example.com"; $subject = "PHP Mail Test"; $message = "This is a test from PHP's mail() function."; $headers = "From: your-gmail-address@gmail.com\r\n" . "Reply-To: your-gmail-address@gmail.com\r\n" . "X-Mailer: PHP/" . phpversion(); if (mail($to, $subject, $message, $headers)) { echo "Mail sent successfully!"; } else { echo "Mail failed to send."; } ?>
Run this script via your web browser, and monitor both Sendmail logs and your web server’s error logs (e.g., /var/log/nginx/error.log) to catch specific errors that might be causing the timeout.
内容的提问来源于stack exchange,提问作者Positonic

