I've got my ActionMailer setup and working perfectly in development. I can call UserMailer.welcome(user).deliver
, and the email reaches its destination. However, when I push my code into production and call the same deliver
method, suddenly I get an error:
Errno::ECONNREFUSED: Connection refused - connect(2)
from /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/net/smtp.rb:546:in `initialize'
from /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/net/smtp.rb:546:in `open'
from /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/net/smtp.rb:546:in `tcp_socket'
from /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/net/smtp.rb:555:in `block in do_start'
from /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/timeout.rb:58:in `timeout'
from /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/timeout.rb:89:in `timeout'
from /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/net/smtp.rb:555:in `do_start'
from /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/net/smtp.rb:525:in `start'
from /webapps/myapp/production/shared/bundle/ruby/1.9.1/gems/mail-2.3.0/lib/mail/network/delivery_methods/smtp.rb:128:in `deliver!'
from /webapps/myapp/production/shared/bundle/ruby/1.9.1/gems/mail-2.3.0/lib/mail/message.rb:1989:in `do_delivery'
from /webapps/myapp/production/shared/bundle/ruby/1.9.1/gems/mail-2.3.0/lib/mail/message.rb:230:in `block in deliver'
from /webapps/myapp/production/shared/bundle/ruby/1.9.1/bundler/gems/rails-5680a51dcbaf/actionmailer/lib/action_mailer/base.rb:414:in `block in deliver_mail'
from /webapps/myapp/production/shared/bundle/ruby/1.9.1/bundler/gems/rails-5680a51dcbaf/activesupport/lib/active_support/notifications.rb:55:in `block in instrument'
from /webapps/myapp/production/shared/bundle/ruby/1.9.1/bundler/gems/rails-5680a51dcbaf/activesupport/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
from /webapps/myapp/production/shared/bundle/ruby/1.9.1/bundler/gems/rails-5680a51dcbaf/activesupport/lib/active_support/notifications.rb:55:in `instrument'
from /webapps/myapp/production/shared/bundle/ruby/1.9.1/bundler/gems/rails-5680a51dcbaf/actionmailer/lib/action_mailer/base.rb:412:in `deliver_mail'
from /webapps/myapp/production/shared/bundle/ruby/1.9.1/gems/mail-2.3.0/lib/mail/message.rb:230:in `deliver'
from (irb):10
from /webapps/myapp/production/shared/bundle/ruby/1.9.1/bundler/gems/rails-5680a51dcbaf/railties/lib/rails/commands/console.rb:45:in `start'
from /webapps/myapp/production/shared/bundle/ruby/1.9.1/bundler/gems/rails-5680a51dcbaf/railties/lib/rails/commands/console.rb:8:in `start'
from /webapps/myapp/production/shared/bundle/ruby/1.9.1/bundler/gems/rails-5680a51dcbaf/railties/lib/rails/commands.rb:40:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
Probably the most valuable info I can offer is that the actual delivery_method
data on the Message object is incorrect in production. In development, when I call UserMailer.welcome(user).delivery_method
, the (formatted) output is:
#<Mail::SMTP:0x000001042c4a20 @settings={
:address=>"smtp.gmail.com",
:port=>587,
:domain=>"foobar.com",
:user_name=>"[email protected]",
:password=>"MY_PASSWORD",
:authentication=>"plain",
:enable_starttls_auto=>true,
:openssl_verify_mode=>nil}>
This clearly matches the settings I've defined in mailers.yml. In production, when I make the same call, the output is:
#<Mail::SMTP:0xbfb2c18 @settings={
:address=>"localhost",
:port=>25,
:domain=>"localhost.localdomain",
:user_name=>nil,
:password=>nil,
:authentication=>nil,
:enable_starttls_auto=>true,
:openssl_verify_mode=>nil}>
This just appears to be the defaults as defined on line 22 of ActionMailer::DeliveryMethods instead of my own settings from mailers.yml.
As far as I can tell, my environments should have ActionMailer setup the same.
config/environment.rb:
Myapp::Application.config.action_mailer.delivery_method = :smtp
Myapp::Application.config.action_mailer.smtp_settings = YAML.load_file(
Rails.root.join('config', 'mailers.yml'))[Rails.env].to_options
config/mailers.yml:
default: &default
address: smtp.gmail.com
port: 587
domain: foobar.com
user_name: [email protected]
password: MY_PASSWORD
authentication: plain
enable_starttls_auto: true
development:
<<: *default
production:
<<: *default
config/environments/development.rb:
Myapp::Application.configure do
# ...
config.action_mailer.raise_delivery_errors = false
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
config.action_mailer.interceptors = ['MailInterceptor']
# ...
end
config/environments/production.rb:
Myapp::Application.configure do
# ...
config.action_mailer.default_url_options = { :host => 'foobar.com' }
# ...
end
Note that I've also tried commenting out the two extra lines in development.rb (and tried adding them into production.rb) with no change -- I still get the same error in production, but not development.
Also, although I don't think it's relevant, I'll include MailIntercepter
that I reference in development.rb (it's just to redirect all mail to my email address instead of test users' email addresses):
class MailInterceptor
def self.delivering_email(message)
message.subject = "[#{message.to}] #{message.subject}"
message.to = "[email protected]"
end
end
Figured it out, though it seems to go against what I thought was supposed to be the standard approach to Rails 3.1 config.
Changed this line:
Myapp::Application.config.action_mailer.smtp_settings = YAML.load_file(
Rails.root.join('config', 'mailers.yml'))[Rails.env].try(:to_options)
To this:
ActionMailer::Base.smtp_settings = YAML.load_file(
Rails.root.join('config', 'mailers.yml'))[Rails.env].try(:to_options)
Still not sure why the former works in development but not production, but the latter now works for me in production, so it's what I'm going with for now.
By any chance do you have your environment.rb
set up like:
Myapp::Application.initialize!
Myapp::Application.configure do { }
If so, swap these two lines. I had nearly the same issue (mailer config worked in dev, not in other environments) and that was the problem.
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