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
@@ -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
  ]
@@ -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,9 @@
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, secrets: false, **details)
3
+ env = tags(**details).env
4
+ env.merge!(config.secrets.to_h) if secrets
5
+
6
+ [ hook_file(hook), env: env ]
4
7
  end
5
8
 
6
9
  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,77 @@
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", "/var/run/docker.sock:/var/run/docker.sock",
12
+ *config.proxy_config_volume.docker_args,
13
+ *config.logging_args,
14
+ config.proxy_image
15
+ end
16
+
17
+ def start
18
+ docker :container, :start, container_name
19
+ end
20
+
21
+ def stop(name: container_name)
22
+ docker :container, :stop, name
23
+ end
24
+
25
+ def start_or_run
26
+ combine start, run, by: "||"
27
+ end
28
+
29
+ def info
30
+ docker :ps, "--filter", "name=^#{container_name}$"
31
+ end
32
+
33
+ def version
34
+ pipe \
35
+ docker(:inspect, container_name, "--format '{{.Config.Image}}'"),
36
+ [ :cut, "-d:", "-f2" ]
37
+ end
38
+
39
+ def logs(since: nil, lines: nil, grep: nil, grep_options: nil)
40
+ pipe \
41
+ docker(:logs, container_name, (" --since #{since}" if since), (" --tail #{lines}" if lines), "--timestamps", "2>&1"),
42
+ ("grep '#{grep}'#{" #{grep_options}" if grep_options}" if grep)
43
+ end
44
+
45
+ def follow_logs(host:, grep: nil, grep_options: nil)
46
+ run_over_ssh pipe(
47
+ docker(:logs, container_name, "--timestamps", "--tail", "10", "--follow", "2>&1"),
48
+ (%(grep "#{grep}"#{" #{grep_options}" if grep_options}) if grep)
49
+ ).join(" "), host: host
50
+ end
51
+
52
+ def remove_container
53
+ docker :container, :prune, "--force", "--filter", "label=org.opencontainers.image.title=kamal-proxy"
54
+ end
55
+
56
+ def remove_image
57
+ docker :image, :prune, "--all", "--force", "--filter", "label=org.opencontainers.image.title=kamal-proxy"
58
+ end
59
+
60
+ def remove_host_directory
61
+ remove_directory config.proxy_directory
62
+ end
63
+
64
+ def cleanup_traefik
65
+ chain \
66
+ docker(:container, :stop, "traefik"),
67
+ combine(
68
+ docker(:container, :prune, "--force", "--filter", "label=org.opencontainers.image.title=Traefik"),
69
+ docker(:image, :prune, "--all", "--force", "--filter", "label=org.opencontainers.image.title=Traefik")
70
+ )
71
+ end
72
+
73
+ private
74
+ def container_name
75
+ config.proxy_container_name
76
+ end
77
+ 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