Connection refused - connect(2) for "localhost" port 25 rails - ruby-on-rails

During my training, I'm working on a website and we use Ruby on Rails. We need to send mails to users so I created a mailer.
I have tried to put the smtp in both development.rb and environment.rb
config.action_mailer.default_url_options = {host: '0.0.0.0:3000'}
config.action_mailer.default charset: 'utf-8'
config.action_mailer.delivery_method = 'smtp'
config.action_mailer.perform_deliveries = true
config.action_mailer.smtp_settings = {
adress: $SMTP_SERVER,
port: $PORT,
from: $MAIL,
enable_starttls_auto: true
#authentication: 'login'
}
It tells me that the error comes from this method line 6
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
# Tell the UserMailer to send a welcome Email after save
UserMailer.welcome_email(#user).deliver_now
format.html { redirect_to(#user, :notice => 'User was successfully created.') }
format.json { render :json => #user, :status => :created, :location => #user }
else
format.html { render :action => "new" }
format.json { render :json => #user.errors, :status => :unprocessable_entity }
end
end
end
I have set the port to 587 but i keep getting the error:
Errno::ECONNREFUSED: Connection refused - connect(2) for "localhost"
port 25
It looks as if another file was overwriting my settings. I also saw that it might be related to my ssh key not being authorized by the server.
Do know what is wrong?
Thanks in advance

First of all, when developing on localhost, it's common to not actually send out mail, rather to treat that as a deployment detail and stick with the Rails default behavior which is to spit out the mail headers and contents into the console STDOUT (where you can verify that the text looks right). Is there a specific reason why you need to test sending messages in the dev environment?
Secondly, you mentioned that you set the SMTP settings in both development.rb and environment.rb. You shouldn't need to set these settings twice; in general I'd use development.rb for settings specific to the dev environment, and environment.rb only for settings that will always apply to all environments (dev, tests, and on the live deployed server). So if you're setting the same settings in both development.rb and environment.rb, I'd start by removing one or the other; redundancy will only make your job harder down the road.
Finally, to troubleshoot this I'd start by asking Rails what its settings are rather than waiting for the mail delivery to fail. Try the following:
Start up rails console
Enter Rails.configuration.action_mailer.smtp_settings and compare the resulting hash against your expectations. This hash should contain the port and domain settings that are used when sending out all mail (in the current environment), so if ActionMailer is trying the wrong port then I'd expect the port to be wrong here too.
Where are you setting $SMTP_SERVER, $PORT and $MAIL? Is there any reason you aren't using Rails' convention for environment variables, ENV['SMTP_SERVER'] etc.?
Hope some of that helps. Good luck!

replace
config.action_mailer.delivery_method = 'smtp'
with
config.action_mailer.delivery_method = :smtp
Ensure your Rails.configuration.action_mailer.smtp_settings is symbolized keys

I ran into the same error message well developing my own application. What I discovered is that as I was not actually sending any emails in a development environment I needed to change one of the lines in the configuration file found at: /your_apps_name/config/environments/development.rb
from
config.action_mailer.raise_delivery_errors = true
to
config.action_mailer.raise_delivery_errors = false
This was causing my application to raise errors when emails were not successfully delivered, and I wasn't actually sending emails so of course they were not being delivered successfully.

The app might be using mailcatcher gem for all outbound emails on development, which you haven't installed or don't have running. At least that was my issue. Check out https://mailcatcher.me and follow the instructions given.

You need to remove config.action_mailer.perform_deliveries = true line.

I was running into this issue when running Sidekiq::Worker.drain_all in my RSpec tests, and it was driving me crazy because I had config.action_mailer.delivery_method = :test in my config/environments/test.rb.
The solution was to set config.action_mailer.delivery_method = :test in my config/environments/development.rb, which is confusing because the implication is that my config/environments/development.rb is overriding my config/environments/test.rb in my RSpec tests.
Regardless, this might fix the problem for others.

For anyone clumsy like me, I got this message when I had everything set up perfectly in my app, but I had simply forgotten to run the command that adds the mailing addon in my production environment. In my case, that line was heroku addons:create mailgun:starter.

Related

How to avoid a 500 Internal Server Error when using the Rails ActionMailer on Heroku

I am trying to send an email to a user upon sign up in my web app, which is built with Rails in the back end and React-Redux on the front end. I used a gem called letter_opener when testing on a local server, and everything seemed to work fine. When I tried it live on Heroku, I got back a 500 error, and I'm not sure what is wrong.
I tried reading the ActionMailer docs, but it didn't seem to mention any issue like this.
The method in the UserMailer:
def welcome_email(user)
#user = user
mail(to: #user.email, subject: "Welcome")
end
Relevant code in UsersController:
def create
# ...
email = UserMailer.welcome_email(#user)
email.deliver_now # This line throws the error
# ...
end
The error from the Heroku logs:
Errno::ECONNREFUSED (Connection refused - connect(2) for "localhost" port 25):
I expected to the email to be delivered, or at least to have a more informative error message. I am not sure why Rails is looking at localhost's port 25.
I am not sure why Rails is looking at localhost's port 25.
ActionMailer defaults to localhost:25, and you probably only changed your development configuration.
Errno::ECONNREFUSED (Connection refused - connect(2) for "localhost" port 25)
Heroku doesn't provide an SMTP server, and there certainly won't be one on localhost. Use an email addon or some other third-party mail service of your choice.
You'll probably have to modify config/environments/production.rb to use whatever mail service you choose.
Chris is right, Heroku doesn't provide an SMTP server and you've to use an Addon. I'll further add on how you can proceed with using sendgrid addon which is free upto much extent.
First, goto your Heroku app -> Enable sendgrid addon. Then you'll be given sendgrid credentials. Keep them safe.
In your config/environments/production.rb add:
config.action_mailer.delivery_method = :smtp
config.action_mailer.default_url_options = { host: "your-domain.com", protocol: 'https' }
Then in your config/environment.rb file add:
...
# Initialize the Rails application.
Rails.application.initialize!
# Add sendgrid support
if Rails.env.production?
ActionMailer::Base.smtp_settings = {
:user_name => "sendgrid_username",
:password => "sendgrid_password",
:domain => "your-domain.com",
:address => "sendgrid_hostname",
:port => 3000, # sendgrid_port
:authentication => :plain,
:enable_starttls_auto => true
}
end
Change the credentials above as required. Also consider using ENV variables for above credentials.

Sidekiq job is scheduled, not running and just disappears

I'm working on a Rails application that sends emails in the background using Sidekiq and Mandrill.
In my application I have 2 queues, one for user interactions with my service (irrelevant) and the second is a mailer queue.
The mailer queue is used by 2 mailers: One for managing the user profile and the other one is for interactions with our service (irrelevant).
Today I noticed that users are not getting emails for a few days already except the confirmation email that is sent by Devise.
The other queue is working flawlessly and doesn't have any problems. (So maybe Sidekiq configuration is not the problem).
For example lets take the UserMailer that notifies the user of a successful profile update:
user_mailer.rb
def update_user(user)
#user = user
mail(:to => user.email)
end
user_profile_controller.rb
def update_resource(user)
user.save
UserMailer.update_user(user).deliver_later(wait: 1.minute)
end
When I tried testing this function with deliver_now instead of deliver_later it worked and the mail was sent (So the connection with Mandrill is working).
When I test this function as it is, the job is being added to the mailer queue. When it's time to send the email it just disappears from the queue without sending the email and without leaving any exceptions in the logs.
I can see it appear in the Sidekiq Web UI and then disappear.
I guess the confirmation email is the only one being sent because it isn't delayed, but I don't know why this is happenning.
Everything is working great on my staging environment. The difference is that it's working with mailtrap and doesn't have as much jobs as the production.
Some code that might be relevant:
production.rb
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:user_name => 'xxx',
:password => Rails.application.secrets.smtp_password,
:address => 'smtp.mandrillapp.com',
:domain => config.app_domain,
:port => 'xxx',
:authentication => :login
}
...
config.action_mailer.default_url_options = { :host => config.app_domain, :protocol => 'https' }
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = false
application.rb
config.active_job.queue_adapter = :sidekiq
Walked through these links without any solution:
http://guides.rubyonrails.org/active_job_basics.html
http://api.rubyonrails.org/classes/ActionMailer/Base.html
Haven't found any other links relevant to my issue.
Tried re-deploying
Tried restarting Sidekiq
Tried restarting Redis
Tried restarting the server itself
Tried sending email from the console - Successful
Tried sending email with deliver_later(wait:1min) - Unsuccessful
I'm suspecting it has something to do with lack of memory on the server. When I increased the memory on the server and the max_connections parameter on postgres, all the emails on that queue that were supposed to be sent, were delivered immediately

root_url on heroku - where is it getting 'Yourhost.com' from?

Some confusion here. Using devise:invitable, and sending emails from heroku with the sendgrid add on.
On local, in the email that's generated when a user is invited, <%= root_url %> generates http://localhost:3000/ - which seems perfectly correct -
but when deployed to heroku, when I receive the invite email, that same <%= root_url %> is coming out as http://yourhost.com/ ...why? Where's that set?
I thought root_url worked off routes.rb automatically and I have
root :to => 'home#splash'
I feel like I'm missing something obvious? I added the suggestions from this question to the application controller, but it has made no difference, the email still references http://yourhost.com/
Help appreciated thank you.
In your config/environments/production.rb set
config.action_mailer.default_url_options = {:host => 'www.yourdomain.com'}
You probably followed the Devise setup instructions displayed after you installed Devise which gets you to add
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
to your developments.rb file - but you just forgot about production.

Rails / Devise / Mailer: Throwing 'config.action_mailer.default_url_options' error on attempted registration

It's just been one problem after another today. I just deployed to my production server and testing it out, with issues whenever anything involves email. Particularly with Devise's confirmable registration email, whenever I sign up for an account, the following error is thrown up in the log...
ActionView::Template::Error (You can no longer call ActionMailer::Base.default_url_options directly. You need to set config.action_mailer.default_url_options. If you are using ActionMailer standalone, you need to include the routing url_helpers directly.):
Looking at my config/environments/production.rb, I have the following set...
config.action_mailer.default_url_options = { :host => 'localhost' }
So config.action_mailer.default_url_options IS being used, but is being completely ignored. I tried changing the host to '127.0.0.1' and my server's IP addy, but it wouldn't have it. Threw it in config/application.rb, but no go. I hunted in my project for any other lines declaring default_url_options, but it's only set in the production.rb file. I Googled and found a post suggesting to set config.cache_classes to false, but negative there as well.
Now here is what's crazy...I got the same error whenever I tried to submit a brand new comment in my project (set up to send an email to confirm the email address if you are a first time commentor). I took OUT config.action_mailer...etc from the production.rb file, and viola - my comment mailer worked and sent the email just fine!
Still, Devise is being absolutely stubborn and keeps throwing the above error at me. Any ideas on why? BTW, all my gems are up to date. Below is my production.rb file.
--- UPDATE ---------------
Have made a little progress, but this is just weird. When I start the server and attempt to do something that will send mail (user registration, comment), I get the ActionMailer::Base error message above. When I try the action AGAIN...it works and the mail gets sent. From that point on (until Passenger and/or the server is rebooted), all mailer actions work fine.
But not without yet another issue (it never ends)...for some reason the email body is completely blank.
I ended up hitting this problem once again when I attempted to test in the test database, and I was determined once and for all to figure out why I was getting this error, and why no one else seemed to have come across it (very little results from Google).
After completely tearing down my project and reconstructing it, I finally pinpointed the issues to the Sitemap-generator plugin I had installed. Once I removed all traces of that, the above error finally ceased.
I'm working on this issue for Fat Free CRM, and I realized that this error happens because Rails 3 lazy-loads classes. All you need to do is 'touch' the ActionMailer::Base class in your environments/**.rb files, and it will load the class. Then you can call ActionMailer::Base.default_url_options from a controller, etc. (We do this so that we can automatically set the mailer host from request.host_with_port)
So my environment files now look like this:
FatFreeCRM::Application.configure do
...
ActionMailer::Base
end
I believe I have solved this issue...though I'm not "exactly" sure what did it. It very well may have been config.cache_classes = true which I commented out, and although I was concerned this would effect my site caching or something else, it doesn't seem to have broke it.
In addition, the empty email body I solved by switching from :sendmail to :smtp.
Here is my final production.rb file, hopefully this might be of use to someone with a similar issue in the future.
MyProject::Application.configure do
# Commented out, causes 'ActionView::Template' error
#config.cache_classes = true
config.whiny_nils = true
config.consider_all_requests_local = true
config.action_view.debug_rjs = true
config.action_controller.perform_caching = true
config.cache_store = :mem_cache_store
config.active_support.deprecation = :log
config.action_dispatch.best_standards_support = :builtin
config.action_mailer.raise_delivery_errors = true
Sunspot.config.solr.url = 'http://127.0.0.1:8080/solr'
Paperclip.options[:command_path] = "/usr/bin/"
config.action_mailer.perform_deliveries = true
config.action_mailer.delivery_method = :smtp
ActionMailer::Base.smtp_settings = {
:address => "smtp.gmail.com",
:enable_starttls_auto => true,
:port => 587,
:authentication => :plain,
:user_name => "user#domain.com",
:password => 'password'
}
config.action_mailer.default_url_options = { :host => 'dev.mydomain.com' }
config.time_zone = "Central Time (US & Canada)"
end

How do I configure Rails to disable sending real emails out while in staging?

I'm on Heroku, and emails don't get sent out in development, but are properly being sent in production. I'd like to run a seperate staging instance on Heroku, but don't want emails being sent out (just to a log).
This line in test.rb tells ActionMailer not to deliver emails:
config.action_mailer.delivery_method = :test
Instead, they are accumulated in the ActionMailer::Base.deliveries array.
You'll need to set up a staging environment for your application and configure Heroku to use that environment on your staging instance.
Applications that use the Mail gem (including rails >= 3.0 projects) can use the safety_mailer gem. Specify a domain (or set of domains, or magic word in email address) email is allowed to go to, and email to all other domains is silently dropped.
https://github.com/cluesque/safety_mailer
Add the gem to your Gemfile, specifying groups (probably not production) to include it in.
gem "safety_mailer", :group => :development
Don't forget to bundle install to install
In your environment file config/environments/development.rb configure it, and some regular expressions.
config.action_mailer.delivery_method = :safety_mailer
config.action_mailer.safety_mailer_settings = {
allowed_matchers: [ /mydomain.com/, /mytestacct#gmail.com/, /super_secret_test/ ],
delivery_method: :smtp,
delivery_method_settings: {
:address => "smtp.mydomain.com",
:port => 25,
:domain => "mydomain.com",
:authentication => :plain,
:user_name => "mydomain_mailer#mydomain.com",
:password => "password"
}
}
... and now, email to anyone#mydomain.com, mytestacct#gmail.com, bob+super_secret_test#yahoo.com all get sent
and email to other recipients (like the real users in the production database you copied to a test server) is suppressed.
You might be interested in mailtrap.io (disclaimer: I am affiliated with this product). It is a perfect tool to test email deliveries in development and production. All you have to do is set mailtrap.io as an smtp server in your staging environment config:
config.action_mailer.smtp_settings = {
:address => "mailtrap.io",
:port => 2525,
:authentication => :plain,
:user_name => "LOGIN",
:password => "PASSWORD"
}
Having this all your test emails sent in staging env will be stored in mailtrap for view and sharing. But non of them will be sent to the real addresses. You can use it in development as well.
And by way - it's totally free!
put this in your environment.rb file
config.action_mailer.delivery_method = :test
It should stop sending mail to the mail server, I think there is a :log option, but I have not tried it out.
I see people suggest using Mailtrap.io. Good alternative is Debug Mail. Using is quite simple.
We use maildev, which you can install locally. Great for development and staging environments, easy to install in a variety of tech stacks.
Depending on your choices
If you want a convenient way of receiving emails for debugging, etc. I recommend https://github.com/fgrehm/letter_opener_web, which will save emails locally, and provide an URL to browse emails that were sent. No email is sent outside, and you can very conveniently see the output in your browser
If you want to be able to open email files with your email clients, you should choose a :file adapter for ActionMailer (configure in config/environments/your_env.rb)
If you want a real production-like environment, I'd suggest to configure an email interceptor that would rewrite the TO/CC/BCC to a real mailbox of your choice, this way you can keep and test your original ActionMailer adapter
if Rails.env.staging?
class TestEmailsInterceptor
def self.delivering_email(mail)
mail.to = ['My Test Box <test-box#example.com>']
# remove bcc, cc, etc.
end
end
ActionMailer::Base.register_interceptor(TestEmailsInterceptor)
end

Resources