Add kamal-proxy in experimental mode

The proxy can be enabled via the config:

```
proxy:
  enabled: true
  hosts:
    - 10.0.0.1
    - 10.0.0.2
```

This will enable the proxy and cause it to be run on the hosts listed
under `hosts`, after running `kamal proxy reboot`.

Enabling the proxy disables `kamal traefik` commands and replaces them
with `kamal proxy` ones. However only the marked hosts will run the
kamal-proxy container, the rest will run Traefik as before.
This commit is contained in:
Donal McBreen
2024-07-17 16:04:46 +01:00
committed by Donal McBreen
parent 66d5e25834
commit eab717e0cf
27 changed files with 924 additions and 17 deletions

View File

@@ -143,6 +143,12 @@ accessories:
traefik:
...
# Proxy
#
# **Experimental** Configuration for kamal-proxy the replacement for Traefik, see kamal docs proxy
proxy:
...
# SSHKit
#
# See kamal docs sshkit

View File

@@ -0,0 +1,83 @@
# Proxy
#
# **Experimental** [kamal-proxy](http://github.com/basecamp/kamal-proxy) is a
# custom built specifically for Kamal. It will replace Traefik in Kamal v2.0,
# but currently is available as an experimental feature.
#
# When this is enabled, the proxy will be started on the hosts listed under the hosts key.
# In addition, the kamal traefik command will be disabled and replaced by kamal proxy.
#
# The kamal proxy command works identically to kamal traefik on hosts that have not
# been included. It will also handle switching between Traefik and kamal-proxy when you
# run kamal proxy reboot.
# Limitations
#
# Currently the proxy will run on ports 80 and 443 and will bind to those
# ports on the host.
#
# There is no way to set custom options for `docker run` when booting the proxy.
#
# If you have custom Traefik configuration via labels or boot arguments they may
# not have an equivalent in kamal-proxy.
# Proxy settings
#
# The proxy is configured in the root configuration under `traefik`. These are
# options that are set when deploying the application, not when booting the proxy
#
# They are application specific, so are not shared when multiple applications
# with the same proxy.
proxy:
# Enabled
#
# Whether to enable experimental proxy support. Defaults to false
enabled: true
# Hosts
#
# The hosts to run the proxy on, instead of Traefik
# This is a temporary setting and will be removed when we full switch to kamal-proxy
#
# If you run `kamal traefik reboot`, then the proxy will be started on these hosts
# in place of traefik.
hosts:
- 10.0.0.1
- 10.0.0.2
# Host
#
# This is the host that will be used to serve the app. By setting this you can run
# multiple apps on the same server sharing the same instance of the proxy.
#
# If this is set only requests that match this host will be forwarded by the proxy.
# if this is not set, then all requests will be forwarded, except for matching
# requests for other apps that do have a host set.
host: foo.example.com
# Deploy timeout
#
# How long to wait for the app to boot when deploying, defaults to 30 seconds
deploy_timeout: 10s
# Response timeout
#
# How long to wait for requests to complete before timing out, defaults to 30 seconds
response_timeout: 10
# Healthcheck
#
# When deploying, the proxy will by default hit /up once every second until we hit
# the deploy timeout, with a 5 second timeout for each request.
#
# Once the app is up, the proxy will stop hitting the healthcheck endpoint.
healthcheck:
interval: 3
path: /health
timeout: 3
# Max Request Body Size
#
# The maximum request size in bytes that the proxy will accept, defaults to 1GB
max_request_body_size: 40_000_000

View File

@@ -0,0 +1,57 @@
class Kamal::Configuration::Proxy
include Kamal::Configuration::Validation
DEFAULT_HTTP_PORT = 80
DEFAULT_HTTPS_PORT = 443
DEFAULT_IMAGE = "basecamp/kamal-proxy:latest"
delegate :argumentize, :optionize, to: Kamal::Utils
def initialize(config:)
@proxy_config = config.raw_config.proxy || {}
validate! proxy_config
end
def enabled?
!!proxy_config.fetch("enabled", false)
end
def hosts
if enabled?
proxy_config.fetch("hosts", [])
else
[]
end
end
def image
proxy_config.fetch("image", DEFAULT_IMAGE)
end
def container_name
"kamal-proxy"
end
def publish_args
argumentize "--publish", [ "#{DEFAULT_HTTP_PORT}:#{DEFAULT_HTTP_PORT}", "#{DEFAULT_HTTPS_PORT}:#{DEFAULT_HTTPS_PORT}" ]
end
def deploy_options
{
host: proxy_config["host"],
"deploy-timeout": proxy_config["deploy_timeout"],
"drain-timeout": proxy_config["drain_timeout"],
"health-check-interval": proxy_config.dig("health_check", "interval"),
"health-check-timeout": proxy_config.dig("health_check", "timeout"),
"health-check-path": proxy_config.dig("health_check", "path"),
"target-timeout": proxy_config["response_timeout"]
}.compact
end
def deploy_command_args
optionize deploy_options
end
private
attr_accessor :proxy_config
end

View File

@@ -58,10 +58,18 @@ class Kamal::Configuration::Role
default_labels.merge(traefik_labels).merge(custom_labels)
end
def labels_for_proxy
default_labels.merge(custom_labels)
end
def label_args
argumentize "--label", labels
end
def label_args_for_proxy
argumentize "--label", labels_for_proxy
end
def logging_args
logging.args
end