From 28d6a131a977810fa83ada78a0c83ff8b5e6dcbc Mon Sep 17 00:00:00 2001 From: Donal McBreen Date: Wed, 31 May 2023 16:17:15 +0100 Subject: [PATCH] Prefix container hostname with the underlying one To make it easier to identity where a docker container is running, prefix its hostname with the underlying one from the host. Docker chooses a 12 character random hex string by default, so we'll keep that as the suffix. --- lib/mrsk/cli/app.rb | 2 +- lib/mrsk/commands/app.rb | 7 ++++--- test/cli/app_test.rb | 4 ++-- test/commands/app_test.rb | 18 ++++++++++++++++++ 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/lib/mrsk/cli/app.rb b/lib/mrsk/cli/app.rb index accfddae..cc4a4cf4 100644 --- a/lib/mrsk/cli/app.rb +++ b/lib/mrsk/cli/app.rb @@ -29,7 +29,7 @@ class Mrsk::Cli::App < Mrsk::Cli::Base execute *auditor.record("Booted app version #{version}"), verbosity: :debug old_version = capture_with_info(*app.current_running_version, raise_on_non_zero_exit: false).strip - execute *app.start_or_run + execute *app.start_or_run(hostname: "#{host}-#{SecureRandom.hex(6)}") Mrsk::Utils::HealthcheckPoller.wait_for_healthy(pause_after_ready: true) { capture_with_info(*app.status(version: version)) } diff --git a/lib/mrsk/commands/app.rb b/lib/mrsk/commands/app.rb index 0e92b8f0..339aa2fc 100644 --- a/lib/mrsk/commands/app.rb +++ b/lib/mrsk/commands/app.rb @@ -8,17 +8,18 @@ class Mrsk::Commands::App < Mrsk::Commands::Base @role = role end - def start_or_run - combine start, run, by: "||" + def start_or_run(hostname: nil) + combine start, run(hostname: hostname), by: "||" end - def run + def run(hostname: nil) role = config.role(self.role) docker :run, "--detach", "--restart unless-stopped", "--name", container_name, + *(["--hostname", hostname] if hostname), "-e", "MRSK_CONTAINER_NAME=\"#{container_name}\"", *role.env_args, *role.health_check_args, diff --git a/test/cli/app_test.rb b/test/cli/app_test.rb index 5e06bd27..ecc96d49 100644 --- a/test/cli/app_test.rb +++ b/test/cli/app_test.rb @@ -5,7 +5,7 @@ class CliAppTest < CliTestCase stub_running run_command("boot").tap do |output| assert_match "docker tag dhh/app:latest dhh/app:latest", output - assert_match "docker run --detach --restart unless-stopped", output + assert_match /docker run --detach --restart unless-stopped --name app-web-latest --hostname 1.1.1.1-[0-9a-f]{12} /, output assert_match "docker container ls --all --filter name=^app-web-123$ --quiet | xargs docker stop", output end end @@ -28,7 +28,7 @@ class CliAppTest < CliTestCase run_command("boot").tap do |output| 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", output + assert_match /docker run --detach --restart unless-stopped --name app-web-latest --hostname 1.1.1.1-[0-9a-f]{12} /, output assert_match "docker container ls --all --filter name=^app-web-123$ --quiet | xargs docker stop", output end ensure diff --git a/test/commands/app_test.rb b/test/commands/app_test.rb index 820f45d3..93bf841b 100644 --- a/test/commands/app_test.rb +++ b/test/commands/app_test.rb @@ -17,6 +17,12 @@ class CommandsAppTest < ActiveSupport::TestCase new_command.run.join(" ") end + test "run with hostname" do + assert_equal \ + "docker run --detach --restart unless-stopped --name app-web-999 --hostname myhost -e MRSK_CONTAINER_NAME=\"app-web-999\" -e RAILS_MASTER_KEY=\"456\" --health-cmd \"curl -f http://localhost:3000/up || exit 1\" --health-interval \"1s\" --log-opt max-size=\"10m\" --label service=\"app\" --label role=\"web\" --label traefik.http.services.app-web.loadbalancer.server.scheme=\"http\" --label traefik.http.routers.app-web.rule=\"PathPrefix(\\`/\\`)\" --label traefik.http.middlewares.app-web-retry.retry.attempts=\"5\" --label traefik.http.middlewares.app-web-retry.retry.initialinterval=\"500ms\" --label traefik.http.routers.app-web.middlewares=\"app-web-retry@docker\" dhh/app:999", + new_command.run(hostname: "myhost").join(" ") + end + test "run with volumes" do @config[:volumes] = ["/local/path:/container/path" ] @@ -77,6 +83,18 @@ class CommandsAppTest < ActiveSupport::TestCase new_command.start.join(" ") end + test "start_or_run" do + assert_equal \ + "docker start app-web-999 || docker run --detach --restart unless-stopped --name app-web-999 -e MRSK_CONTAINER_NAME=\"app-web-999\" -e RAILS_MASTER_KEY=\"456\" --health-cmd \"curl -f http://localhost:3000/up || exit 1\" --health-interval \"1s\" --log-opt max-size=\"10m\" --label service=\"app\" --label role=\"web\" --label traefik.http.services.app-web.loadbalancer.server.scheme=\"http\" --label traefik.http.routers.app-web.rule=\"PathPrefix(\\`/\\`)\" --label traefik.http.middlewares.app-web-retry.retry.attempts=\"5\" --label traefik.http.middlewares.app-web-retry.retry.initialinterval=\"500ms\" --label traefik.http.routers.app-web.middlewares=\"app-web-retry@docker\" dhh/app:999", + new_command.start_or_run.join(" ") + end + + test "start_or_run with hostname" do + assert_equal \ + "docker start app-web-999 || docker run --detach --restart unless-stopped --name app-web-999 --hostname myhost -e MRSK_CONTAINER_NAME=\"app-web-999\" -e RAILS_MASTER_KEY=\"456\" --health-cmd \"curl -f http://localhost:3000/up || exit 1\" --health-interval \"1s\" --log-opt max-size=\"10m\" --label service=\"app\" --label role=\"web\" --label traefik.http.services.app-web.loadbalancer.server.scheme=\"http\" --label traefik.http.routers.app-web.rule=\"PathPrefix(\\`/\\`)\" --label traefik.http.middlewares.app-web-retry.retry.attempts=\"5\" --label traefik.http.middlewares.app-web-retry.retry.initialinterval=\"500ms\" --label traefik.http.routers.app-web.middlewares=\"app-web-retry@docker\" dhh/app:999", + new_command.start_or_run(hostname: "myhost").join(" ") + end + test "stop" do assert_equal \ "docker ps --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting --latest | xargs docker stop",