From 6f2eaed398654096f2d4a9c36d843f3af0742212 Mon Sep 17 00:00:00 2001 From: Donal McBreen Date: Tue, 10 Sep 2024 17:47:38 +0100 Subject: [PATCH] Work out the host and port for the container Avoid docker inspect: 1. Use the container ID as the host 2. Configure the port, default to 3000 --- lib/kamal/cli/app.rb | 4 ++-- lib/kamal/cli/app/boot.rb | 2 +- lib/kamal/cli/proxy.rb | 2 +- lib/kamal/commands/app/containers.rb | 7 ------- lib/kamal/commands/proxy.rb | 6 +++--- lib/kamal/configuration/docs/proxy.yml | 6 ++++++ lib/kamal/configuration/proxy.rb | 4 ++++ test/cli/app_test.rb | 2 +- test/cli/proxy_test.rb | 10 +++++----- test/commands/proxy_test.rb | 8 ++++---- .../docker/deployer/app_with_roles/config/deploy.yml | 1 + 11 files changed, 28 insertions(+), 24 deletions(-) diff --git a/lib/kamal/cli/app.rb b/lib/kamal/cli/app.rb index 732addae..aaa8cd50 100644 --- a/lib/kamal/cli/app.rb +++ b/lib/kamal/cli/app.rb @@ -44,7 +44,7 @@ class Kamal::Cli::App < Kamal::Cli::Base if role.running_traefik? && KAMAL.proxy_host?(host) version = capture_with_info(*app.current_running_version, raise_on_non_zero_exit: false).strip - endpoint = capture_with_info(*app.container_endpoint(version: version)).strip + endpoint = capture_with_info(*app.container_id_for_version(version)).strip raise Kamal::Cli::BootError, "Failed to get endpoint for #{role} on #{host}, did the container boot?" if endpoint.empty? execute *KAMAL.proxy.deploy(role.container_prefix, target: endpoint) @@ -66,7 +66,7 @@ class Kamal::Cli::App < Kamal::Cli::Base if role.running_traefik? && KAMAL.proxy_host?(host) version = capture_with_info(*app.current_running_version, raise_on_non_zero_exit: false).strip - endpoint = capture_with_info(*app.container_endpoint(version: version)).strip + endpoint = capture_with_info(*app.container_id_for_version(version)).strip if endpoint.present? execute *KAMAL.proxy.remove(role.container_prefix, target: endpoint), raise_on_non_zero_exit: false end diff --git a/lib/kamal/cli/app/boot.rb b/lib/kamal/cli/app/boot.rb index b6a09477..00e0fb73 100644 --- a/lib/kamal/cli/app/boot.rb +++ b/lib/kamal/cli/app/boot.rb @@ -53,7 +53,7 @@ class Kamal::Cli::App::Boot if proxy_host? execute *app.run_for_proxy(hostname: hostname) if running_traefik? - endpoint = capture_with_info(*app.container_endpoint(version: version)).strip + endpoint = capture_with_info(*app.container_id_for_version(version)).strip raise Kamal::Cli::BootError, "Failed to get endpoint for #{role} on #{host}, did the container boot?" if endpoint.empty? execute *KAMAL.proxy.deploy(role.container_prefix, target: endpoint) else diff --git a/lib/kamal/cli/proxy.rb b/lib/kamal/cli/proxy.rb index 81b734f7..b0bb33a4 100644 --- a/lib/kamal/cli/proxy.rb +++ b/lib/kamal/cli/proxy.rb @@ -52,7 +52,7 @@ class Kamal::Cli::Proxy < Kamal::Cli::Base app = KAMAL.app(role: role, host: host) version = capture_with_info(*app.current_running_version, raise_on_non_zero_exit: false).strip - endpoint = capture_with_info(*app.container_endpoint(version: version)).strip + endpoint = capture_with_info(*app.container_id_for_version(version)).strip if endpoint.present? info "Deploying #{endpoint} for role `#{role}` on #{host}..." diff --git a/lib/kamal/commands/app/containers.rb b/lib/kamal/commands/app/containers.rb index 2d828962..0bab388b 100644 --- a/lib/kamal/commands/app/containers.rb +++ b/lib/kamal/commands/app/containers.rb @@ -28,11 +28,4 @@ module Kamal::Commands::App::Containers container_id_for(container_name: container_name(version)), xargs(docker(:inspect, "--format", DOCKER_HEALTH_LOG_FORMAT)) end - - def container_endpoint(version:) - pipe \ - container_id_for(container_name: container_name(version)), - xargs(docker(:inspect, "--format", "'{{index .NetworkSettings.Networks.kamal.Aliases 0}}{{range $k, $v := .NetworkSettings.Ports}}{{printf \":%s\" $k}}{{break}}{{end}}'")), - [ :sed, "-e", "'s/\\/tcp$//'" ] - end end diff --git a/lib/kamal/commands/proxy.rb b/lib/kamal/commands/proxy.rb index 3a17afae..b50cd0f2 100644 --- a/lib/kamal/commands/proxy.rb +++ b/lib/kamal/commands/proxy.rb @@ -1,6 +1,6 @@ class Kamal::Commands::Proxy < Kamal::Commands::Base delegate :argumentize, :optionize, to: Kamal::Utils - delegate :container_name, to: :proxy_config + delegate :container_name, :port, to: :proxy_config attr_reader :proxy_config @@ -35,11 +35,11 @@ class Kamal::Commands::Proxy < Kamal::Commands::Base end def deploy(service, target:) - docker :exec, container_name, "kamal-proxy", :deploy, service, *optionize({ target: target }), *proxy_config.deploy_command_args + docker :exec, container_name, "kamal-proxy", :deploy, service, *optionize({ target: "#{target}:#{port}" }), *proxy_config.deploy_command_args end def remove(service, target:) - docker :exec, container_name, "kamal-proxy", :remove, service, *optionize({ target: target }) + docker :exec, container_name, "kamal-proxy", :remove, service, *optionize({ target: "#{target}:#{port}" }) end def info diff --git a/lib/kamal/configuration/docs/proxy.yml b/lib/kamal/configuration/docs/proxy.yml index 2d101aef..c30117fb 100644 --- a/lib/kamal/configuration/docs/proxy.yml +++ b/lib/kamal/configuration/docs/proxy.yml @@ -56,6 +56,12 @@ proxy: # requests for other apps that do have a host set. host: foo.example.com + # Port + # + # The port the application is exposed on + # Defaults to 80 + port: 3000 + # SSL # # Kamal Proxy can automatically obtain and renew TLS certificates for your applications. diff --git a/lib/kamal/configuration/proxy.rb b/lib/kamal/configuration/proxy.rb index 69b79be7..db3dcd96 100644 --- a/lib/kamal/configuration/proxy.rb +++ b/lib/kamal/configuration/proxy.rb @@ -25,6 +25,10 @@ class Kamal::Configuration::Proxy end end + def port + proxy_config.fetch("port", 80) + end + def image proxy_config.fetch("image", DEFAULT_IMAGE) end diff --git a/test/cli/app_test.rb b/test/cli/app_test.rb index 225bf21d..17ae3deb 100644 --- a/test/cli/app_test.rb +++ b/test/cli/app_test.rb @@ -363,7 +363,7 @@ class CliAppTest < CliTestCase assert_match /Renaming container .* to .* as already deployed on 1.1.1.1/, output # Rename assert_match /docker rename app-web-latest app-web-latest_replaced_[0-9a-f]{16}/, output assert_match /docker run --detach --restart unless-stopped --name app-web-latest --network kamal --hostname 1.1.1.1-[0-9a-f]{12} -e KAMAL_CONTAINER_NAME="app-web-latest" -e KAMAL_VERSION="latest" --env-file .kamal\/env\/roles\/app-web.env --log-opt max-size="10m" --label service="app" --label role="web" --label destination dhh\/app:latest/, output - assert_match /docker exec kamal-proxy kamal-proxy deploy app-web --target "123"/, output + assert_match /docker exec kamal-proxy kamal-proxy deploy app-web --target "123:3000"/, output assert_match "docker container ls --all --filter name=^app-web-123$ --quiet | xargs docker stop", output end end diff --git a/test/cli/proxy_test.rb b/test/cli/proxy_test.rb index e35c3c06..3d65207c 100644 --- a/test/cli/proxy_test.rb +++ b/test/cli/proxy_test.rb @@ -10,8 +10,8 @@ class CliProxyTest < CliTestCase test "reboot" do SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info) - .with(:docker, :container, :ls, "--all", "--filter", "name=^app-web-123$", "--quiet", "|", :xargs, :docker, :inspect, "--format", "'{{index .NetworkSettings.Networks.kamal.Aliases 0}}{{range $k, $v := .NetworkSettings.Ports}}{{printf \":%s\" $k}}{{break}}{{end}}'", "|", :sed, "-e", "'s/\\/tcp$//'") - .returns("172.1.0.2:80") + .with(:docker, :container, :ls, "--all", "--filter", "name=^app-web-123$", "--quiet") + .returns("abcdefabcdef") .at_least_once SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info) @@ -25,7 +25,7 @@ class CliProxyTest < CliTestCase assert_match "docker container prune --force --filter label=org.opencontainers.image.title=kamal-proxy on 1.1.1.1", output assert_match "docker container prune --force --filter label=org.opencontainers.image.title=Traefik on 1.1.1.1", output assert_match "docker run --name kamal-proxy --network kamal --detach --restart unless-stopped --publish 80:80 --publish 443:443 --volume /var/run/docker.sock:/var/run/docker.sock --volume kamal-proxy:/root/.config/kamal-proxy --log-opt max-size=\"10m\" #{Kamal::Configuration::Proxy::DEFAULT_IMAGE} on 1.1.1.1", output - assert_match "docker exec kamal-proxy kamal-proxy deploy app-web --target \"172.1.0.2:80\" --deploy-timeout \"6s\" --buffer-requests --buffer-responses --log-request-header \"Cache-Control\" --log-request-header \"Last-Modified\" on 1.1.1.1", output + assert_match "docker exec kamal-proxy kamal-proxy deploy app-web --target \"abcdefabcdef:3000\" --deploy-timeout \"6s\" --buffer-requests --buffer-responses --log-request-header \"Cache-Control\" --log-request-header \"Last-Modified\" on 1.1.1.1", output assert_match "docker container stop kamal-proxy on 1.1.1.2", output assert_match "docker container stop traefik on 1.1.1.2", output @@ -37,8 +37,8 @@ class CliProxyTest < CliTestCase test "reboot --rolling" do SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info) - .with(:docker, :container, :ls, "--all", "--filter", "name=^app-web-123$", "--quiet", "|", :xargs, :docker, :inspect, "--format", "'{{index .NetworkSettings.Networks.kamal.Aliases 0}}{{range $k, $v := .NetworkSettings.Ports}}{{printf \":%s\" $k}}{{break}}{{end}}'", "|", :sed, "-e", "'s/\\/tcp$//'") - .returns("172.1.0.2:80") + .with(:docker, :container, :ls, "--all", "--filter", "name=^app-web-123$", "--quiet") + .returns("abcdefabcdef") .at_least_once SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info) diff --git a/test/commands/proxy_test.rb b/test/commands/proxy_test.rb index 0a2cc6c0..71bb4f1c 100644 --- a/test/commands/proxy_test.rb +++ b/test/commands/proxy_test.rb @@ -109,14 +109,14 @@ class CommandsProxyTest < ActiveSupport::TestCase test "deploy" do assert_equal \ - "docker exec kamal-proxy kamal-proxy deploy service --target \"172.1.0.2:80\" --buffer-requests --buffer-responses --log-request-header \"Cache-Control\" --log-request-header \"Last-Modified\"", - new_command.deploy("service", target: "172.1.0.2:80").join(" ") + "docker exec kamal-proxy kamal-proxy deploy service --target \"172.1.0.2:3000\" --buffer-requests --buffer-responses --log-request-header \"Cache-Control\" --log-request-header \"Last-Modified\"", + new_command.deploy("service", target: "172.1.0.2").join(" ") end test "remove" do assert_equal \ - "docker exec kamal-proxy kamal-proxy remove service --target \"172.1.0.2:80\"", - new_command.remove("service", target: "172.1.0.2:80").join(" ") + "docker exec kamal-proxy kamal-proxy remove service --target \"172.1.0.2:3000\"", + new_command.remove("service", target: "172.1.0.2").join(" ") end private diff --git a/test/integration/docker/deployer/app_with_roles/config/deploy.yml b/test/integration/docker/deployer/app_with_roles/config/deploy.yml index c15af55b..2f5c6fc3 100644 --- a/test/integration/docker/deployer/app_with_roles/config/deploy.yml +++ b/test/integration/docker/deployer/app_with_roles/config/deploy.yml @@ -13,6 +13,7 @@ proxy: enabled: true hosts: - vm2 + port: 80 deploy_timeout: 2s asset_path: /usr/share/nginx/html/versions