Thin server not loading environment variables with Capistrano - ruby-on-rails

I'm deploying my rails app with capistrano and using the thin server. I have 2 env vars for my mailer username and password defined in ~/.bash_profile with export SMTP_USERNAME=....
When I ssh to the server and try to send emails from the rails console it works fine but it looks like they are not loaded by thin when I run cap deploy or any other command.
What's the correct way to define them? I've seen some posts where they suggest to define them directly in the config/environments/production.rb or in some other file related to the code itself. I was trying to avoid that for security reasons.
UPDATE: I tried to use a yml file to store this but I ran into this problem:
I created a new file email_config.rb in config/initializers. Its content is:
EMAIL_CONFIG = YAML.load_file("#{RAILS_ROOT}/config/email.yml")[RAILS_ENV]
In config/email.yml I have:
production:
username: username
password: password
In my config/environments/production.rb I have:
config.action_mailer.delivery_method = :smtp
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true
config.action_mailer.default :charset => "utf-8"
config.action_mailer.smtp_settings = {
address: "smtp.gmail.com",
port: 587,
authentication: :plain,
enable_starttls_auto: true,
user_name: EMAIL_CONFIG[:username],
password: EMAIL_CONFIG[:password]
}
Now the problem is that initializers are loaded after environments.rb and if I put the definition of the EMAIL_CONFIG variable just before my email configuration, then the RAILS_ROOT variable is not define.

Like you're saying, not a god idea to save a password directly in the production.rb. A better option would be to reference them from shell variables (closer to your current setup) or from a yaml file (what I do personally). You can find more information in this post

Related

devise not sending recover password email

the mail configuration is through smtp.
everything is working ok with localhost in dev mode, devise sends recover password email using smtp conf in development.rb
manual mail sending with action mail is also ok
when in production mode,
only the host is modified to match the host in production machine
the smtp conf is unchanged, and manually sending mail is ok in a rails console
BUT devise does not send recover password mail
how to debug that ?
is Devise really taking on the global mail conf in production.rb ?
there is no Devise::Mailer override.
and this is uncommented in initializer
please share the github page of your project, so we can have a look. Then also share the log of your production server. you can recover it with heroku logs. I did configure this for my apps, eventually it broke down. It is a little bit tricky. I did follow some guide. If you did the same quote the guide you followed. I followed this guide, I remember that I had to allow in my gmail account setting the usage of gmail account from my app. Then there is some settings that you need to do in production.rb, I am quoting the guide, go to that link to see the full guide and check also other guides online:
Setting Up Production Environment
Now you will need to edit the file “config/environments/production.rb”. We will be adding very similar things to this file. First you can add:
config.action_mailer.default_url_options = { :host => 'yoursite.herokuapp.com' }
NOTE: You may also need to add this line. When I was setting up the mailer, I did not find this line in any other tutorials. I had the development mailer working, however I could not get heroku to work. I received this error in the heroku logs:
ActionView::Template::Error: Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true
I found the answer here: ActionView::Template::Error: Missing host to link to on stackoverflow. If you come across this, then add:
Rails.application.routes.default_url_options[:host] = 'yoursite.herokuapp.com'
to your production.rb file.
Next you will have to add in these lines. Once again make sure that you leave the variables as they are.
config.action_mailer.delivery_method = :smtp
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = false
config.action_mailer.default :charset => "utf-8"
config.action_mailer.smtp_settings = {
address: "smtp.gmail.com",
port: 587,
domain: ENV["GMAIL_DOMAIN"],
authentication: "plain",
enable_starttls_auto: true,
user_name: ENV["GMAIL_USERNAME"],
password: ENV["GMAIL_PASSWORD"]
}
read the comments from this post and all the other relevant guides to configure this, you may need to use some smtp api to send the email....

Ruby on Rails 4 with SendGrid - authentication fails , but only on production server on Linode

In my application I have set up sendgrid SMTP service. I am using Figaro gem for setting ENV variables for SMTP configuration.
Everything is fine on development mode - I can send e-mails. But when I deploy to my VPS on Linode, every time when I try to send mail I get:
Net::SMTPAuthenticationError (535 Authentication failed: Bad username / password
On the Rails console of the production server I can verify that ENV["GRID_USER'] and ENV["GRID_PASS"] are correct. The same result I get when I'm checking for Figaro.env.grid_user and Figaro.env.grid_pass (in production mode).
The credentials are correct.
What could be the reason for failing authentication, surprisingly only in production mode?
Here you can see my smtp config in production.rb :
config.action_mailer.smtp_settings = {
address: "smtp.sendgrid.net",
user_name: ENV['GRID_USER'],
password: ['GRID_PASS'],
domain: "why.bio",
port: 587,
authentication: 'plain',
enable_starttls_auto: true
}
Here is the way I declare my credentials in application.yml :
GRID_USER: "MySendGridUserName"
GRID_PASS: "very_wierd_password"
I have checked a hundreds of questions in StackOverflow and a number of blogs, but could not find the solution.
You need to use ENV['GRID_PASS'] and not just ['GRID_PASS'] in your configuration.

how to place SMTP configuration on a separate file?

I'm configuring my app to send emails through gmail smtp, so I'm writing the action_mailer setup in the production.rb file.
Though I don't want to have my gmail credentials written in the production.rb file, which is git versioned.
this is what I have made so far:
in production rb:
require "SmtpData"
config.action_mailer.default_url_options = {:host => 'my server's ip'}
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
enable_starttls_auto: "true",
address: SmtpData::ADDRESS,
port: SmtpData::PORT,
domain: "pjforex.com",
authentication: :plain,
:user_name => SmtpData::USER,
:password => SmtpData::PASS
}
then I created config/initializers/smtp_data.rb containing:
class SmtpData
USER = 'user#gmail.com'
PASS = 'password'
ADDRESS = "smtp.gmail.com"
PORT = "587"
end
But when my capistrano tries to precompile the assets, I get :
rake aborted!
uninitialized constant SmtpData
any clue on how to solve this. or better approach to this issue?
thanks,
You need to store your configuration in a file excluded from Git but shared between deployments. Assuming you are using Capistrano 3, it would be something like this:
1) On your server create a file shared/config/smtp.yml (using YAML is not something crucial, but it's just cleaner for configs) in Capistrano root folder with the following content:
user: user#gmail.com
pass: your_password
address: smtp.gmail.com
port: 587
2) Add this file to your linked_files in config/deploy.rb (ideally, config/database.yml should be stored this way too):
set :linked_files, %w{config/database.yml config/smtp.yml}
3) Read SMTP config in production.rb from config/smtp.yml.
4) You can also have config/smtp.yml locally for your development environment, but don't forget to add it to your .gitignore then.
I believe that production.rb gets loaded before smtp_data.rb, which is why production.rb isn't able to access the class you have defined.
One solution we use, to keep sensitive credentials out of our git versions, is to create (as in your example) production.rb.template and add this to your git repository. This file is pretty much a copy of what you currently have for production.rb, except that you would have placeholders for where credentials should go. For example,
:username => USERNAME GOES HERE
Then, we remove production.rb from the repository (and, optionally, set it to be ignored by git). When you check out your local copy of the repository, you copy production.rb.template as production.rb, and you fill in the credential information. This will only exist in your local deployment and would not be pushed to git.

ActionMailer not sending mail in development Rails 4

Why is this mailer not sending any mail? (Or any ideas for debugging?)
In my_app/config/environments/development.rb I have this code:
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: 'smtp.gmail.com',
port: 587,
domain: 'my_app.com',
user_name: ENV['GMAIL_USERNAME'],
password: ENV['GMAIL_PASSWORD'],
authentication: 'plain',
enable_starttls_auto: true }
Then on my local computer in ~/.bash_profile I have this code:
export GMAIL_USERNAME='blah#my_app.com'
export GMAIL_PASSWORD='***'
When I run $ env in my terminal, I see that both environment variables are correctly set.
I have also restarted my rails server.
You should add
config.action_mailer.perform_deliveries = true
as by default this is on false, preventing mails to be sent from your development environment...
For anyone not using smtp, switching the delivery method to sendmail helped me in addition to explicitly setting deliveries to be performed:
config.action_mailer.delivery_method = :sendmail
If you're having issues sending email from console, you have to call the deliver method on your mail.
MyMailer.create_email.deliver
All of these answers are great, but there is another place where you can get burned, especially in the context of debugging.
In development.rb make sure you set config.action_mailer.raise_delivery_errors = true
If your .deliver method seems to be working without issue, but you never actually receive the email across the wire, your delivery method may be throwing an exception and rails is swallowing the error. This is very true if you simply have something as simple as a misconfigured credentials, or an aws access denied API error. Save ripping your hair out and make sure you have raise_delivery_errors turned on. It wants to tell you something but can't.
So I've figured it out. Having the line ActionMailer::Base.delivery_method = :smtp in config/environment.rb overrides ActionMailer::Base.delivery_method = :test in config/environments/test.rb.
So, delete that line, ActionMailer::Base.delivery_method = :smtp from config/environment.rb and place it in config/environments/production.rb. That allows you to place ActionMailer::Base.delivery_method = :test in config/environments/test.rb and the version you want in config/environments/development.rb. I made development.rb :test as I populated my database using Faker and changed it to :smtp so I was sure that real emails were sent as an additional check.
Note: You must restart your server for these changes to take effect.
Another note: Heroku's current SendGrid Instructions (https://devcenter.heroku.com/articles/sendgrid) put the SendGrid Heroku configuration code in a new config/initializers/mail.rb file which will likely require removing its last line and placing the desired version in each config/environments/[production.rb, development.rb, test.rb]

Why am I unable to send an email with pow?

I have a rails project which sends an email using an ActionMailer. This seems to work fine with 'rails server' on localhost:3000 but when I use pow, I get authentication error messages from the smtp server. I'm guessing this has something to do with environment variables. Here is the config code
config.action_mailer.smtp_settings = {
address: "smtp.gmail.com",
port: 587,
domain: "railscasts.com",
authentication: "plain",
enable_starttls_auto: true,
user_name: ENV["GMAIL_USERNAME"],
password: ENV["GMAIL_PASSWORD"]
}
I'm on Mountain Lion.
Thanks
I have a different suggestion:
In dev, just use letter_opener. It's more useful in that context than actually sending emails, anyway.
In production, use SendGrid and not GMail. SendGrid is awesome and really easy to set up.
Pow loads environment variables from checking two files in the application root
.powrc
.powenv
I created the .powrc file using the touch command, then added my environment variables
export GMAIL_USERNAME=username
export GMAIL_PASSWORD="my password"
I then restarted the worker for the app this way:
touch tmp/restart.txt
E-mails now work!
As blamattina has suggested, it may have something to do with your domain in your configuration file! According to the example given by Ruby on Rails Guides:
The correct, Gmail compatible configuration looks like this:
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:domain => 'baci.lindsaar.net',
:user_name => '<username>',
:password => '<password>',
:authentication => 'plain',
:enable_starttls_auto => true }
Your domain is set to railscasts.com. Unless that's your website, my guess is that this domain is not correct. In fact, it is apparently optional as well.
This StackOverflow details that a plugin was once necessary, but is no longer needed if you're using Rails 3.2 or higher. A comment below the top answer in the article details that the domain is optional.
Update: Based on the error you described, it looks like you're hitting an authentication error! This may be because of your login credentials not properly registering.
This user is asking in the context of using Heroku, but the error is the same. If your app works properly with the Rails server, but not on Pow, it's a server-side setup issue. The solution involves needing to properly set your ENV (environment) variables to work with your server.

Resources