garson
garson

Reputation: 1617

PHPMailer is causing 504 timeout error on my Digital Ocean server using nginx

I am installing an email-sending capability on one PHP page on my server. I want to be able to specify the gmail account to send from so I am using PHPMailer. However, every time I load the page that sends the email, I get a 504 Gateway timeout error after about 30 seconds. Eventually, the email is sent (I receive it about 5 minutes later) but is this normal? It is a very basic text email.

This is my code to send the email

require '../html/lib/phpmailer/PHPMailerAutoload.php';


//Create a new PHPMailer instance
$mail = new PHPMailer;

//Tell PHPMailer to use SMTP
$mail->isSMTP();

//Enable SMTP debugging
// 0 = off (for production use)
// 1 = client messages
// 2 = client and server messages
$mail->SMTPDebug = 2;

//Ask for HTML-friendly debug output
$mail->Debugoutput = 'html';

//Set the hostname of the mail server
$mail->Host = 'smtp.gmail.com';

//Set the SMTP port number - 587 for authenticated TLS, a.k.a. RFC4409 SMTP submission
$mail->Port = 587;

//Set the encryption system to use - ssl (deprecated) or tls
$mail->SMTPSecure = 'tls';

//Whether to use SMTP authentication
$mail->SMTPAuth = true;

//Username to use for SMTP authentication - use full email address for gmail
$mail->Username = "[email protected]";

//Password to use for SMTP authentication
$mail->Password = "pw";

//Set who the message is to be sent from
$mail->setFrom('[email protected]', 'First Last');

//Set an alternative reply-to address
//$mail->addReplyTo('@example.com', 'First Last');

//Set who the message is to be sent to
$mail->addAddress('[email protected]', 'recip');
$mail->Subject = 'PHPMailer GMail SMTP test 2';

//Read an HTML message body from an external file, convert referenced images to embedded,
//convert HTML into a basic plain-text alternative body
//$mail->msgHTML(file_get_contents('contents.html'), dirname(__FILE__));

//Replace the plain text body with one created manually
$mail->Body = 'This is another plain-text message body';

//Attach an image file
//$mail->addAttachment('images/phpmailer_mini.png');

//send the message, check for errors
if (!$mail->send()) {
    echo "Mailer Error: " . $mail->ErrorInfo;
} else {
    echo "Message sent!";
}

Upvotes: 4

Views: 10311

Answers (2)

hsols
hsols

Reputation: 71

Digital Ocean states in their support center how to enable services like smtp to prioritize connections over IPv4 whilst still maintaining accessible IPv6 functionality to your droplet otherwise.

You can give priority to IPv4 addresses over IPv6 so that you can continue to send out email without disabling IPv6. You would do that by editing the Droplet's /etc/gai.conf file and removing the comment (#) from the following line:

Default Configuration: #precedence ::ffff:0:0/96 100

Configuration with Priority to IPv4: precedence ::ffff:0:0/96 100

This has been checked and confirmed working by me for the PHPMailer-issue where request would time out (504 Gateway Time-out) but where the mail is still eventually delivered (Ubuntu 16.04 LEMP).

This is because Ngninx drops the connection to PHP-FPM whilst the php-script is still running in the background trying to resolve an IPv6 SMTP-address, before finally moving over to IPv4 on no-success.

Upvotes: 1

Synchro
Synchro

Reputation: 37770

SMTP timeouts are pretty long (at least 5 mins). The 504 you're getting is because the timeout between nginx and your PHP cgi (I'd assume you're running FPM) is shorter, so by the time PHP generates an error, nginx has already dropped the connection, so you're getting no feedback.

It's fairly likely this is a DNS or firewall issue on your host - check out the troubleshooting docs.

Upvotes: 2

Related Questions