kamal 2.0.0.alpha → 2.0.0.beta2

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.
Files changed (80) 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 +21 -49
  7. data/lib/kamal/cli/build.rb +21 -14
  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 +213 -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/execution.rb +1 -0
  25. data/lib/kamal/commands/app/proxy.rb +16 -0
  26. data/lib/kamal/commands/app.rb +7 -15
  27. data/lib/kamal/commands/auditor.rb +6 -3
  28. data/lib/kamal/commands/base.rb +8 -0
  29. data/lib/kamal/commands/builder/base.rb +2 -6
  30. data/lib/kamal/commands/builder/hybrid.rb +1 -1
  31. data/lib/kamal/commands/builder/remote.rb +27 -4
  32. data/lib/kamal/commands/builder.rb +1 -1
  33. data/lib/kamal/commands/docker.rb +4 -0
  34. data/lib/kamal/commands/hook.rb +8 -2
  35. data/lib/kamal/commands/lock.rb +2 -6
  36. data/lib/kamal/commands/proxy.rb +72 -0
  37. data/lib/kamal/commands/prune.rb +1 -9
  38. data/lib/kamal/commands/server.rb +11 -1
  39. data/lib/kamal/configuration/accessory.rb +14 -2
  40. data/lib/kamal/configuration/builder.rb +9 -3
  41. data/lib/kamal/configuration/docs/builder.yml +20 -10
  42. data/lib/kamal/configuration/docs/configuration.yml +16 -16
  43. data/lib/kamal/configuration/docs/env.yml +10 -11
  44. data/lib/kamal/configuration/docs/proxy.yml +100 -0
  45. data/lib/kamal/configuration/docs/registry.yml +4 -2
  46. data/lib/kamal/configuration/docs/role.yml +3 -5
  47. data/lib/kamal/configuration/env/tag.rb +4 -3
  48. data/lib/kamal/configuration/env.rb +10 -17
  49. data/lib/kamal/configuration/proxy.rb +66 -0
  50. data/lib/kamal/configuration/registry.rb +3 -2
  51. data/lib/kamal/configuration/role.rb +63 -94
  52. data/lib/kamal/configuration/validator/builder.rb +2 -0
  53. data/lib/kamal/configuration/validator/proxy.rb +11 -0
  54. data/lib/kamal/configuration/validator.rb +3 -1
  55. data/lib/kamal/configuration.rb +80 -33
  56. data/lib/kamal/env_file.rb +4 -0
  57. data/lib/kamal/secrets/adapters/base.rb +18 -0
  58. data/lib/kamal/secrets/adapters/bitwarden.rb +64 -0
  59. data/lib/kamal/secrets/adapters/last_pass.rb +30 -0
  60. data/lib/kamal/secrets/adapters/one_password.rb +61 -0
  61. data/lib/kamal/secrets/adapters/test.rb +10 -0
  62. data/lib/kamal/secrets/adapters.rb +14 -0
  63. data/lib/kamal/secrets/dotenv/inline_command_substitution.rb +32 -0
  64. data/lib/kamal/secrets.rb +37 -0
  65. data/lib/kamal/sshkit_with_ext.rb +1 -0
  66. data/lib/kamal/utils.rb +12 -0
  67. data/lib/kamal/version.rb +1 -1
  68. data/lib/kamal.rb +3 -1
  69. metadata +23 -16
  70. data/lib/kamal/cli/env.rb +0 -54
  71. data/lib/kamal/cli/templates/sample_hooks/post-traefik-reboot.sample +0 -3
  72. data/lib/kamal/cli/templates/template.env +0 -2
  73. data/lib/kamal/cli/traefik.rb +0 -122
  74. data/lib/kamal/commands/app/cord.rb +0 -22
  75. data/lib/kamal/commands/traefik.rb +0 -85
  76. data/lib/kamal/configuration/docs/healthcheck.yml +0 -59
  77. data/lib/kamal/configuration/docs/traefik.yml +0 -62
  78. data/lib/kamal/configuration/healthcheck.rb +0 -63
  79. data/lib/kamal/configuration/traefik.rb +0 -60
  80. /data/lib/kamal/cli/templates/sample_hooks/{pre-traefik-reboot.sample → pre-proxy-reboot.sample} +0 -0
@@ -3,18 +3,18 @@ module Kamal::Commands::App::Assets
3
3
  asset_container = "#{role.container_prefix}-assets"
4
4
 
5
5
  combine \
6
- make_directory(role.asset_extracted_path),
6
+ make_directory(role.asset_extracted_directory),
7
7
  [ *docker(:stop, "-t 1", asset_container, "2> /dev/null"), "|| true" ],
8
- docker(:run, "--name", asset_container, "--detach", "--rm", config.absolute_image, "sleep 1000000"),
9
- docker(:cp, "-L", "#{asset_container}:#{role.asset_path}/.", role.asset_extracted_path),
8
+ docker(:run, "--name", asset_container, "--detach", "--rm", "--entrypoint", "sleep", config.absolute_image, "1000000"),
9
+ docker(:cp, "-L", "#{asset_container}:#{role.asset_path}/.", role.asset_extracted_directory),
10
10
  docker(:stop, "-t 1", asset_container),
11
11
  by: "&&"
12
12
  end
13
13
 
14
14
  def sync_asset_volumes(old_version: nil)
15
- new_extracted_path, new_volume_path = role.asset_extracted_path(config.version), role.asset_volume.host_path
15
+ new_extracted_path, new_volume_path = role.asset_extracted_directory(config.version), role.asset_volume.host_path
16
16
  if old_version.present?
17
- old_extracted_path, old_volume_path = role.asset_extracted_path(old_version), role.asset_volume(old_version).host_path
17
+ old_extracted_path, old_volume_path = role.asset_extracted_directory(old_version), role.asset_volume(old_version).host_path
18
18
  end
19
19
 
20
20
  commands = [ make_directory(new_volume_path), copy_contents(new_extracted_path, new_volume_path) ]
@@ -29,8 +29,8 @@ module Kamal::Commands::App::Assets
29
29
 
30
30
  def clean_up_assets
31
31
  chain \
32
- find_and_remove_older_siblings(role.asset_extracted_path),
33
- find_and_remove_older_siblings(role.asset_volume_path)
32
+ find_and_remove_older_siblings(role.asset_extracted_directory),
33
+ find_and_remove_older_siblings(role.asset_volume_directory)
34
34
  end
35
35
 
36
36
  private
@@ -39,7 +39,7 @@ module Kamal::Commands::App::Assets
39
39
  :find,
40
40
  Pathname.new(path).dirname.to_s,
41
41
  "-maxdepth 1",
42
- "-name", "'#{role.container_prefix}-*'",
42
+ "-name", "'#{role.name}-*'",
43
43
  "!", "-name", Pathname.new(path).basename.to_s,
44
44
  "-exec rm -rf \"{}\" +"
45
45
  ]
@@ -11,6 +11,7 @@ module Kamal::Commands::App::Execution
11
11
  docker :run,
12
12
  ("-it" if interactive),
13
13
  "--rm",
14
+ "--network", "kamal",
14
15
  *role&.env_args(host),
15
16
  *argumentize("--env", env),
16
17
  *config.volume_args,
@@ -0,0 +1,16 @@
1
+ module Kamal::Commands::App::Proxy
2
+ delegate :proxy_container_name, to: :config
3
+
4
+ def deploy(target:)
5
+ proxy_exec :deploy, role.container_prefix, *role.proxy.deploy_command_args(target: target)
6
+ end
7
+
8
+ def remove(target:)
9
+ proxy_exec :remove, role.container_prefix, *role.proxy.remove_command_args(target: target)
10
+ end
11
+
12
+ private
13
+ def proxy_exec(*command)
14
+ docker :exec, proxy_container_name, "kamal-proxy", *command
15
+ end
16
+ end
@@ -1,10 +1,12 @@
1
1
  class Kamal::Commands::App < Kamal::Commands::Base
2
- include Assets, Containers, Cord, Execution, Images, Logging
2
+ include Assets, Containers, Execution, Images, Logging, Proxy
3
3
 
4
4
  ACTIVE_DOCKER_STATUSES = [ :running, :restarting ]
5
5
 
6
6
  attr_reader :role, :host
7
7
 
8
+ delegate :container_name, to: :role
9
+
8
10
  def initialize(config, role: nil, host: nil)
9
11
  super(config)
10
12
  @role = role
@@ -16,11 +18,11 @@ class Kamal::Commands::App < Kamal::Commands::Base
16
18
  "--detach",
17
19
  "--restart unless-stopped",
18
20
  "--name", container_name,
21
+ "--network", "kamal",
19
22
  *([ "--hostname", hostname ] if hostname),
20
23
  "-e", "KAMAL_CONTAINER_NAME=\"#{container_name}\"",
21
24
  "-e", "KAMAL_VERSION=\"#{config.version}\"",
22
25
  *role.env_args(host),
23
- *role.health_check_args,
24
26
  *role.logging_args,
25
27
  *config.volume_args,
26
28
  *role.asset_volume_args,
@@ -41,7 +43,7 @@ class Kamal::Commands::App < Kamal::Commands::Base
41
43
  def stop(version: nil)
42
44
  pipe \
43
45
  version ? container_id_for_version(version) : current_running_container_id,
44
- xargs(config.stop_wait_time ? docker(:stop, "-t", config.stop_wait_time) : docker(:stop))
46
+ xargs(docker(:stop, *role.stop_args))
45
47
  end
46
48
 
47
49
  def info
@@ -69,21 +71,11 @@ class Kamal::Commands::App < Kamal::Commands::Base
69
71
  extract_version_from_name
70
72
  end
71
73
 
72
-
73
- def make_env_directory
74
- make_directory role.env(host).secrets_directory
75
- end
76
-
77
- def remove_env_file
78
- [ :rm, "-f", role.env(host).secrets_file ]
74
+ def ensure_env_directory
75
+ make_directory role.env_directory
79
76
  end
80
77
 
81
-
82
78
  private
83
- def container_name(version = nil)
84
- [ role.container_prefix, version || config.version ].compact.join("-")
85
- end
86
-
87
79
  def latest_image_id
88
80
  docker :image, :ls, *argumentize("--filter", "reference=#{config.latest_image}"), "--format", "'{{.ID}}'"
89
81
  end
@@ -8,9 +8,12 @@ class Kamal::Commands::Auditor < Kamal::Commands::Base
8
8
 
9
9
  # Runs remotely
10
10
  def record(line, **details)
11
- append \
12
- [ :echo, audit_tags(**details).except(:version, :service_version, :service).to_s, line ],
13
- audit_log_file
11
+ combine \
12
+ [ :mkdir, "-p", config.run_directory ],
13
+ append(
14
+ [ :echo, audit_tags(**details).except(:version, :service_version, :service).to_s, line ],
15
+ audit_log_file
16
+ )
14
17
  end
15
18
 
16
19
  def reveal
@@ -37,6 +37,10 @@ module Kamal::Commands
37
37
  [ :rm, "-r", path ]
38
38
  end
39
39
 
40
+ def remove_file(path)
41
+ [ :rm, path ]
42
+ end
43
+
40
44
  private
41
45
  def combine(*commands, by: "&&")
42
46
  commands
@@ -81,6 +85,10 @@ module Kamal::Commands
81
85
  [ :git, *([ "-C", path ] if path), *args.compact ]
82
86
  end
83
87
 
88
+ def grep(*args)
89
+ args.compact.unshift :grep
90
+ end
91
+
84
92
  def tags(**details)
85
93
  Kamal::Tags.from_config(config, **details)
86
94
  end
@@ -32,7 +32,7 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
32
32
  docker(:buildx, :ls)
33
33
  end
34
34
 
35
- def buildx_inspect
35
+ def inspect_builder
36
36
  docker :buildx, :inspect, builder_name unless docker_driver?
37
37
  end
38
38
 
@@ -78,7 +78,7 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
78
78
  end
79
79
 
80
80
  def build_secrets
81
- argumentize "--secret", secrets.collect { |secret| [ "id", secret ] }
81
+ argumentize "--secret", secrets.keys.collect { |secret| [ "id", secret ] }
82
82
  end
83
83
 
84
84
  def build_dockerfile
@@ -101,10 +101,6 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
101
101
  config.builder
102
102
  end
103
103
 
104
- def context_host(builder_name)
105
- docker :context, :inspect, builder_name, "--format", ENDPOINT_DOCKER_HOST_INSPECT
106
- end
107
-
108
104
  def platform_options(arches)
109
105
  argumentize "--platform", arches.map { |arch| "linux/#{arch}" }.join(",") if arches.any?
110
106
  end
@@ -16,6 +16,6 @@ class Kamal::Commands::Builder::Hybrid < Kamal::Commands::Builder::Remote
16
16
  end
17
17
 
18
18
  def append_remote_buildx
19
- docker :buildx, :create, *platform_options(remote_arches), "--append", "--name", builder_name, builder_name
19
+ docker :buildx, :create, *platform_options(remote_arches), "--append", "--name", builder_name, remote_context_name
20
20
  end
21
21
  end
@@ -17,21 +17,44 @@ class Kamal::Commands::Builder::Remote < Kamal::Commands::Builder::Base
17
17
  docker(:buildx, :ls)
18
18
  end
19
19
 
20
+ def inspect_builder
21
+ combine \
22
+ combine inspect_buildx, inspect_remote_context,
23
+ [ "(echo no compatible builder && exit 1)" ],
24
+ by: "||"
25
+ end
26
+
20
27
  private
21
28
  def builder_name
22
- "kamal-remote-#{driver}-#{remote.gsub(/[^a-z0-9_-]/, "-")}"
29
+ "kamal-remote-#{remote.gsub(/[^a-z0-9_-]/, "-")}"
30
+ end
31
+
32
+ def remote_context_name
33
+ "#{builder_name}-context"
34
+ end
35
+
36
+ def inspect_buildx
37
+ pipe \
38
+ docker(:buildx, :inspect, builder_name),
39
+ grep("-q", "Endpoint:.*#{remote_context_name}")
40
+ end
41
+
42
+ def inspect_remote_context
43
+ pipe \
44
+ docker(:context, :inspect, remote_context_name, "--format", ENDPOINT_DOCKER_HOST_INSPECT),
45
+ grep("-xq", remote)
23
46
  end
24
47
 
25
48
  def create_remote_context
26
- docker :context, :create, builder_name, "--description", "'#{builder_name} host'", "--docker", "'host=#{remote}'"
49
+ docker :context, :create, remote_context_name, "--description", "'#{builder_name} host'", "--docker", "'host=#{remote}'"
27
50
  end
28
51
 
29
52
  def remove_remote_context
30
- docker :context, :rm, builder_name
53
+ docker :context, :rm, remote_context_name
31
54
  end
32
55
 
33
56
  def create_buildx
34
- docker :buildx, :create, "--name", builder_name, builder_name
57
+ docker :buildx, :create, "--name", builder_name, remote_context_name
35
58
  end
36
59
 
37
60
  def remove_buildx
@@ -1,7 +1,7 @@
1
1
  require "active_support/core_ext/string/filters"
2
2
 
3
3
  class Kamal::Commands::Builder < Kamal::Commands::Base
4
- delegate :create, :remove, :push, :clean, :pull, :info, :buildx_inspect, :validate_image, :first_mirror, to: :target
4
+ delegate :create, :remove, :push, :clean, :pull, :info, :inspect_builder, :validate_image, :first_mirror, to: :target
5
5
  delegate :local?, :remote?, to: "config.builder"
6
6
 
7
7
  include Clone
@@ -19,6 +19,10 @@ class Kamal::Commands::Docker < Kamal::Commands::Base
19
19
  [ '[ "${EUID:-$(id -u)}" -eq 0 ] || command -v sudo >/dev/null || command -v su >/dev/null' ]
20
20
  end
21
21
 
22
+ def create_network
23
+ docker :network, :create, :kamal
24
+ end
25
+
22
26
  private
23
27
  def get_docker
24
28
  shell \
@@ -1,6 +1,12 @@
1
1
  class Kamal::Commands::Hook < Kamal::Commands::Base
2
- def run(hook, **details)
3
- [ hook_file(hook), env: tags(**details).env ]
2
+ def run(hook)
3
+ [ hook_file(hook) ]
4
+ end
5
+
6
+ def env(secrets: false, **details)
7
+ tags(**details).env.tap do |env|
8
+ env.merge!(config.secrets.to_h) if secrets
9
+ end
4
10
  end
5
11
 
6
12
  def hook_exists?(hook)
@@ -44,14 +44,10 @@ class Kamal::Commands::Lock < Kamal::Commands::Base
44
44
  "/dev/null"
45
45
  end
46
46
 
47
- def locks_dir
48
- File.join(config.run_directory, "locks")
49
- end
50
-
51
47
  def lock_dir
52
- dir_name = [ config.service, config.destination ].compact.join("-")
48
+ dir_name = [ "lock", config.service, config.destination ].compact.join("-")
53
49
 
54
- File.join(locks_dir, dir_name)
50
+ File.join(config.run_directory, dir_name)
55
51
  end
56
52
 
57
53
  def lock_details_file
@@ -0,0 +1,72 @@
1
+ class Kamal::Commands::Proxy < Kamal::Commands::Base
2
+ delegate :argumentize, :optionize, to: Kamal::Utils
3
+
4
+ def run
5
+ docker :run,
6
+ "--name", container_name,
7
+ "--network", "kamal",
8
+ "--detach",
9
+ "--restart", "unless-stopped",
10
+ *config.proxy_publish_args,
11
+ "--volume", "kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy",
12
+ *config.logging_args,
13
+ config.proxy_image
14
+ end
15
+
16
+ def start
17
+ docker :container, :start, container_name
18
+ end
19
+
20
+ def stop(name: container_name)
21
+ docker :container, :stop, name
22
+ end
23
+
24
+ def start_or_run
25
+ combine start, run, by: "||"
26
+ end
27
+
28
+ def info
29
+ docker :ps, "--filter", "name=^#{container_name}$"
30
+ end
31
+
32
+ def version
33
+ pipe \
34
+ docker(:inspect, container_name, "--format '{{.Config.Image}}'"),
35
+ [ :cut, "-d:", "-f2" ]
36
+ end
37
+
38
+ def logs(since: nil, lines: nil, grep: nil, grep_options: nil)
39
+ pipe \
40
+ docker(:logs, container_name, (" --since #{since}" if since), (" --tail #{lines}" if lines), "--timestamps", "2>&1"),
41
+ ("grep '#{grep}'#{" #{grep_options}" if grep_options}" if grep)
42
+ end
43
+
44
+ def follow_logs(host:, grep: nil, grep_options: nil)
45
+ run_over_ssh pipe(
46
+ docker(:logs, container_name, "--timestamps", "--tail", "10", "--follow", "2>&1"),
47
+ (%(grep "#{grep}"#{" #{grep_options}" if grep_options}) if grep)
48
+ ).join(" "), host: host
49
+ end
50
+
51
+ def remove_container
52
+ docker :container, :prune, "--force", "--filter", "label=org.opencontainers.image.title=kamal-proxy"
53
+ end
54
+
55
+ def remove_image
56
+ docker :image, :prune, "--all", "--force", "--filter", "label=org.opencontainers.image.title=kamal-proxy"
57
+ end
58
+
59
+ def cleanup_traefik
60
+ chain \
61
+ docker(:container, :stop, "traefik"),
62
+ combine(
63
+ docker(:container, :prune, "--force", "--filter", "label=org.opencontainers.image.title=Traefik"),
64
+ docker(:image, :prune, "--all", "--force", "--filter", "label=org.opencontainers.image.title=Traefik")
65
+ )
66
+ end
67
+
68
+ private
69
+ def container_name
70
+ config.proxy_container_name
71
+ end
72
+ end
@@ -9,7 +9,7 @@ class Kamal::Commands::Prune < Kamal::Commands::Base
9
9
  def tagged_images
10
10
  pipe \
11
11
  docker(:image, :ls, *service_filter, "--format", "'{{.ID}} {{.Repository}}:{{.Tag}}'"),
12
- "grep -v -w \"#{active_image_list}\"",
12
+ grep("-v -w \"#{active_image_list}\""),
13
13
  "while read image tag; do docker rmi $tag; done"
14
14
  end
15
15
 
@@ -20,10 +20,6 @@ class Kamal::Commands::Prune < Kamal::Commands::Base
20
20
  "while read container_id; do docker rm $container_id; done"
21
21
  end
22
22
 
23
- def healthcheck_containers
24
- docker :container, :prune, "--force", *healthcheck_service_filter
25
- end
26
-
27
23
  private
28
24
  def stopped_containers_filters
29
25
  [ "created", "exited", "dead" ].flat_map { |status| [ "--filter", "status=#{status}" ] }
@@ -39,8 +35,4 @@ class Kamal::Commands::Prune < Kamal::Commands::Base
39
35
  def service_filter
40
36
  [ "--filter", "label=service=#{config.service}" ]
41
37
  end
42
-
43
- def healthcheck_service_filter
44
- [ "--filter", "label=service=#{config.healthcheck_service}" ]
45
- end
46
38
  end
@@ -1,5 +1,15 @@
1
1
  class Kamal::Commands::Server < Kamal::Commands::Base
2
2
  def ensure_run_directory
3
- [ :mkdir, "-p", config.run_directory ]
3
+ make_directory config.run_directory
4
+ end
5
+
6
+ def remove_app_directory
7
+ remove_directory config.app_directory
8
+ end
9
+
10
+ def app_directory_count
11
+ pipe \
12
+ [ :ls, config.apps_directory ],
13
+ [ :wc, "-l" ]
4
14
  end
5
15
  end
@@ -16,7 +16,7 @@ class Kamal::Configuration::Accessory
16
16
 
17
17
  @env = Kamal::Configuration::Env.new \
18
18
  config: accessory_config.fetch("env", {}),
19
- secrets_file: File.join(config.host_env_directory, "accessories", "#{service_name}.env"),
19
+ secrets: config.secrets,
20
20
  context: "accessories/#{name}/env"
21
21
  end
22
22
 
@@ -51,7 +51,19 @@ class Kamal::Configuration::Accessory
51
51
  end
52
52
 
53
53
  def env_args
54
- env.args
54
+ [ *env.clear_args, *argumentize("--env-file", secrets_path) ]
55
+ end
56
+
57
+ def env_directory
58
+ File.join(config.env_directory, "accessories")
59
+ end
60
+
61
+ def secrets_io
62
+ env.secrets_io
63
+ end
64
+
65
+ def secrets_path
66
+ File.join(config.env_directory, "accessories", "#{name}.env")
55
67
  end
56
68
 
57
69
  def files
@@ -28,7 +28,9 @@ class Kamal::Configuration::Builder
28
28
  end
29
29
 
30
30
  def local_arches
31
- @local_arches ||= if remote
31
+ @local_arches ||= if local_disabled?
32
+ []
33
+ elsif remote
32
34
  arches & [ Kamal::Utils.docker_arch ]
33
35
  else
34
36
  arches
@@ -48,7 +50,7 @@ class Kamal::Configuration::Builder
48
50
  end
49
51
 
50
52
  def local?
51
- arches.empty? || local_arches.any?
53
+ !local_disabled? && (arches.empty? || local_arches.any?)
52
54
  end
53
55
 
54
56
  def cached?
@@ -60,7 +62,7 @@ class Kamal::Configuration::Builder
60
62
  end
61
63
 
62
64
  def secrets
63
- builder_config["secrets"] || []
65
+ (builder_config["secrets"] || []).to_h { |key| [ key, config.secrets[key] ] }
64
66
  end
65
67
 
66
68
  def dockerfile
@@ -79,6 +81,10 @@ class Kamal::Configuration::Builder
79
81
  builder_config.fetch("driver", "docker-container")
80
82
  end
81
83
 
84
+ def local_disabled?
85
+ builder_config["local"] == false
86
+ end
87
+
82
88
  def cache_from
83
89
  if cached?
84
90
  case builder_config["cache"]["type"]
@@ -12,24 +12,29 @@
12
12
  #
13
13
  # Options go under the builder key in the root configuration.
14
14
  builder:
15
- # Driver
16
- #
17
- # The build driver to use, defaults to `docker-container`
18
- driver: docker
19
15
 
20
16
  # Arch
21
17
  #
22
- # The architectures to build for, defaults to `[ amd64, arm64 ]`
23
- # Unless you are using the docker driver, when it defaults to the local architecture
24
- # You can set an array or just a single value
18
+ # The architectures to build for - you can set an array or just a single value.
19
+ #
20
+ # Allowed values are `amd64` and `arm64`
25
21
  arch:
26
22
  - amd64
27
23
 
28
- # Remote configuration
24
+ # Remote
29
25
  #
30
- # If you have a remote builder, you can configure it here
26
+ # The connection string for a remote builder. If supplied Kamal will use this
27
+ # for builds that do not match the local architecture of the deployment host.
31
28
  remote: ssh://docker@docker-builder
32
29
 
30
+ # Local
31
+ #
32
+ # If set to false, Kamal will always use the remote builder even when building
33
+ # the local architecture.
34
+ #
35
+ # Defaults to true
36
+ local: true
37
+
33
38
  # Builder cache
34
39
  #
35
40
  # The type must be either 'gha' or 'registry'
@@ -73,7 +78,7 @@ builder:
73
78
 
74
79
  # Build secrets
75
80
  #
76
- # Values are read from the environment.
81
+ # Values are read from the .kamal/secrets.
77
82
  #
78
83
  secrets:
79
84
  - SECRET1
@@ -98,3 +103,8 @@ builder:
98
103
  #
99
104
  # SSH agent socket or keys to expose to the build
100
105
  ssh: default=$SSH_AUTH_SOCK
106
+
107
+ # Driver
108
+ #
109
+ # The build driver to use, defaults to `docker-container`
110
+ driver: docker
@@ -70,7 +70,7 @@ env:
70
70
  # volume containing both sets of files.
71
71
  # This requires that file names change when the contents change
72
72
  # (e.g. by including a hash of the contents in the name).
73
-
73
+ #
74
74
  # To configure this, set the path to the assets:
75
75
  asset_path: /path/to/assets
76
76
 
@@ -93,11 +93,6 @@ primary_role: workers
93
93
  # Whether roles with no servers are allowed. Defaults to `false`.
94
94
  allow_empty_roles: false
95
95
 
96
- # Stop wait time
97
- #
98
- # How long we wait for a container to stop before killing it, defaults to 30 seconds
99
- stop_wait_time: 60
100
-
101
96
  # Retain containers
102
97
  #
103
98
  # How many old containers and images we retain, defaults to 5
@@ -111,9 +106,20 @@ minimum_version: 1.3.0
111
106
  # Readiness delay
112
107
  #
113
108
  # Seconds to wait for a container to boot after is running, default 7
114
- # This only applies to containers that do not specify a healthcheck
109
+ #
110
+ # This only applies to containers that do not run a proxy or specify a healthcheck
115
111
  readiness_delay: 4
116
112
 
113
+ # Deploy timeout
114
+ #
115
+ # How long to wait for a container to become ready, default 30
116
+ deploy_timeout: 10
117
+
118
+ # Drain timeout
119
+ #
120
+ # How long to wait for a containers to drain, default 30
121
+ drain_timeout: 10
122
+
117
123
  # Run directory
118
124
  #
119
125
  # Directory to store kamal runtime files in on the host, default `.kamal`
@@ -137,10 +143,10 @@ builder:
137
143
  accessories:
138
144
  ...
139
145
 
140
- # Traefik
146
+ # Proxy
141
147
  #
142
- # The Traefik proxy is used for zero-downtime deployments, see kamal docs traefik
143
- traefik:
148
+ # Configuration for kamal-proxy, see kamal docs proxy
149
+ proxy:
144
150
  ...
145
151
 
146
152
  # SSHKit
@@ -155,12 +161,6 @@ sshkit:
155
161
  boot:
156
162
  ...
157
163
 
158
- # Healthcheck
159
- #
160
- # Configuring healthcheck commands, intervals and timeouts, see kamal docs healthcheck
161
- healthcheck:
162
- ...
163
-
164
164
  # Logging
165
165
  #
166
166
  # Docker logging configuration, see kamal docs logging
@@ -1,7 +1,7 @@
1
1
  # Environment variables
2
2
  #
3
- # Environment variables can be set directory in the Kamal configuration or
4
- # for loaded from a .env file, for secrets that should not be checked into Git.
3
+ # Environment variables can be set directly in the Kamal configuration or
4
+ # read from .kamal/secrets.
5
5
 
6
6
  # Reading environment variables from the configuration
7
7
  #
@@ -12,26 +12,25 @@ env:
12
12
  DATABASE_HOST: mysql-db1
13
13
  DATABASE_PORT: 3306
14
14
 
15
- # Using .env file to load required environment variables
15
+ # Using .kamal/secrets file to load required environment variables
16
16
  #
17
- # Kamal uses dotenv to automatically load environment variables set in the .env file present
18
- # in the application root.
17
+ # Kamal uses dotenv to automatically load environment variables set in the .kamal/secrets file.
19
18
  #
20
19
  # This file can be used to set variables like KAMAL_REGISTRY_PASSWORD or database passwords.
21
- # But for this reason you must ensure that .env files are not checked into Git or included
22
- # in your Dockerfile! The format is just key-value like:
20
+ # You can use variable or command substitution in the secrets file.
21
+ #
23
22
  # ```
24
- # KAMAL_REGISTRY_PASSWORD=pw
25
- # DB_PASSWORD=secret123
23
+ # KAMAL_REGISTRY_PASSWORD=$KAMAL_REGISTRY_PASSWORD
24
+ # RAILS_MASTER_KEY=$(cat config/master.key)
26
25
  # ```
27
- # See https://kamal-deploy.org/docs/commands/envify/ for how to use generated .env files.
26
+ #
27
+ # If you store secrets directly in .kamal/secrets, ensure that it is not checked into version control.
28
28
  #
29
29
  # To pass the secrets you should list them under the `secret` key. When you do this the
30
30
  # other variables need to be moved under the `clear` key.
31
31
  #
32
32
  # Unlike clear values, secrets are not passed directly to the container,
33
33
  # but are stored in an env file on the host
34
- # The file is not updated when deploying, only when running `kamal envify` or `kamal env push`.
35
34
  env:
36
35
  clear:
37
36
  DB_USER: app