kamal 2.0.0.alpha → 2.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/kamal/cli/accessory.rb +44 -20
  4. data/lib/kamal/cli/app/boot.rb +22 -16
  5. data/lib/kamal/cli/app.rb +37 -3
  6. data/lib/kamal/cli/base.rb +9 -48
  7. data/lib/kamal/cli/build.rb +8 -3
  8. data/lib/kamal/cli/healthcheck/barrier.rb +2 -0
  9. data/lib/kamal/cli/healthcheck/poller.rb +18 -39
  10. data/lib/kamal/cli/lock.rb +2 -3
  11. data/lib/kamal/cli/main.rb +54 -51
  12. data/lib/kamal/cli/proxy.rb +224 -0
  13. data/lib/kamal/cli/prune.rb +0 -1
  14. data/lib/kamal/cli/secrets.rb +36 -0
  15. data/lib/kamal/cli/server.rb +0 -2
  16. data/lib/kamal/cli/templates/deploy.yml +0 -11
  17. data/lib/kamal/cli/templates/sample_hooks/post-proxy-reboot.sample +3 -0
  18. data/lib/kamal/cli/templates/secrets +16 -0
  19. data/lib/kamal/cli.rb +1 -0
  20. data/lib/kamal/commander/specifics.rb +3 -3
  21. data/lib/kamal/commander.rb +17 -9
  22. data/lib/kamal/commands/accessory.rb +7 -7
  23. data/lib/kamal/commands/app/assets.rb +8 -8
  24. data/lib/kamal/commands/app/proxy.rb +16 -0
  25. data/lib/kamal/commands/app.rb +7 -15
  26. data/lib/kamal/commands/auditor.rb +6 -3
  27. data/lib/kamal/commands/base.rb +8 -0
  28. data/lib/kamal/commands/builder/base.rb +2 -6
  29. data/lib/kamal/commands/builder/hybrid.rb +1 -1
  30. data/lib/kamal/commands/builder/remote.rb +27 -4
  31. data/lib/kamal/commands/builder.rb +1 -1
  32. data/lib/kamal/commands/docker.rb +4 -0
  33. data/lib/kamal/commands/hook.rb +5 -2
  34. data/lib/kamal/commands/lock.rb +2 -6
  35. data/lib/kamal/commands/proxy.rb +77 -0
  36. data/lib/kamal/commands/prune.rb +1 -9
  37. data/lib/kamal/commands/server.rb +11 -1
  38. data/lib/kamal/configuration/accessory.rb +14 -2
  39. data/lib/kamal/configuration/builder.rb +9 -3
  40. data/lib/kamal/configuration/docs/builder.yml +20 -10
  41. data/lib/kamal/configuration/docs/configuration.yml +16 -16
  42. data/lib/kamal/configuration/docs/env.yml +10 -11
  43. data/lib/kamal/configuration/docs/proxy.yml +100 -0
  44. data/lib/kamal/configuration/docs/registry.yml +4 -2
  45. data/lib/kamal/configuration/docs/role.yml +3 -5
  46. data/lib/kamal/configuration/env/tag.rb +4 -3
  47. data/lib/kamal/configuration/env.rb +10 -17
  48. data/lib/kamal/configuration/proxy.rb +66 -0
  49. data/lib/kamal/configuration/registry.rb +3 -2
  50. data/lib/kamal/configuration/role.rb +63 -94
  51. data/lib/kamal/configuration/validator/builder.rb +2 -0
  52. data/lib/kamal/configuration/validator/proxy.rb +11 -0
  53. data/lib/kamal/configuration/validator.rb +3 -1
  54. data/lib/kamal/configuration.rb +90 -33
  55. data/lib/kamal/env_file.rb +4 -0
  56. data/lib/kamal/secrets/adapters/base.rb +18 -0
  57. data/lib/kamal/secrets/adapters/bitwarden.rb +64 -0
  58. data/lib/kamal/secrets/adapters/last_pass.rb +30 -0
  59. data/lib/kamal/secrets/adapters/one_password.rb +61 -0
  60. data/lib/kamal/secrets/adapters/test.rb +10 -0
  61. data/lib/kamal/secrets/adapters.rb +14 -0
  62. data/lib/kamal/secrets/dotenv/inline_command_substitution.rb +32 -0
  63. data/lib/kamal/secrets.rb +37 -0
  64. data/lib/kamal/sshkit_with_ext.rb +1 -0
  65. data/lib/kamal/utils.rb +12 -0
  66. data/lib/kamal/version.rb +1 -1
  67. data/lib/kamal.rb +3 -1
  68. metadata +23 -16
  69. data/lib/kamal/cli/env.rb +0 -54
  70. data/lib/kamal/cli/templates/sample_hooks/post-traefik-reboot.sample +0 -3
  71. data/lib/kamal/cli/templates/template.env +0 -2
  72. data/lib/kamal/cli/traefik.rb +0 -122
  73. data/lib/kamal/commands/app/cord.rb +0 -22
  74. data/lib/kamal/commands/traefik.rb +0 -85
  75. data/lib/kamal/configuration/docs/healthcheck.yml +0 -59
  76. data/lib/kamal/configuration/docs/traefik.yml +0 -62
  77. data/lib/kamal/configuration/healthcheck.rb +0 -63
  78. data/lib/kamal/configuration/traefik.rb +0 -60
  79. /data/lib/kamal/cli/templates/sample_hooks/{pre-traefik-reboot.sample → pre-proxy-reboot.sample} +0 -0
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kamal
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.alpha
4
+ version: 2.0.0.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-09-01 00:00:00.000000000 Z
11
+ date: 2024-09-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -78,14 +78,14 @@ dependencies:
78
78
  requirements:
79
79
  - - "~>"
80
80
  - !ruby/object:Gem::Version
81
- version: '2.8'
81
+ version: '3.1'
82
82
  type: :runtime
83
83
  prerelease: false
84
84
  version_requirements: !ruby/object:Gem::Requirement
85
85
  requirements:
86
86
  - - "~>"
87
87
  - !ruby/object:Gem::Version
88
- version: '2.8'
88
+ version: '3.1'
89
89
  - !ruby/object:Gem::Dependency
90
90
  name: zeitwerk
91
91
  requirement: !ruby/object:Gem::Requirement
@@ -218,25 +218,25 @@ files:
218
218
  - lib/kamal/cli/base.rb
219
219
  - lib/kamal/cli/build.rb
220
220
  - lib/kamal/cli/build/clone.rb
221
- - lib/kamal/cli/env.rb
222
221
  - lib/kamal/cli/healthcheck/barrier.rb
223
222
  - lib/kamal/cli/healthcheck/error.rb
224
223
  - lib/kamal/cli/healthcheck/poller.rb
225
224
  - lib/kamal/cli/lock.rb
226
225
  - lib/kamal/cli/main.rb
226
+ - lib/kamal/cli/proxy.rb
227
227
  - lib/kamal/cli/prune.rb
228
228
  - lib/kamal/cli/registry.rb
229
+ - lib/kamal/cli/secrets.rb
229
230
  - lib/kamal/cli/server.rb
230
231
  - lib/kamal/cli/templates/deploy.yml
231
232
  - lib/kamal/cli/templates/sample_hooks/docker-setup.sample
232
233
  - lib/kamal/cli/templates/sample_hooks/post-deploy.sample
233
- - lib/kamal/cli/templates/sample_hooks/post-traefik-reboot.sample
234
+ - lib/kamal/cli/templates/sample_hooks/post-proxy-reboot.sample
234
235
  - lib/kamal/cli/templates/sample_hooks/pre-build.sample
235
236
  - lib/kamal/cli/templates/sample_hooks/pre-connect.sample
236
237
  - lib/kamal/cli/templates/sample_hooks/pre-deploy.sample
237
- - lib/kamal/cli/templates/sample_hooks/pre-traefik-reboot.sample
238
- - lib/kamal/cli/templates/template.env
239
- - lib/kamal/cli/traefik.rb
238
+ - lib/kamal/cli/templates/sample_hooks/pre-proxy-reboot.sample
239
+ - lib/kamal/cli/templates/secrets
240
240
  - lib/kamal/commander.rb
241
241
  - lib/kamal/commander/specifics.rb
242
242
  - lib/kamal/commands.rb
@@ -244,10 +244,10 @@ files:
244
244
  - lib/kamal/commands/app.rb
245
245
  - lib/kamal/commands/app/assets.rb
246
246
  - lib/kamal/commands/app/containers.rb
247
- - lib/kamal/commands/app/cord.rb
248
247
  - lib/kamal/commands/app/execution.rb
249
248
  - lib/kamal/commands/app/images.rb
250
249
  - lib/kamal/commands/app/logging.rb
250
+ - lib/kamal/commands/app/proxy.rb
251
251
  - lib/kamal/commands/auditor.rb
252
252
  - lib/kamal/commands/base.rb
253
253
  - lib/kamal/commands/builder.rb
@@ -259,10 +259,10 @@ files:
259
259
  - lib/kamal/commands/docker.rb
260
260
  - lib/kamal/commands/hook.rb
261
261
  - lib/kamal/commands/lock.rb
262
+ - lib/kamal/commands/proxy.rb
262
263
  - lib/kamal/commands/prune.rb
263
264
  - lib/kamal/commands/registry.rb
264
265
  - lib/kamal/commands/server.rb
265
- - lib/kamal/commands/traefik.rb
266
266
  - lib/kamal/configuration.rb
267
267
  - lib/kamal/configuration/accessory.rb
268
268
  - lib/kamal/configuration/alias.rb
@@ -274,24 +274,22 @@ files:
274
274
  - lib/kamal/configuration/docs/builder.yml
275
275
  - lib/kamal/configuration/docs/configuration.yml
276
276
  - lib/kamal/configuration/docs/env.yml
277
- - lib/kamal/configuration/docs/healthcheck.yml
278
277
  - lib/kamal/configuration/docs/logging.yml
278
+ - lib/kamal/configuration/docs/proxy.yml
279
279
  - lib/kamal/configuration/docs/registry.yml
280
280
  - lib/kamal/configuration/docs/role.yml
281
281
  - lib/kamal/configuration/docs/servers.yml
282
282
  - lib/kamal/configuration/docs/ssh.yml
283
283
  - lib/kamal/configuration/docs/sshkit.yml
284
- - lib/kamal/configuration/docs/traefik.yml
285
284
  - lib/kamal/configuration/env.rb
286
285
  - lib/kamal/configuration/env/tag.rb
287
- - lib/kamal/configuration/healthcheck.rb
288
286
  - lib/kamal/configuration/logging.rb
287
+ - lib/kamal/configuration/proxy.rb
289
288
  - lib/kamal/configuration/registry.rb
290
289
  - lib/kamal/configuration/role.rb
291
290
  - lib/kamal/configuration/servers.rb
292
291
  - lib/kamal/configuration/ssh.rb
293
292
  - lib/kamal/configuration/sshkit.rb
294
- - lib/kamal/configuration/traefik.rb
295
293
  - lib/kamal/configuration/validation.rb
296
294
  - lib/kamal/configuration/validator.rb
297
295
  - lib/kamal/configuration/validator/accessory.rb
@@ -299,12 +297,21 @@ files:
299
297
  - lib/kamal/configuration/validator/builder.rb
300
298
  - lib/kamal/configuration/validator/configuration.rb
301
299
  - lib/kamal/configuration/validator/env.rb
300
+ - lib/kamal/configuration/validator/proxy.rb
302
301
  - lib/kamal/configuration/validator/registry.rb
303
302
  - lib/kamal/configuration/validator/role.rb
304
303
  - lib/kamal/configuration/validator/servers.rb
305
304
  - lib/kamal/configuration/volume.rb
306
305
  - lib/kamal/env_file.rb
307
306
  - lib/kamal/git.rb
307
+ - lib/kamal/secrets.rb
308
+ - lib/kamal/secrets/adapters.rb
309
+ - lib/kamal/secrets/adapters/base.rb
310
+ - lib/kamal/secrets/adapters/bitwarden.rb
311
+ - lib/kamal/secrets/adapters/last_pass.rb
312
+ - lib/kamal/secrets/adapters/one_password.rb
313
+ - lib/kamal/secrets/adapters/test.rb
314
+ - lib/kamal/secrets/dotenv/inline_command_substitution.rb
308
315
  - lib/kamal/sshkit_with_ext.rb
309
316
  - lib/kamal/tags.rb
310
317
  - lib/kamal/utils.rb
@@ -329,7 +336,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
329
336
  - !ruby/object:Gem::Version
330
337
  version: '0'
331
338
  requirements: []
332
- rubygems_version: 3.5.17
339
+ rubygems_version: 3.5.16
333
340
  signing_key:
334
341
  specification_version: 4
335
342
  summary: Deploy web apps in containers to servers running Docker with zero downtime.
data/lib/kamal/cli/env.rb DELETED
@@ -1,54 +0,0 @@
1
- require "tempfile"
2
-
3
- class Kamal::Cli::Env < Kamal::Cli::Base
4
- desc "push", "Push the env file to the remote hosts"
5
- def push
6
- with_lock do
7
- on(KAMAL.hosts) do
8
- execute *KAMAL.auditor.record("Pushed env files"), verbosity: :debug
9
-
10
- KAMAL.roles_on(host).each do |role|
11
- execute *KAMAL.app(role: role, host: host).make_env_directory
12
- upload! role.env(host).secrets_io, role.env(host).secrets_file, mode: 400
13
- end
14
- end
15
-
16
- on(KAMAL.traefik_hosts) do
17
- execute *KAMAL.traefik.make_env_directory
18
- upload! KAMAL.traefik.env.secrets_io, KAMAL.traefik.env.secrets_file, mode: 400
19
- end
20
-
21
- on(KAMAL.accessory_hosts) do
22
- KAMAL.accessories_on(host).each do |accessory|
23
- accessory_config = KAMAL.config.accessory(accessory)
24
- execute *KAMAL.accessory(accessory).make_env_directory
25
- upload! accessory_config.env.secrets_io, accessory_config.env.secrets_file, mode: 400
26
- end
27
- end
28
- end
29
- end
30
-
31
- desc "delete", "Delete the env file from the remote hosts"
32
- def delete
33
- with_lock do
34
- on(KAMAL.hosts) do
35
- execute *KAMAL.auditor.record("Deleted env files"), verbosity: :debug
36
-
37
- KAMAL.roles_on(host).each do |role|
38
- execute *KAMAL.app(role: role, host: host).remove_env_file
39
- end
40
- end
41
-
42
- on(KAMAL.traefik_hosts) do
43
- execute *KAMAL.traefik.remove_env_file
44
- end
45
-
46
- on(KAMAL.accessory_hosts) do
47
- KAMAL.accessories_on(host).each do |accessory|
48
- accessory_config = KAMAL.config.accessory(accessory)
49
- execute *KAMAL.accessory(accessory).remove_env_file
50
- end
51
- end
52
- end
53
- end
54
- end
@@ -1,3 +0,0 @@
1
- #!/bin/sh
2
-
3
- echo "Rebooted Traefik on $KAMAL_HOSTS"
@@ -1,2 +0,0 @@
1
- KAMAL_REGISTRY_PASSWORD=change-this
2
- RAILS_MASTER_KEY=another-env
@@ -1,122 +0,0 @@
1
- class Kamal::Cli::Traefik < Kamal::Cli::Base
2
- desc "boot", "Boot Traefik on servers"
3
- def boot
4
- with_lock do
5
- on(KAMAL.traefik_hosts) do
6
- execute *KAMAL.registry.login
7
- execute *KAMAL.traefik.start_or_run
8
- end
9
- end
10
- end
11
-
12
- desc "reboot", "Reboot Traefik on servers (stop container, remove container, start new container)"
13
- option :rolling, type: :boolean, default: false, desc: "Reboot traefik on hosts in sequence, rather than in parallel"
14
- option :confirmed, aliases: "-y", type: :boolean, default: false, desc: "Proceed without confirmation question"
15
- def reboot
16
- confirming "This will cause a brief outage on each host. Are you sure?" do
17
- with_lock do
18
- host_groups = options[:rolling] ? KAMAL.traefik_hosts : [ KAMAL.traefik_hosts ]
19
- host_groups.each do |hosts|
20
- host_list = Array(hosts).join(",")
21
- run_hook "pre-traefik-reboot", hosts: host_list
22
- on(hosts) do
23
- execute *KAMAL.auditor.record("Rebooted traefik"), verbosity: :debug
24
- execute *KAMAL.registry.login
25
- execute *KAMAL.traefik.stop, raise_on_non_zero_exit: false
26
- execute *KAMAL.traefik.remove_container
27
- execute *KAMAL.traefik.run
28
- end
29
- run_hook "post-traefik-reboot", hosts: host_list
30
- end
31
- end
32
- end
33
- end
34
-
35
- desc "start", "Start existing Traefik container on servers"
36
- def start
37
- with_lock do
38
- on(KAMAL.traefik_hosts) do
39
- execute *KAMAL.auditor.record("Started traefik"), verbosity: :debug
40
- execute *KAMAL.traefik.start
41
- end
42
- end
43
- end
44
-
45
- desc "stop", "Stop existing Traefik container on servers"
46
- def stop
47
- with_lock do
48
- on(KAMAL.traefik_hosts) do
49
- execute *KAMAL.auditor.record("Stopped traefik"), verbosity: :debug
50
- execute *KAMAL.traefik.stop, raise_on_non_zero_exit: false
51
- end
52
- end
53
- end
54
-
55
- desc "restart", "Restart existing Traefik container on servers"
56
- def restart
57
- with_lock do
58
- stop
59
- start
60
- end
61
- end
62
-
63
- desc "details", "Show details about Traefik container from servers"
64
- def details
65
- on(KAMAL.traefik_hosts) { |host| puts_by_host host, capture_with_info(*KAMAL.traefik.info), type: "Traefik" }
66
- end
67
-
68
- desc "logs", "Show log lines from Traefik on servers"
69
- option :since, aliases: "-s", desc: "Show logs since timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)"
70
- option :lines, type: :numeric, aliases: "-n", desc: "Number of log lines to pull from each server"
71
- option :grep, aliases: "-g", desc: "Show lines with grep match only (use this to fetch specific requests by id)"
72
- option :grep_options, aliases: "-o", desc: "Additional options supplied to grep"
73
- option :follow, aliases: "-f", desc: "Follow logs on primary server (or specific host set by --hosts)"
74
- def logs
75
- grep = options[:grep]
76
- grep_options = options[:grep_options]
77
-
78
- if options[:follow]
79
- run_locally do
80
- info "Following logs on #{KAMAL.primary_host}..."
81
- info KAMAL.traefik.follow_logs(host: KAMAL.primary_host, grep: grep, grep_options: grep_options)
82
- exec KAMAL.traefik.follow_logs(host: KAMAL.primary_host, grep: grep, grep_options: grep_options)
83
- end
84
- else
85
- since = options[:since]
86
- lines = options[:lines].presence || ((since || grep) ? nil : 100) # Default to 100 lines if since or grep isn't set
87
-
88
- on(KAMAL.traefik_hosts) do |host|
89
- puts_by_host host, capture(*KAMAL.traefik.logs(since: since, lines: lines, grep: grep, grep_options: grep_options)), type: "Traefik"
90
- end
91
- end
92
- end
93
-
94
- desc "remove", "Remove Traefik container and image from servers"
95
- def remove
96
- with_lock do
97
- stop
98
- remove_container
99
- remove_image
100
- end
101
- end
102
-
103
- desc "remove_container", "Remove Traefik container from servers", hide: true
104
- def remove_container
105
- with_lock do
106
- on(KAMAL.traefik_hosts) do
107
- execute *KAMAL.auditor.record("Removed traefik container"), verbosity: :debug
108
- execute *KAMAL.traefik.remove_container
109
- end
110
- end
111
- end
112
-
113
- desc "remove_image", "Remove Traefik image from servers", hide: true
114
- def remove_image
115
- with_lock do
116
- on(KAMAL.traefik_hosts) do
117
- execute *KAMAL.auditor.record("Removed traefik image"), verbosity: :debug
118
- execute *KAMAL.traefik.remove_image
119
- end
120
- end
121
- end
122
- end
@@ -1,22 +0,0 @@
1
- module Kamal::Commands::App::Cord
2
- def cord(version:)
3
- pipe \
4
- docker(:inspect, "-f '{{ range .Mounts }}{{printf \"%s %s\\n\" .Source .Destination}}{{ end }}'", container_name(version)),
5
- [ :awk, "'$2 == \"#{role.cord_volume.container_path}\" {print $1}'" ]
6
- end
7
-
8
- def tie_cord(cord)
9
- create_empty_file(cord)
10
- end
11
-
12
- def cut_cord(cord)
13
- remove_directory(cord)
14
- end
15
-
16
- private
17
- def create_empty_file(file)
18
- chain \
19
- make_directory_for(file),
20
- [ :touch, file ]
21
- end
22
- end
@@ -1,85 +0,0 @@
1
- class Kamal::Commands::Traefik < Kamal::Commands::Base
2
- delegate :argumentize, :optionize, to: Kamal::Utils
3
- delegate :port, :publish?, :labels, :env, :image, :options, :args, to: :"config.traefik"
4
-
5
- def run
6
- docker :run, "--name traefik",
7
- "--detach",
8
- "--restart", "unless-stopped",
9
- *publish_args,
10
- "--volume", "/var/run/docker.sock:/var/run/docker.sock",
11
- *env_args,
12
- *config.logging_args,
13
- *label_args,
14
- *docker_options_args,
15
- image,
16
- "--providers.docker",
17
- *cmd_option_args
18
- end
19
-
20
- def start
21
- docker :container, :start, "traefik"
22
- end
23
-
24
- def stop
25
- docker :container, :stop, "traefik"
26
- end
27
-
28
- def start_or_run
29
- any start, run
30
- end
31
-
32
- def info
33
- docker :ps, "--filter", "name=^traefik$"
34
- end
35
-
36
- def logs(since: nil, lines: nil, grep: nil, grep_options: nil)
37
- pipe \
38
- docker(:logs, "traefik", (" --since #{since}" if since), (" --tail #{lines}" if lines), "--timestamps", "2>&1"),
39
- ("grep '#{grep}'#{" #{grep_options}" if grep_options}" if grep)
40
- end
41
-
42
- def follow_logs(host:, grep: nil, grep_options: nil)
43
- run_over_ssh pipe(
44
- docker(:logs, "traefik", "--timestamps", "--tail", "10", "--follow", "2>&1"),
45
- (%(grep "#{grep}"#{" #{grep_options}" if grep_options}) if grep)
46
- ).join(" "), host: host
47
- end
48
-
49
- def remove_container
50
- docker :container, :prune, "--force", "--filter", "label=org.opencontainers.image.title=Traefik"
51
- end
52
-
53
- def remove_image
54
- docker :image, :prune, "--all", "--force", "--filter", "label=org.opencontainers.image.title=Traefik"
55
- end
56
-
57
- def make_env_directory
58
- make_directory(env.secrets_directory)
59
- end
60
-
61
- def remove_env_file
62
- [ :rm, "-f", env.secrets_file ]
63
- end
64
-
65
- private
66
- def publish_args
67
- argumentize "--publish", port if publish?
68
- end
69
-
70
- def label_args
71
- argumentize "--label", labels
72
- end
73
-
74
- def env_args
75
- env.args
76
- end
77
-
78
- def docker_options_args
79
- optionize(options)
80
- end
81
-
82
- def cmd_option_args
83
- optionize args, with: "="
84
- end
85
- end
@@ -1,59 +0,0 @@
1
- # Healthcheck configuration
2
- #
3
- # On roles that are running Traefik, Kamal will supply a default healthcheck to `docker run`.
4
- # For other roles, by default no healthcheck is supplied.
5
- #
6
- # If no healthcheck is supplied and the image does not define one, they we wait for the container
7
- # to reach a running state and then pause for the readiness delay.
8
- #
9
- # The default healthcheck is `curl -f http://localhost:<port>/<path>`, so it assumes that `curl`
10
- # is available within the container.
11
-
12
- # Healthcheck options
13
- #
14
- # These go under the `healthcheck` key in the root or role configuration.
15
- healthcheck:
16
-
17
- # Command
18
- #
19
- # The command to run, defaults to `curl -f http://localhost:<port>/<path>` on roles running Traefik
20
- cmd: "curl -f http://localhost"
21
-
22
- # Interval
23
- #
24
- # The Docker healthcheck interval, defaults to `1s`
25
- interval: 10s
26
-
27
- # Max attempts
28
- #
29
- # The maximum number of times we poll the container to see if it is healthy, defaults to `7`
30
- # Each check is separated by an increasing interval starting with 1 second.
31
- max_attempts: 3
32
-
33
- # Port
34
- #
35
- # The port to use in the healthcheck, defaults to `3000`
36
- port: "80"
37
-
38
- # Path
39
- #
40
- # The path to use in the healthcheck, defaults to `/up`
41
- path: /health
42
-
43
- # Cords for zero-downtime deployments
44
- #
45
- # The cord file is used for zero-downtime deployments. The healthcheck is augmented with a check
46
- # for the existance of the file. This allows us to delete the file and force the container to
47
- # become unhealthy, causing Traefik to stop routing traffic to it.
48
- #
49
- # Kamal mounts a volume at this location and creates the file before starting the container.
50
- # You can set the value to `false` to disable the cord file, but this loses the zero-downtime
51
- # guarantee.
52
- #
53
- # The default value is `/tmp/kamal-cord`
54
- cord: /cord
55
-
56
- # Log lines
57
- #
58
- # Number of lines to log from the container when the healthcheck fails, defaults to `50`
59
- log_lines: 100
@@ -1,62 +0,0 @@
1
- # Traefik
2
- #
3
- # Traefik is a reverse proxy, used by Kamal for zero-downtime deployments.
4
- #
5
- # We start an instance on the hosts in it's own container.
6
- #
7
- # During a deployment:
8
- # 1. We start a new container which Traefik automatically detects due to the labels we have applied
9
- # 2. Traefik starts routing traffic to the new container
10
- # 3. We force the old container to fail it's healthcheck, causing Traefik to stop routing traffic to it
11
- # 4. We stop the old container
12
-
13
- # Traefik settings
14
- #
15
- # Traekik is configured in the root configuration under `traefik`.
16
- traefik:
17
-
18
- # Image
19
- #
20
- # The Traefik image to use, defaults to `traefik:v2.10`
21
- image: traefik:v2.9
22
-
23
- # Host port
24
- #
25
- # The host port to publish the Traefik container on, defaults to `80`
26
- host_port: "8080"
27
-
28
- # Disabling publishing
29
- #
30
- # To avoid publishing the Traefik container, set this to `false`
31
- publish: false
32
-
33
- # Labels
34
- #
35
- # Additional labels to apply to the Traefik container
36
- labels:
37
- traefik.http.routers.catchall.entryPoints: http
38
- traefik.http.routers.catchall.rule: PathPrefix(`/`)
39
- traefik.http.routers.catchall.service: unavailable
40
- traefik.http.routers.catchall.priority: "1"
41
- traefik.http.services.unavailable.loadbalancer.server.port: "0"
42
-
43
- # Arguments
44
- #
45
- # Additional arguments to pass to the Traefik container
46
- args:
47
- entryPoints.http.address: ":80"
48
- entryPoints.http.forwardedHeaders.insecure: true
49
- accesslog: true
50
- accesslog.format: json
51
-
52
- # Options
53
- #
54
- # Additional options to pass to `docker run`
55
- options:
56
- cpus: 2
57
-
58
- # Environment variables
59
- #
60
- # See kamal docs env
61
- env:
62
- ...
@@ -1,63 +0,0 @@
1
- class Kamal::Configuration::Healthcheck
2
- include Kamal::Configuration::Validation
3
-
4
- attr_reader :healthcheck_config
5
-
6
- def initialize(healthcheck_config:, context: "healthcheck")
7
- @healthcheck_config = healthcheck_config || {}
8
- validate! @healthcheck_config, context: context
9
- end
10
-
11
- def merge(other)
12
- self.class.new healthcheck_config: healthcheck_config.deep_merge(other.healthcheck_config)
13
- end
14
-
15
- def cmd
16
- healthcheck_config.fetch("cmd", http_health_check)
17
- end
18
-
19
- def port
20
- healthcheck_config.fetch("port", 3000)
21
- end
22
-
23
- def path
24
- healthcheck_config.fetch("path", "/up")
25
- end
26
-
27
- def max_attempts
28
- healthcheck_config.fetch("max_attempts", 7)
29
- end
30
-
31
- def interval
32
- healthcheck_config.fetch("interval", "1s")
33
- end
34
-
35
- def cord
36
- healthcheck_config.fetch("cord", "/tmp/kamal-cord")
37
- end
38
-
39
- def log_lines
40
- healthcheck_config.fetch("log_lines", 50)
41
- end
42
-
43
- def set_port_or_path?
44
- healthcheck_config["port"].present? || healthcheck_config["path"].present?
45
- end
46
-
47
- def to_h
48
- {
49
- "cmd" => cmd,
50
- "interval" => interval,
51
- "max_attempts" => max_attempts,
52
- "port" => port,
53
- "path" => path,
54
- "cord" => cord,
55
- "log_lines" => log_lines
56
- }
57
- end
58
-
59
- private
60
- def http_health_check
61
- "curl -f #{URI.join("http://localhost:#{port}", path)} || exit 1" if path.present? || port.present?
62
- end
63
- end
@@ -1,60 +0,0 @@
1
- class Kamal::Configuration::Traefik
2
- DEFAULT_IMAGE = "traefik:v2.10"
3
- CONTAINER_PORT = 80
4
- DEFAULT_ARGS = {
5
- "log.level" => "DEBUG"
6
- }
7
- DEFAULT_LABELS = {
8
- # These ensure we serve a 502 rather than a 404 if no containers are available
9
- "traefik.http.routers.catchall.entryPoints" => "http",
10
- "traefik.http.routers.catchall.rule" => "PathPrefix(`/`)",
11
- "traefik.http.routers.catchall.service" => "unavailable",
12
- "traefik.http.routers.catchall.priority" => 1,
13
- "traefik.http.services.unavailable.loadbalancer.server.port" => "0"
14
- }
15
-
16
- include Kamal::Configuration::Validation
17
-
18
- attr_reader :config, :traefik_config
19
-
20
- def initialize(config:)
21
- @config = config
22
- @traefik_config = config.raw_config.traefik || {}
23
- validate! traefik_config
24
- end
25
-
26
- def publish?
27
- traefik_config["publish"] != false
28
- end
29
-
30
- def labels
31
- DEFAULT_LABELS.merge(traefik_config["labels"] || {})
32
- end
33
-
34
- def env
35
- Kamal::Configuration::Env.new \
36
- config: traefik_config.fetch("env", {}),
37
- secrets_file: File.join(config.host_env_directory, "traefik", "traefik.env"),
38
- context: "traefik/env"
39
- end
40
-
41
- def host_port
42
- traefik_config.fetch("host_port", CONTAINER_PORT)
43
- end
44
-
45
- def options
46
- traefik_config.fetch("options", {})
47
- end
48
-
49
- def port
50
- "#{host_port}:#{CONTAINER_PORT}"
51
- end
52
-
53
- def args
54
- DEFAULT_ARGS.merge(traefik_config.fetch("args", {}))
55
- end
56
-
57
- def image
58
- traefik_config.fetch("image", DEFAULT_IMAGE)
59
- end
60
- end