diff --git a/lib/kamal/configuration/docs/proxy.yml b/lib/kamal/configuration/docs/proxy.yml index 9b09704b1..ecd7607a6 100644 --- a/lib/kamal/configuration/docs/proxy.yml +++ b/lib/kamal/configuration/docs/proxy.yml @@ -114,10 +114,16 @@ proxy: # the deploy timeout, with a 5-second timeout for each request. # # Once the app is up, the proxy will stop hitting the healthcheck endpoint. + # + # The `host` option allows setting a custom Host header for health check requests. + # This is useful when your application validates the Host header (e.g., Django's + # ALLOWED_HOSTS, Rails host authorization). Without this, health checks using + # internal IPs may be rejected even when the application is healthy. healthcheck: interval: 3 path: /health timeout: 3 + host: example.com # Buffering # diff --git a/lib/kamal/configuration/proxy.rb b/lib/kamal/configuration/proxy.rb index 7ccbfb3a4..dccc67bb0 100644 --- a/lib/kamal/configuration/proxy.rb +++ b/lib/kamal/configuration/proxy.rb @@ -78,6 +78,7 @@ def deploy_options "health-check-interval": seconds_duration(proxy_config.dig("healthcheck", "interval")), "health-check-timeout": seconds_duration(proxy_config.dig("healthcheck", "timeout")), "health-check-path": proxy_config.dig("healthcheck", "path"), + "health-check-host": proxy_config.dig("healthcheck", "host"), "target-timeout": seconds_duration(proxy_config["response_timeout"]), "buffer-requests": proxy_config.fetch("buffering", { "requests": true }).fetch("requests", true), "buffer-responses": proxy_config.fetch("buffering", { "responses": true }).fetch("responses", true), diff --git a/test/configuration/proxy_test.rb b/test/configuration/proxy_test.rb index e0b328f3b..13ddaf896 100644 --- a/test/configuration/proxy_test.rb +++ b/test/configuration/proxy_test.rb @@ -105,6 +105,35 @@ class ConfigurationProxyTest < ActiveSupport::TestCase end end + test "health check host in deploy options" do + @deploy[:proxy] = { + "host" => "example.com", + "healthcheck" => { + "path" => "/up", + "host" => "example.com" + } + } + + proxy = config.proxy + options = proxy.deploy_options + assert_equal "example.com", options[:"health-check-host"] + assert_equal "/up", options[:"health-check-path"] + end + + test "health check without custom host" do + @deploy[:proxy] = { + "host" => "example.com", + "healthcheck" => { + "path" => "/up" + } + } + + proxy = config.proxy + options = proxy.deploy_options + assert_nil options[:"health-check-host"] + assert_equal "/up", options[:"health-check-path"] + end + private def config Kamal::Configuration.new(@deploy)