Configure email in rails app (deployed with kamal)

20 Mars 2024

Last week, I took the time to fix a bug related to email sending in one of my apps. Not being able to send emails from an app quickly becomes problematic.

After spending a considerable amount of time grumbling about SPF and DKIM, testing different configurations, locally and in production, I found the root of the problem... Let me explain.

Kamal was creating a deploy.yml file containing the environment variables that need to be passed to the container during deployment.

Before the correction:

# Inject ENV variables into containers (secrets come from .env).
# Remember to run 'kamal env push' after making changes!
env:
  clear:
    DB_HOST: 128.0.0.1
    RAILS_SERVE_STATIC_FILES: true
  secret:
    - RAILS_MASTER_KEY
    - POSTGRES_PASSWORD

In my case, I had properly initialized the file with the basic variables, but I did not update the new ones regarding the email configurations, thus preventing production from authenticating during email sending.

deploy.yml after modification:

# Inject ENV variables into containers (secrets come from .env).
# Remember to run 'kamal env push' after making changes!
env:
  clear:
    DB_HOST: 128.0.0.1
    RAILS_SERVE_STATIC_FILES: true
  secret:
    - RAILS_MASTER_KEY
    - POSTGRES_PASSWORD
    - EMAIL_USER_NAME
    - EMAIL_PASSWORD

From this point, the error was corrected. As a reminder, to configure the mail account, add the following to production.rb:

config.action_mailer.default_url_options = { host: 'example.com' }
config.action_mailer.perform_deliveries = true
config.action_mailer.delivery_method = :smtp

config.action_mailer.smtp_settings = {
  address:             'smtp.gmail.com', # modify if other than Gmail
  domain:              'example.com',
  port:                587,
  user_name:           ENV['EMAIL_USER_NAME'],
  password:            ENV['EMAIL_PASSWORD'],
  authentication:      'plain',
  enable_starttls_auto: true,
}

And there you go! Now it's time to test.