Spent yesterday and this morning trying to figure out what's going on. I've got a simple Rails 5 app successfully sending emails using sendgrid from the development rails console but attempting the same thing in heroku deployed production rails console doesn't send email but generates the following error:
Errno::ECONNREFUSED: Connection refused - connect(2) for "localhost" port 25
from (irb):1
More details:
# Load the Rails application.
require_relative 'application'
# Initialize the Rails application.
Rails.application.initialize!
Invoicer::Application.configure do
# Setup the mailer config
config.action_mailer.delivery_method = :smtp
config.action_mailer.perform_deliveries = true
config.action_mailer.smtp_settings = {
:user_name => ENV['SENDGRID_USERNAME'],
:password => ENV['SENDGRID_PASSWORD'],
:domain => '[myapp].herokuapp.com',
:address => 'smtp.sendgrid.net',
:port => 587,
:authentication => :plain,
:enable_starttls_auto => true
}
end
The only email related not commented code is:
# Don't care if the mailer can't send.
config.action_mailer.raise_delivery_errors = false
config.action_mailer.perform_caching = false
The only email related line not commented is:
config.action_mailer.perform_caching = false
In development on my local machine an email is generated.
>> ActionMailer::Base.delivery_method
=> :smtp
>> InvoiceMailer.invoice_email(Customer.first).delivery_method
Customer Load (0.6ms) SELECT "customers".* FROM "customers" ORDER BY "customers"."id" ASC LIMIT $1 [["LIMIT", 1]]
Rendering invoice_mailer/invoice_email.html.erb within layouts/mailer
Rendered invoice_mailer/invoice_email.html.erb within layouts/mailer (0.0ms)
Rendering invoice_mailer/invoice_email.text.erb within layouts/mailer
Rendered invoice_mailer/invoice_email.text.erb within layouts/mailer (0.0ms)
InvoiceMailer#invoice_email: processed outbound mail in 17.6ms
=> #<Mail::SMTP:0x007f939b607b48 @settings= {:address=>"smtp.sendgrid.net", :port=>587, :domain=>"fm- invoicer.herokuapp.com", :user_name=>"[email protected]", :password=>"ms9nps8r7677", :authentication=>:plain, :enable_starttls_auto=>true, :openssl_verify_mode=>nil, :ssl=>nil, :tls=>nil}>
Heroku production no email is sent and I get an error.
$ heroku run rails c
Loading production environment (Rails 5.1.3)
irb(main):001:0> InvoiceMailer.invoice_email(Customer.first).deliver
D, [2017-09-03T14:59:53.803069 #4] DEBUG -- :Customer Load (7.2ms) SELECT "customers".* FROM "customers" ORDER BY "customers"."id" ASC LIMIT $1 [["LIMIT", 1]]
I, [2017-09-03T14:59:53.863967 #4] INFO -- :Rendering invoice_mailer/invoice_email.html.erb within layouts/mailer
I, [2017-09-03T14:59:53.864680 #4] INFO -- :Rendered invoice_mailer/invoice_email.html.erb within layouts/mailer (0.6ms)
I, [2017-09-03T14:59:53.865742 #4] INFO -- :Rendering invoice_mailer/invoice_email.text.erb within layouts/mailer
I, [2017-09-03T14:59:53.866329 #4] INFO -- :Rendered invoice_mailer/invoice_email.text.erb within layouts/mailer (0.4ms)
D, [2017-09-03T14:59:54.087932 #4] DEBUG -- : InvoiceMailer#invoice_email: processed outbound mail in 232.7ms
I, [2017-09-03T14:59:54.101584 #4] INFO -- : Sent mail to [email protected] (13.4ms)
D, [2017-09-03T14:59:54.102047 #4] DEBUG -- : Date: Sun, 03 Sep 2017 14:59:54 +0000
From: [email protected]
To: [email protected]
Message-ID: <59ac18ea16bd6_451d0d888799@f74404ed-7ea9-41ff-9b05-715d2a185bf4.mail>
Subject: XXXXX Website Monthly Invoice - August-2017
Mime-Version: 1.0
Content-Type: multipart/alternative;
boundary="--==_mimepart_59ac18ea151a7_451d0d8886dd";
charset=UTF-8
Content-Transfer-Encoding: 7bit
----==_mimepart_59ac18ea151a7_451d0d8886dd
Content-Type: text/plain;
charset=UTF-8
Content-Transfer-Encoding: 7bit
Dear XXX
Attached please find your monthly invoice.
Best,
XXX
CrazyJ Media ;-)
----==_mimepart_59ac18ea151a7_451d0d8886dd
Content-Type: text/html;
charset=UTF-8
Content-Transfer-Encoding: 7bit
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style>
/* Email styles need to be inline */
</style>
</head>
<body>
<!DOCTYPE html>
<html>
<head>
<meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
</head>
<body>
<p>Dear XXX,</p>
<p>Attached please find the latest monthly invoice.</p>
<p>Best,<br>XXX<br>Crazy J Media</p>
</body>
</html>
</body>
</html>
----==_mimepart_59ac18ea151a7_451d0d8886dd--
Errno::ECONNREFUSED: Connection refused - connect(2) for "localhost" port 25
from (irb):1
Also in Heroku Rails Console:
irb(main):001:0> ActionMailer::Base.delivery_method
=> :smtp
irb(main):002:0> InvoiceMailer.invoice_email(Customer.first).delivery_method
D, [2017-09-13T22:42:58.951166 #4] DEBUG -- : Customer Load (2.8ms) SELECT "customers".* FROM "customers" ORDER BY "customers"."id" ASC LIMIT $1 [["LIMIT", 1]]
I, [2017-09-13T22:42:59.037206 #4] INFO -- : Rendering invoice_mailer/invoice_email.html.erb within layouts/mailer
I, [2017-09-13T22:42:59.038316 #4] INFO -- : Rendered invoice_mailer/invoice_email.html.erb within layouts/mailer (0.9ms)
I, [2017-09-13T22:42:59.039720 #4] INFO -- : Rendering invoice_mailer/invoice_email.text.erb within layouts/mailer
I, [2017-09-13T22:42:59.040359 #4] INFO -- : Rendered invoice_mailer/invoice_email.text.erb within layouts/mailer (0.5ms)
D, [2017-09-13T22:42:59.413839 #4] DEBUG -- : InvoiceMailer#invoice_email: processed outbound mail in 405.7ms
=> #<Mail::SMTP:0x0000000575c678 @settings={:address=>"localhost", :port=>25, :domain=>"localhost.localdomain", :user_name=>nil, :password=>nil, :authentication=>nil, :enable_starttls_auto=>true, :openssl_verify_mode=>nil, :ssl=>nil, :tls=>nil}>
Anyone have any ideas? I've studied Heroku's sendgrid ruby docs as well as several SO questions and answers like this one but to no avail. I've restarted my heroku server and my sendgrid account linked to this app is working and recording email sent from development.
Much positive karma being sent in advance to anyone with any insight!
The error shows that it's configured to send email using the SMTP server at localhost port 25, which would indicate that your config isn't being used!
When Rails.application.initialize!
runs in production, ActionMailer is eager-loaded and configured with the settings it has been given at that moment. In your case it looks like that means it's using default values, as your own config isn't set until later.
You can resolve this by simply setting the config before initializing the app; either re-order your environment.rb so that config happens first, or move the ActionMailer config to application.rb or an environment-specific config (environments/production.rb, for example).
Probably you should move the Action Mailer configs to config/environments/production.rb and/or check if nothing is overriding your settings inside this file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With