kamal 1.8.2 → 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.
Files changed (89) 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/alias/command.rb +9 -0
  5. data/lib/kamal/cli/app/boot.rb +22 -16
  6. data/lib/kamal/cli/app.rb +40 -5
  7. data/lib/kamal/cli/base.rb +19 -51
  8. data/lib/kamal/cli/build.rb +12 -13
  9. data/lib/kamal/cli/healthcheck/barrier.rb +2 -0
  10. data/lib/kamal/cli/healthcheck/poller.rb +18 -39
  11. data/lib/kamal/cli/lock.rb +2 -3
  12. data/lib/kamal/cli/main.rb +54 -51
  13. data/lib/kamal/cli/proxy.rb +224 -0
  14. data/lib/kamal/cli/prune.rb +0 -1
  15. data/lib/kamal/cli/secrets.rb +36 -0
  16. data/lib/kamal/cli/server.rb +2 -3
  17. data/lib/kamal/cli/templates/deploy.yml +4 -21
  18. data/lib/kamal/cli/templates/sample_hooks/post-proxy-reboot.sample +3 -0
  19. data/lib/kamal/cli/templates/secrets +16 -0
  20. data/lib/kamal/cli.rb +1 -0
  21. data/lib/kamal/commander/specifics.rb +3 -3
  22. data/lib/kamal/commander.rb +24 -8
  23. data/lib/kamal/commands/accessory.rb +7 -7
  24. data/lib/kamal/commands/app/assets.rb +8 -8
  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 +26 -13
  30. data/lib/kamal/commands/builder/hybrid.rb +21 -0
  31. data/lib/kamal/commands/builder/local.rb +14 -0
  32. data/lib/kamal/commands/builder/remote.rb +63 -0
  33. data/lib/kamal/commands/builder.rb +13 -29
  34. data/lib/kamal/commands/docker.rb +4 -0
  35. data/lib/kamal/commands/hook.rb +5 -2
  36. data/lib/kamal/commands/lock.rb +2 -6
  37. data/lib/kamal/commands/proxy.rb +77 -0
  38. data/lib/kamal/commands/prune.rb +1 -9
  39. data/lib/kamal/commands/server.rb +11 -1
  40. data/lib/kamal/configuration/accessory.rb +14 -2
  41. data/lib/kamal/configuration/alias.rb +15 -0
  42. data/lib/kamal/configuration/builder.rb +52 -18
  43. data/lib/kamal/configuration/docs/alias.yml +26 -0
  44. data/lib/kamal/configuration/docs/builder.yml +26 -23
  45. data/lib/kamal/configuration/docs/configuration.yml +22 -16
  46. data/lib/kamal/configuration/docs/env.yml +10 -11
  47. data/lib/kamal/configuration/docs/proxy.yml +100 -0
  48. data/lib/kamal/configuration/docs/registry.yml +4 -2
  49. data/lib/kamal/configuration/docs/role.yml +3 -5
  50. data/lib/kamal/configuration/env/tag.rb +4 -3
  51. data/lib/kamal/configuration/env.rb +10 -17
  52. data/lib/kamal/configuration/proxy.rb +66 -0
  53. data/lib/kamal/configuration/registry.rb +3 -2
  54. data/lib/kamal/configuration/role.rb +63 -94
  55. data/lib/kamal/configuration/validator/alias.rb +15 -0
  56. data/lib/kamal/configuration/validator/builder.rb +4 -0
  57. data/lib/kamal/configuration/validator/proxy.rb +11 -0
  58. data/lib/kamal/configuration/validator.rb +42 -24
  59. data/lib/kamal/configuration.rb +91 -33
  60. data/lib/kamal/env_file.rb +4 -0
  61. data/lib/kamal/secrets/adapters/base.rb +18 -0
  62. data/lib/kamal/secrets/adapters/bitwarden.rb +64 -0
  63. data/lib/kamal/secrets/adapters/last_pass.rb +30 -0
  64. data/lib/kamal/secrets/adapters/one_password.rb +61 -0
  65. data/lib/kamal/secrets/adapters/test.rb +10 -0
  66. data/lib/kamal/secrets/adapters.rb +14 -0
  67. data/lib/kamal/secrets/dotenv/inline_command_substitution.rb +32 -0
  68. data/lib/kamal/secrets.rb +37 -0
  69. data/lib/kamal/sshkit_with_ext.rb +1 -0
  70. data/lib/kamal/utils.rb +28 -0
  71. data/lib/kamal/version.rb +1 -1
  72. data/lib/kamal.rb +3 -1
  73. metadata +32 -23
  74. data/lib/kamal/cli/env.rb +0 -54
  75. data/lib/kamal/cli/templates/sample_hooks/post-traefik-reboot.sample +0 -3
  76. data/lib/kamal/cli/templates/template.env +0 -2
  77. data/lib/kamal/cli/traefik.rb +0 -122
  78. data/lib/kamal/commands/app/cord.rb +0 -22
  79. data/lib/kamal/commands/builder/multiarch/remote.rb +0 -61
  80. data/lib/kamal/commands/builder/multiarch.rb +0 -41
  81. data/lib/kamal/commands/builder/native/cached.rb +0 -25
  82. data/lib/kamal/commands/builder/native/remote.rb +0 -67
  83. data/lib/kamal/commands/builder/native.rb +0 -20
  84. data/lib/kamal/commands/traefik.rb +0 -85
  85. data/lib/kamal/configuration/docs/healthcheck.yml +0 -59
  86. data/lib/kamal/configuration/docs/traefik.yml +0 -62
  87. data/lib/kamal/configuration/healthcheck.rb +0 -63
  88. data/lib/kamal/configuration/traefik.rb +0 -60
  89. /data/lib/kamal/cli/templates/sample_hooks/{pre-traefik-reboot.sample → pre-proxy-reboot.sample} +0 -0
@@ -1,7 +1,9 @@
1
1
  class Kamal::Commands::Accessory < Kamal::Commands::Base
2
2
  attr_reader :accessory_config
3
3
  delegate :service_name, :image, :hosts, :port, :files, :directories, :cmd,
4
- :publish_args, :env_args, :volume_args, :label_args, :option_args, to: :accessory_config
4
+ :publish_args, :env_args, :volume_args, :label_args, :option_args,
5
+ :secrets_io, :secrets_path, :env_directory,
6
+ to: :accessory_config
5
7
 
6
8
  def initialize(config, name:)
7
9
  super(config)
@@ -13,6 +15,7 @@ class Kamal::Commands::Accessory < Kamal::Commands::Base
13
15
  "--name", service_name,
14
16
  "--detach",
15
17
  "--restart", "unless-stopped",
18
+ "--network", "kamal",
16
19
  *config.logging_args,
17
20
  *publish_args,
18
21
  *env_args,
@@ -61,6 +64,7 @@ class Kamal::Commands::Accessory < Kamal::Commands::Base
61
64
  docker :run,
62
65
  ("-it" if interactive),
63
66
  "--rm",
67
+ "--network", "kamal",
64
68
  *env_args,
65
69
  *volume_args,
66
70
  image,
@@ -98,12 +102,8 @@ class Kamal::Commands::Accessory < Kamal::Commands::Base
98
102
  docker :image, :rm, "--force", image
99
103
  end
100
104
 
101
- def make_env_directory
102
- make_directory accessory_config.env.secrets_directory
103
- end
104
-
105
- def remove_env_file
106
- [ :rm, "-f", accessory_config.env.secrets_file ]
105
+ def ensure_env_directory
106
+ make_directory env_directory
107
107
  end
108
108
 
109
109
  private
@@ -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
@@ -1,20 +1,41 @@
1
-
2
1
  class Kamal::Commands::Builder::Base < Kamal::Commands::Base
3
2
  class BuilderError < StandardError; end
4
3
 
5
4
  ENDPOINT_DOCKER_HOST_INSPECT = "'{{.Endpoints.docker.Host}}'"
6
5
 
7
6
  delegate :argumentize, to: Kamal::Utils
8
- delegate :args, :secrets, :dockerfile, :target, :local_arch, :local_host, :remote_arch, :remote_host, :cache_from, :cache_to, :ssh, to: :builder_config
7
+ delegate \
8
+ :args, :secrets, :dockerfile, :target, :arches, :local_arches, :remote_arches, :remote,
9
+ :cache_from, :cache_to, :ssh, :driver, :docker_driver?,
10
+ to: :builder_config
9
11
 
10
12
  def clean
11
13
  docker :image, :rm, "--force", config.absolute_image
12
14
  end
13
15
 
16
+ def push
17
+ docker :buildx, :build,
18
+ "--push",
19
+ *platform_options(arches),
20
+ *([ "--builder", builder_name ] unless docker_driver?),
21
+ *build_options,
22
+ build_context
23
+ end
24
+
14
25
  def pull
15
26
  docker :pull, config.absolute_image
16
27
  end
17
28
 
29
+ def info
30
+ combine \
31
+ docker(:context, :ls),
32
+ docker(:buildx, :ls)
33
+ end
34
+
35
+ def inspect_builder
36
+ docker :buildx, :inspect, builder_name unless docker_driver?
37
+ end
38
+
18
39
  def build_options
19
40
  [ *build_tags, *build_cache, *build_labels, *build_args, *build_secrets, *build_dockerfile, *build_target, *build_ssh ]
20
41
  end
@@ -32,14 +53,6 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
32
53
  )
33
54
  end
34
55
 
35
- def context_hosts
36
- :true
37
- end
38
-
39
- def config_context_hosts
40
- []
41
- end
42
-
43
56
  def first_mirror
44
57
  docker(:info, "--format '{{index .RegistryConfig.Mirrors 0}}'")
45
58
  end
@@ -65,7 +78,7 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
65
78
  end
66
79
 
67
80
  def build_secrets
68
- argumentize "--secret", secrets.collect { |secret| [ "id", secret ] }
81
+ argumentize "--secret", secrets.keys.collect { |secret| [ "id", secret ] }
69
82
  end
70
83
 
71
84
  def build_dockerfile
@@ -88,7 +101,7 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
88
101
  config.builder
89
102
  end
90
103
 
91
- def context_host(builder_name)
92
- docker :context, :inspect, builder_name, "--format", ENDPOINT_DOCKER_HOST_INSPECT
104
+ def platform_options(arches)
105
+ argumentize "--platform", arches.map { |arch| "linux/#{arch}" }.join(",") if arches.any?
93
106
  end
94
107
  end
@@ -0,0 +1,21 @@
1
+ class Kamal::Commands::Builder::Hybrid < Kamal::Commands::Builder::Remote
2
+ def create
3
+ combine \
4
+ create_local_buildx,
5
+ create_remote_context,
6
+ append_remote_buildx
7
+ end
8
+
9
+ private
10
+ def builder_name
11
+ "kamal-hybrid-#{driver}-#{remote.gsub(/[^a-z0-9_-]/, "-")}"
12
+ end
13
+
14
+ def create_local_buildx
15
+ docker :buildx, :create, *platform_options(local_arches), "--name", builder_name, "--driver=#{driver}"
16
+ end
17
+
18
+ def append_remote_buildx
19
+ docker :buildx, :create, *platform_options(remote_arches), "--append", "--name", builder_name, remote_context_name
20
+ end
21
+ end
@@ -0,0 +1,14 @@
1
+ class Kamal::Commands::Builder::Local < Kamal::Commands::Builder::Base
2
+ def create
3
+ docker :buildx, :create, "--name", builder_name, "--driver=#{driver}" unless docker_driver?
4
+ end
5
+
6
+ def remove
7
+ docker :buildx, :rm, builder_name unless docker_driver?
8
+ end
9
+
10
+ private
11
+ def builder_name
12
+ "kamal-local-#{driver}"
13
+ end
14
+ end
@@ -0,0 +1,63 @@
1
+ class Kamal::Commands::Builder::Remote < Kamal::Commands::Builder::Base
2
+ def create
3
+ chain \
4
+ create_remote_context,
5
+ create_buildx
6
+ end
7
+
8
+ def remove
9
+ chain \
10
+ remove_remote_context,
11
+ remove_buildx
12
+ end
13
+
14
+ def info
15
+ chain \
16
+ docker(:context, :ls),
17
+ docker(:buildx, :ls)
18
+ end
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
+
27
+ private
28
+ def builder_name
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)
46
+ end
47
+
48
+ def create_remote_context
49
+ docker :context, :create, remote_context_name, "--description", "'#{builder_name} host'", "--docker", "'host=#{remote}'"
50
+ end
51
+
52
+ def remove_remote_context
53
+ docker :context, :rm, remote_context_name
54
+ end
55
+
56
+ def create_buildx
57
+ docker :buildx, :create, "--name", builder_name, remote_context_name
58
+ end
59
+
60
+ def remove_buildx
61
+ docker :buildx, :rm, builder_name
62
+ end
63
+ end
@@ -1,8 +1,8 @@
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, :context_hosts, :config_context_hosts, :validate_image,
5
- :first_mirror, to: :target
4
+ delegate :create, :remove, :push, :clean, :pull, :info, :inspect_builder, :validate_image, :first_mirror, to: :target
5
+ delegate :local?, :remote?, to: "config.builder"
6
6
 
7
7
  include Clone
8
8
 
@@ -11,43 +11,27 @@ class Kamal::Commands::Builder < Kamal::Commands::Base
11
11
  end
12
12
 
13
13
  def target
14
- if config.builder.multiarch?
15
- if config.builder.remote?
16
- if config.builder.local?
17
- multiarch_remote
18
- else
19
- native_remote
20
- end
14
+ if remote?
15
+ if local?
16
+ hybrid
21
17
  else
22
- multiarch
18
+ remote
23
19
  end
24
20
  else
25
- if config.builder.cached?
26
- native_cached
27
- else
28
- native
29
- end
21
+ local
30
22
  end
31
23
  end
32
24
 
33
- def native
34
- @native ||= Kamal::Commands::Builder::Native.new(config)
35
- end
36
-
37
- def native_cached
38
- @native ||= Kamal::Commands::Builder::Native::Cached.new(config)
39
- end
40
-
41
- def native_remote
42
- @native ||= Kamal::Commands::Builder::Native::Remote.new(config)
25
+ def remote
26
+ @remote ||= Kamal::Commands::Builder::Remote.new(config)
43
27
  end
44
28
 
45
- def multiarch
46
- @multiarch ||= Kamal::Commands::Builder::Multiarch.new(config)
29
+ def local
30
+ @local ||= Kamal::Commands::Builder::Local.new(config)
47
31
  end
48
32
 
49
- def multiarch_remote
50
- @multiarch_remote ||= Kamal::Commands::Builder::Multiarch::Remote.new(config)
33
+ def hybrid
34
+ @hybrid ||= Kamal::Commands::Builder::Hybrid.new(config)
51
35
  end
52
36
 
53
37
 
@@ -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
@@ -0,0 +1,15 @@
1
+ class Kamal::Configuration::Alias
2
+ include Kamal::Configuration::Validation
3
+
4
+ attr_reader :name, :command
5
+
6
+ def initialize(name, config:)
7
+ @name, @command = name.inquiry, config.raw_config["aliases"][name]
8
+
9
+ validate! \
10
+ command,
11
+ example: validation_yml["aliases"]["uname"],
12
+ context: "aliases/#{name}",
13
+ with: Kamal::Configuration::Validator::Alias
14
+ end
15
+ end