kamal 1.8.3 → 2.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
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 -65
  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