😈

RailsのActionMailerでsmtp_settingsが反映されない

2024/05/25に公開

概要

dockerでsmtpサーバーを立ててRailsのアプリが立ち上がってるコンテナからメールを送信しようとしたところ下記のエラーで送信できませんでした。

Errno::ECONNREFUSED: Connection refused - connect(2) for "localhost" port 25
from /home/admin/.rbenv/versions/3.2.3/lib/ruby/gems/3.2.0/gems/net-smtp-0.4.0/lib/net/smtp.rb:631:in `initialize'

smtpは172.25.0.4で立ち上げてたので設定はこんな感じです。

config.action_mailer.perform_caching = false
config.action_mailer.delivery_method = ENV.fetch('MAIL_DELIVERY_METHOD', :sendmail)
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true
config.action_mailer.smtp_settings = {
  address: '172.25.0.4',
  port: 25,
  enable_starttls_auto: false,
  openssl_verify_mode: OpenSSL::SSL::VERIFY_NONE
}

smtp_settingsで指定した値が無視されます。Rails.configuration.action_mailerを覗いてみるとしっかり設定されてるのが確認できます。

Rails.configuration.action_mailer
=> {:preview_paths=>["/home/admin/book-keeper/test/mailers/previews", "/home/admin/book-keeper/spec/mailers/previews"],
 :deliver_later_queue_name=>nil,
 :smtp_settings=>{:address=>"172.25.0.4", :port=>25, :enable_starttls_auto=>false, :openssl_verify_mode=>0, :open_timeout=>5, :read_timeout=>5},
 :raise_delivery_errors=>true,
 :perform_caching=>false,
 :delivery_method=>"smtp",
 :perform_deliveries=>true,
 :default_url_options=>{:host=>"localhost:3000"},
 :show_previews=>true,
 :preview_path=>"/home/admin/book-keeper/spec/mailers/previews",
 :assets_dir=>"/home/admin/book-keeper/public",
 :javascripts_dir=>"/home/admin/book-keeper/public/javascripts",
 :stylesheets_dir=>"/home/admin/book-keeper/public/stylesheets",
 :cache_store=>#<ActiveSupport::Cache::NullStore options={:compress=>true, :compress_threshold=>1024}>,
 :asset_host=>nil,
 :relative_url_root=>nil}

このアプリをdockerで構築するのは初めてだったので環境はエラーを見るためにdevelopmentで起動。bin/rails serverで起動するローカル開発環境と動作を分けるためdelivery_methodは環境変数から取っていました。

これが問題でした。

修正

config.action_mailer.delivery_method = ENV.fetch('MAIL_DELIVERY_METHOD', :sendmail).to_sym

delivery_methodはシンボルじゃないでいけません。確かにドキュメントにはシンボルで4種類の値が列挙してあるのですが、不正な値が与えられるとdelivery_methodだけでなくsmtp_settingsもデフォルトの値が採用されるようです。

解説(愚痴)

Railsのバージョンは7.1.1です。

ちょっとひどい仕様ですね。本来であれば不正な値が与えられたら例外にすべきかと。Rails.configuration.action_mailerに値が反映されてるのも混乱を招きます。3時間くらい溶けたかな。delivery_methodを環境変数から取るシチュエーションは少なそうなのでこの問題に遭遇する人は少ないのかもしれませんが。

そういえば最初にconfig.action_mailer.delivery_method = ENV.fetch('MAIL_DELIVERY_METHOD', :sendmail)を書いた時にGithub Copilotto_symとサジェストしたんですよね。その時は軽く流しちゃったんですけど、惜しかった。まあ、どちらにしてもサラッとデフォルト値使うのはやめて欲しいですが。

時間ができたらPR出してみようかとも思ってますが、破壊的変更になるので難しいかな。

皆んな大好きStackOverFlowで見つけました。エラーメッセージで最初に検索すえればよかった。なんかそこじゃない気がしちゃったんですよね。

https://stackoverflow.com/questions/31009419/connection-refused-connect2-for-localhost-port-25-rails

Discussion