Merge pull request #196 from handy-la/main
Configurable max_attempts for healthcheck
This commit is contained in:
@@ -646,18 +646,21 @@ That'll post a line like follows to a preconfigured chatbot in Basecamp:
|
|||||||
[My App] [dhh] Rolled back to version d264c4e92470ad1bd18590f04466787262f605de
|
[My App] [dhh] Rolled back to version d264c4e92470ad1bd18590f04466787262f605de
|
||||||
```
|
```
|
||||||
|
|
||||||
### Using custom healthcheck path or port
|
### Custom healthcheck
|
||||||
|
|
||||||
MRSK defaults to checking the health of your application again `/up` on port 3000. You can tailor both with the `healthcheck` setting:
|
MRSK defaults to checking the health of your application again `/up` on port 3000 up to 7 times. You can tailor the behaviour with the `healthcheck` setting:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
healthcheck:
|
healthcheck:
|
||||||
path: /healthz
|
path: /healthz
|
||||||
port: 4000
|
port: 4000
|
||||||
|
max_attempts: 7
|
||||||
```
|
```
|
||||||
|
|
||||||
This will ensure your application is configured with a traefik label for the healthcheck against `/healthz` and that the pre-deploy healthcheck that MRSK performs is done against the same path on port 4000.
|
This will ensure your application is configured with a traefik label for the healthcheck against `/healthz` and that the pre-deploy healthcheck that MRSK performs is done against the same path on port 4000.
|
||||||
|
|
||||||
|
The healthcheck also allows for an optional `max_attempts` setting, which will attempt the healthcheck up to the specified number of times before failing the deploy. This is useful for applications that take a while to start up. The default is 7.
|
||||||
|
|
||||||
## Commands
|
## Commands
|
||||||
|
|
||||||
### Running commands on servers
|
### Running commands on servers
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
class Mrsk::Cli::Healthcheck < Mrsk::Cli::Base
|
class Mrsk::Cli::Healthcheck < Mrsk::Cli::Base
|
||||||
MAX_ATTEMPTS = 7
|
|
||||||
|
|
||||||
class HealthcheckError < StandardError; end
|
class HealthcheckError < StandardError; end
|
||||||
|
|
||||||
@@ -13,6 +12,7 @@ class Mrsk::Cli::Healthcheck < Mrsk::Cli::Base
|
|||||||
|
|
||||||
target = "Health check against #{MRSK.config.healthcheck["path"]}"
|
target = "Health check against #{MRSK.config.healthcheck["path"]}"
|
||||||
attempt = 1
|
attempt = 1
|
||||||
|
max_attempts = MRSK.config.healthcheck["max_attempts"]
|
||||||
|
|
||||||
begin
|
begin
|
||||||
status = capture_with_info(*MRSK.healthcheck.curl)
|
status = capture_with_info(*MRSK.healthcheck.curl)
|
||||||
@@ -23,8 +23,8 @@ class Mrsk::Cli::Healthcheck < Mrsk::Cli::Base
|
|||||||
raise HealthcheckError, "#{target} failed with status #{status}"
|
raise HealthcheckError, "#{target} failed with status #{status}"
|
||||||
end
|
end
|
||||||
rescue SSHKit::Command::Failed
|
rescue SSHKit::Command::Failed
|
||||||
if attempt <= MAX_ATTEMPTS
|
if attempt <= max_attempts
|
||||||
info "#{target} failed to respond, retrying in #{attempt}s..."
|
info "#{target} failed to respond, retrying in #{attempt}s (attempt #{attempt}/#{max_attempts})..."
|
||||||
sleep attempt
|
sleep attempt
|
||||||
attempt += 1
|
attempt += 1
|
||||||
|
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ class Mrsk::Configuration
|
|||||||
end
|
end
|
||||||
|
|
||||||
def healthcheck
|
def healthcheck
|
||||||
{ "path" => "/up", "port" => 3000 }.merge(raw_config.healthcheck || {})
|
{ "path" => "/up", "port" => 3000, "max_attempts" => 7 }.merge(raw_config.healthcheck || {})
|
||||||
end
|
end
|
||||||
|
|
||||||
def readiness_delay
|
def readiness_delay
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ class CliHealthcheckTest < CliTestCase
|
|||||||
.returns("200")
|
.returns("200")
|
||||||
|
|
||||||
run_command("perform").tap do |output|
|
run_command("perform").tap do |output|
|
||||||
assert_match "Health check against /up failed to respond, retrying in 1s...", output
|
assert_match "Health check against /up failed to respond, retrying in 1s (attempt 1/7)...", output
|
||||||
assert_match "Health check against /up failed to respond, retrying in 2s...", output
|
assert_match "Health check against /up failed to respond, retrying in 2s (attempt 2/7)...", output
|
||||||
assert_match "Health check against /up succeeded with 200 OK!", output
|
assert_match "Health check against /up succeeded with 200 OK!", output
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -249,6 +249,6 @@ class ConfigurationTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
test "to_h" do
|
test "to_h" do
|
||||||
assert_equal({ :roles=>["web"], :hosts=>["1.1.1.1", "1.1.1.2"], :primary_host=>"1.1.1.1", :version=>"missing", :repository=>"dhh/app", :absolute_image=>"dhh/app:missing", :service_with_version=>"app-missing", :env_args=>["-e", "REDIS_URL=\"redis://x/y\""], :ssh_options=>{:user=>"root", :auth_methods=>["publickey"]}, :volume_args=>["--volume", "/local/path:/container/path"], :logging=>["--log-opt", "max-size=\"10m\""], :healthcheck=>{"path"=>"/up", "port"=>3000 }}, @config.to_h)
|
assert_equal({ :roles=>["web"], :hosts=>["1.1.1.1", "1.1.1.2"], :primary_host=>"1.1.1.1", :version=>"missing", :repository=>"dhh/app", :absolute_image=>"dhh/app:missing", :service_with_version=>"app-missing", :env_args=>["-e", "REDIS_URL=\"redis://x/y\""], :ssh_options=>{:user=>"root", :auth_methods=>["publickey"]}, :volume_args=>["--volume", "/local/path:/container/path"], :logging=>["--log-opt", "max-size=\"10m\""], :healthcheck=>{"path"=>"/up", "port"=>3000, "max_attempts" => 7 }}, @config.to_h)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user