kamal 2.0.0.alpha → 2.0.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/kamal/cli/accessory.rb +44 -20
- data/lib/kamal/cli/app/boot.rb +22 -16
- data/lib/kamal/cli/app.rb +37 -3
- data/lib/kamal/cli/base.rb +9 -48
- data/lib/kamal/cli/build.rb +8 -3
- data/lib/kamal/cli/healthcheck/barrier.rb +2 -0
- data/lib/kamal/cli/healthcheck/poller.rb +18 -39
- data/lib/kamal/cli/lock.rb +2 -3
- data/lib/kamal/cli/main.rb +54 -51
- data/lib/kamal/cli/proxy.rb +224 -0
- data/lib/kamal/cli/prune.rb +0 -1
- data/lib/kamal/cli/secrets.rb +36 -0
- data/lib/kamal/cli/server.rb +0 -2
- data/lib/kamal/cli/templates/deploy.yml +0 -11
- data/lib/kamal/cli/templates/sample_hooks/post-proxy-reboot.sample +3 -0
- data/lib/kamal/cli/templates/secrets +16 -0
- data/lib/kamal/cli.rb +1 -0
- data/lib/kamal/commander/specifics.rb +3 -3
- data/lib/kamal/commander.rb +17 -9
- data/lib/kamal/commands/accessory.rb +7 -7
- data/lib/kamal/commands/app/assets.rb +8 -8
- data/lib/kamal/commands/app/proxy.rb +16 -0
- data/lib/kamal/commands/app.rb +7 -15
- data/lib/kamal/commands/auditor.rb +6 -3
- data/lib/kamal/commands/base.rb +8 -0
- data/lib/kamal/commands/builder/base.rb +2 -6
- data/lib/kamal/commands/builder/hybrid.rb +1 -1
- data/lib/kamal/commands/builder/remote.rb +27 -4
- data/lib/kamal/commands/builder.rb +1 -1
- data/lib/kamal/commands/docker.rb +4 -0
- data/lib/kamal/commands/hook.rb +5 -2
- data/lib/kamal/commands/lock.rb +2 -6
- data/lib/kamal/commands/proxy.rb +77 -0
- data/lib/kamal/commands/prune.rb +1 -9
- data/lib/kamal/commands/server.rb +11 -1
- data/lib/kamal/configuration/accessory.rb +14 -2
- data/lib/kamal/configuration/builder.rb +9 -3
- data/lib/kamal/configuration/docs/builder.yml +20 -10
- data/lib/kamal/configuration/docs/configuration.yml +16 -16
- data/lib/kamal/configuration/docs/env.yml +10 -11
- data/lib/kamal/configuration/docs/proxy.yml +100 -0
- data/lib/kamal/configuration/docs/registry.yml +4 -2
- data/lib/kamal/configuration/docs/role.yml +3 -5
- data/lib/kamal/configuration/env/tag.rb +4 -3
- data/lib/kamal/configuration/env.rb +10 -17
- data/lib/kamal/configuration/proxy.rb +66 -0
- data/lib/kamal/configuration/registry.rb +3 -2
- data/lib/kamal/configuration/role.rb +63 -94
- data/lib/kamal/configuration/validator/builder.rb +2 -0
- data/lib/kamal/configuration/validator/proxy.rb +11 -0
- data/lib/kamal/configuration/validator.rb +3 -1
- data/lib/kamal/configuration.rb +90 -33
- data/lib/kamal/env_file.rb +4 -0
- data/lib/kamal/secrets/adapters/base.rb +18 -0
- data/lib/kamal/secrets/adapters/bitwarden.rb +64 -0
- data/lib/kamal/secrets/adapters/last_pass.rb +30 -0
- data/lib/kamal/secrets/adapters/one_password.rb +61 -0
- data/lib/kamal/secrets/adapters/test.rb +10 -0
- data/lib/kamal/secrets/adapters.rb +14 -0
- data/lib/kamal/secrets/dotenv/inline_command_substitution.rb +32 -0
- data/lib/kamal/secrets.rb +37 -0
- data/lib/kamal/sshkit_with_ext.rb +1 -0
- data/lib/kamal/utils.rb +12 -0
- data/lib/kamal/version.rb +1 -1
- data/lib/kamal.rb +3 -1
- metadata +23 -16
- data/lib/kamal/cli/env.rb +0 -54
- data/lib/kamal/cli/templates/sample_hooks/post-traefik-reboot.sample +0 -3
- data/lib/kamal/cli/templates/template.env +0 -2
- data/lib/kamal/cli/traefik.rb +0 -122
- data/lib/kamal/commands/app/cord.rb +0 -22
- data/lib/kamal/commands/traefik.rb +0 -85
- data/lib/kamal/configuration/docs/healthcheck.yml +0 -59
- data/lib/kamal/configuration/docs/traefik.yml +0 -62
- data/lib/kamal/configuration/healthcheck.rb +0 -63
- data/lib/kamal/configuration/traefik.rb +0 -60
- /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.
|
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-
|
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: '
|
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: '
|
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-
|
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-
|
238
|
-
- lib/kamal/cli/templates/
|
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.
|
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
|
data/lib/kamal/cli/traefik.rb
DELETED
@@ -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
|
/data/lib/kamal/cli/templates/sample_hooks/{pre-traefik-reboot.sample → pre-proxy-reboot.sample}
RENAMED
File without changes
|