しかしブラウザは、その app を Docker 内部の名前としてではなく、通常のホスト名として扱います。
app や dev は実在の TLD であり、しかも HSTS(HTTP Strict Transport Security)を強制する対象なので、ブラウザは http://app/ を https://app/ に書き換えます。
接続先が HTTPS 非対応なら、結果として ERR_SSL_PROTOCOL_ERROR や Are you trying to open an SSL connection to a non-SSL Puma? のようなエラーになります。
2026-03-25 05:37:53 +0000 HTTP parse error, malformed request: #<Puma::HttpParserError: Invalid HTTP format, parsing fails. Are you trying to open an SSL connection to a non-SSL Puma?>
[Screenshot Image]: /x/tmp/screenshots/failures_test_should_destroy_Article.png
E
Error:
ArticlesTest#test_should_destroy_Article:
Selenium::WebDriver::Error::UnknownError: unknown error: net::ERR_SSL_PROTOCOL_ERROR
(Session info: chrome=145.0.7632.109)
test/system/articles_test.rb:38:in 'block in <class:ArticlesTest>'
要点
Docker Compose の
compose.yamlでサービス名を付ける際は、HTTP での接続先となるコンテナのサービス名にはappやdevといったトップレベルドメイン(TLD)として実在する文字列を使わないほうが安全です。具体的な対策
HTTP で接続するサービス(コンテナ)には、ハイフン(
-)を用いて複数の単語を組み合わせた名前をつけるのが、簡単な解決策です。app,devrails-app,web-serverなぜエラーになるのか
Docker Compose のネットワーク内では、サービス名で名前解決をして他コンテナへアクセスできます。そのため、Selenium コンテナ内のブラウザから
http://app/のようにアクセスする設定にすることがあります。しかしブラウザは、その
appを Docker 内部の名前としてではなく、通常のホスト名として扱います。appやdevは実在の TLD であり、しかも HSTS(HTTP Strict Transport Security)を強制する対象なので、ブラウザはhttp://app/をhttps://app/に書き換えます。 接続先が HTTPS 非対応なら、結果としてERR_SSL_PROTOCOL_ERRORやAre you trying to open an SSL connection to a non-SSL Puma?のようなエラーになります。一方、
rails-appのように、TLD と一致しない名前にすれば、HSTS 強制の対象から外れ、HTTPS に書き換えられないため、エラーを防ぐことができます。背景:何が起きているか
Docker の
compose.yamlのservicesで定義したサービス名は、Docker ネットワーク内で他コンテナへアクセスする際のホスト名として使えます。ここでのホスト名とは、http://example.com/のexample.comに当たります。サービス名にドット(
.)が含まれていない場合、単一ラベルのホスト名となり、ブラウザはその名前を TLD として扱います。例えば、appというサービス名は、appという TLD のみからなるホスト名として認識されます。TLD のみのホスト名のうち、
appやdevは HSTS 強制の対象となっており、HSTS プレロードリストなどの仕組みにより、HTTPS 接続が強制されます。そのため、http://app/という HTTP での接続になるよう設定しても、ブラウザは強制的にhttps://app/という HTTPS での接続へと書き換えて接続しようとします。結果、
appやdevのような HSTS が強制される名前を持つサービス(コンテナ)に対して、Selenium コンテナ内のブラウザは、HTTP で接続するよう設定されていても、HTTPS で接続してしまいます。 さらに、接続される側のコンテナが HTTPS に対応していない場合、接続がエラーとなります。このように、E2E テストやシステムテストでは「ブラウザがどう解釈するか」は無視できない事項です。 コンテナ間疎通の都合だけで名前を決めるのではなく、ブラウザが特殊な扱いをする名前ではないか、という観点も持っておくとトラブルを減らせます。
注意点
http://app:3000/のような URL でもエラーになり得ます。facebook.comやwww.amazon.comといったドットを含むホスト名も多数存在するためです。接続エラーに遭遇した状況
compose.yamlにおいて、selenium/standalone-chromiumイメージの Selenium コンテナからサービス名がappのコンテナへ HTTP で接続する設定をしたところ、以下のエラーが発生しました。なお、サービス名を
appからrails-appに変更したところ、無事意図したとおりに動くようになりました。 HSTS 強制の対象となる TLD(app)との一致を回避した結果、ブラウザが HTTPS へ強制的に書き換えなくなったためと考えられます。参考資料