kamal 1.8.3 → 2.7.0

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 (130) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/kamal/cli/accessory.rb +92 -38
  4. data/lib/kamal/cli/alias/command.rb +10 -0
  5. data/lib/kamal/cli/app/{prepare_assets.rb → assets.rb} +1 -1
  6. data/lib/kamal/cli/app/boot.rb +23 -16
  7. data/lib/kamal/cli/app/error_pages.rb +33 -0
  8. data/lib/kamal/cli/app/ssl_certificates.rb +28 -0
  9. data/lib/kamal/cli/app.rb +132 -30
  10. data/lib/kamal/cli/base.rb +57 -53
  11. data/lib/kamal/cli/build.rb +81 -38
  12. data/lib/kamal/cli/healthcheck/barrier.rb +2 -0
  13. data/lib/kamal/cli/healthcheck/poller.rb +18 -39
  14. data/lib/kamal/cli/lock.rb +2 -3
  15. data/lib/kamal/cli/main.rb +60 -59
  16. data/lib/kamal/cli/proxy.rb +290 -0
  17. data/lib/kamal/cli/prune.rb +0 -1
  18. data/lib/kamal/cli/registry.rb +2 -0
  19. data/lib/kamal/cli/secrets.rb +49 -0
  20. data/lib/kamal/cli/server.rb +6 -5
  21. data/lib/kamal/cli/templates/deploy.yml +53 -53
  22. data/lib/kamal/cli/templates/sample_hooks/docker-setup.sample +2 -12
  23. data/lib/kamal/cli/templates/sample_hooks/post-app-boot.sample +3 -0
  24. data/lib/kamal/cli/templates/sample_hooks/post-deploy.sample +1 -1
  25. data/lib/kamal/cli/templates/sample_hooks/post-proxy-reboot.sample +3 -0
  26. data/lib/kamal/cli/templates/sample_hooks/pre-app-boot.sample +3 -0
  27. data/lib/kamal/cli/templates/sample_hooks/pre-build.sample +1 -1
  28. data/lib/kamal/cli/templates/sample_hooks/pre-connect.sample +1 -1
  29. data/lib/kamal/cli/templates/sample_hooks/pre-deploy.sample +19 -6
  30. data/lib/kamal/cli/templates/sample_hooks/pre-proxy-reboot.sample +3 -0
  31. data/lib/kamal/cli/templates/secrets +17 -0
  32. data/lib/kamal/cli.rb +2 -0
  33. data/lib/kamal/commander/specifics.rb +19 -6
  34. data/lib/kamal/commander.rb +39 -32
  35. data/lib/kamal/commands/accessory/proxy.rb +16 -0
  36. data/lib/kamal/commands/accessory.rb +19 -19
  37. data/lib/kamal/commands/app/assets.rb +10 -10
  38. data/lib/kamal/commands/app/containers.rb +2 -2
  39. data/lib/kamal/commands/app/error_pages.rb +9 -0
  40. data/lib/kamal/commands/app/execution.rb +7 -4
  41. data/lib/kamal/commands/app/images.rb +1 -1
  42. data/lib/kamal/commands/app/logging.rb +16 -6
  43. data/lib/kamal/commands/app/proxy.rb +32 -0
  44. data/lib/kamal/commands/app.rb +25 -24
  45. data/lib/kamal/commands/auditor.rb +12 -3
  46. data/lib/kamal/commands/base.rb +54 -8
  47. data/lib/kamal/commands/builder/base.rb +46 -16
  48. data/lib/kamal/commands/builder/clone.rb +16 -14
  49. data/lib/kamal/commands/builder/cloud.rb +22 -0
  50. data/lib/kamal/commands/builder/hybrid.rb +21 -0
  51. data/lib/kamal/commands/builder/local.rb +14 -0
  52. data/lib/kamal/commands/builder/pack.rb +46 -0
  53. data/lib/kamal/commands/builder/remote.rb +63 -0
  54. data/lib/kamal/commands/builder.rb +21 -45
  55. data/lib/kamal/commands/docker.rb +4 -0
  56. data/lib/kamal/commands/hook.rb +8 -2
  57. data/lib/kamal/commands/lock.rb +2 -6
  58. data/lib/kamal/commands/proxy.rb +127 -0
  59. data/lib/kamal/commands/prune.rb +1 -9
  60. data/lib/kamal/commands/registry.rb +9 -7
  61. data/lib/kamal/commands/server.rb +11 -1
  62. data/lib/kamal/configuration/accessory.rb +89 -12
  63. data/lib/kamal/configuration/alias.rb +15 -0
  64. data/lib/kamal/configuration/builder.rb +73 -15
  65. data/lib/kamal/configuration/docs/accessory.yml +53 -15
  66. data/lib/kamal/configuration/docs/alias.yml +26 -0
  67. data/lib/kamal/configuration/docs/boot.yml +3 -3
  68. data/lib/kamal/configuration/docs/builder.yml +63 -38
  69. data/lib/kamal/configuration/docs/configuration.yml +62 -46
  70. data/lib/kamal/configuration/docs/env.yml +61 -17
  71. data/lib/kamal/configuration/docs/logging.yml +3 -3
  72. data/lib/kamal/configuration/docs/proxy.yml +168 -0
  73. data/lib/kamal/configuration/docs/registry.yml +20 -13
  74. data/lib/kamal/configuration/docs/role.yml +14 -13
  75. data/lib/kamal/configuration/docs/servers.yml +2 -2
  76. data/lib/kamal/configuration/docs/ssh.yml +23 -19
  77. data/lib/kamal/configuration/docs/sshkit.yml +4 -4
  78. data/lib/kamal/configuration/env/tag.rb +4 -3
  79. data/lib/kamal/configuration/env.rb +19 -17
  80. data/lib/kamal/configuration/proxy/boot.rb +129 -0
  81. data/lib/kamal/configuration/proxy.rb +124 -0
  82. data/lib/kamal/configuration/registry.rb +7 -6
  83. data/lib/kamal/configuration/role.rb +69 -98
  84. data/lib/kamal/configuration/servers.rb +8 -1
  85. data/lib/kamal/configuration/validator/accessory.rb +6 -2
  86. data/lib/kamal/configuration/validator/alias.rb +15 -0
  87. data/lib/kamal/configuration/validator/builder.rb +6 -0
  88. data/lib/kamal/configuration/validator/proxy.rb +25 -0
  89. data/lib/kamal/configuration/validator/role.rb +3 -1
  90. data/lib/kamal/configuration/validator/servers.rb +1 -1
  91. data/lib/kamal/configuration/validator.rb +62 -24
  92. data/lib/kamal/configuration.rb +96 -50
  93. data/lib/kamal/docker.rb +30 -0
  94. data/lib/kamal/env_file.rb +7 -1
  95. data/lib/kamal/git.rb +10 -0
  96. data/lib/kamal/secrets/adapters/aws_secrets_manager.rb +51 -0
  97. data/lib/kamal/secrets/adapters/base.rb +33 -0
  98. data/lib/kamal/secrets/adapters/bitwarden.rb +81 -0
  99. data/lib/kamal/secrets/adapters/bitwarden_secrets_manager.rb +66 -0
  100. data/lib/kamal/secrets/adapters/doppler.rb +57 -0
  101. data/lib/kamal/secrets/adapters/enpass.rb +71 -0
  102. data/lib/kamal/secrets/adapters/gcp_secret_manager.rb +112 -0
  103. data/lib/kamal/secrets/adapters/last_pass.rb +40 -0
  104. data/lib/kamal/secrets/adapters/one_password.rb +104 -0
  105. data/lib/kamal/secrets/adapters/passbolt.rb +130 -0
  106. data/lib/kamal/secrets/adapters/test.rb +14 -0
  107. data/lib/kamal/secrets/adapters.rb +16 -0
  108. data/lib/kamal/secrets/dotenv/inline_command_substitution.rb +33 -0
  109. data/lib/kamal/secrets.rb +42 -0
  110. data/lib/kamal/sshkit_with_ext.rb +1 -0
  111. data/lib/kamal/utils.rb +30 -0
  112. data/lib/kamal/version.rb +1 -1
  113. data/lib/kamal.rb +3 -1
  114. metadata +63 -36
  115. data/lib/kamal/cli/env.rb +0 -54
  116. data/lib/kamal/cli/templates/sample_hooks/post-traefik-reboot.sample +0 -3
  117. data/lib/kamal/cli/templates/sample_hooks/pre-traefik-reboot.sample +0 -3
  118. data/lib/kamal/cli/templates/template.env +0 -2
  119. data/lib/kamal/cli/traefik.rb +0 -122
  120. data/lib/kamal/commands/app/cord.rb +0 -22
  121. data/lib/kamal/commands/builder/multiarch/remote.rb +0 -65
  122. data/lib/kamal/commands/builder/multiarch.rb +0 -41
  123. data/lib/kamal/commands/builder/native/cached.rb +0 -25
  124. data/lib/kamal/commands/builder/native/remote.rb +0 -67
  125. data/lib/kamal/commands/builder/native.rb +0 -20
  126. data/lib/kamal/commands/traefik.rb +0 -85
  127. data/lib/kamal/configuration/docs/healthcheck.yml +0 -59
  128. data/lib/kamal/configuration/docs/traefik.yml +0 -62
  129. data/lib/kamal/configuration/healthcheck.rb +0 -63
  130. data/lib/kamal/configuration/traefik.rb +0 -60
@@ -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,14 +1,16 @@
1
1
  class Kamal::Commands::Registry < Kamal::Commands::Base
2
- delegate :registry, to: :config
2
+ def login(registry_config: nil)
3
+ registry_config ||= config.registry
3
4
 
4
- def login
5
5
  docker :login,
6
- registry.server,
7
- "-u", sensitive(Kamal::Utils.escape_shell_value(registry.username)),
8
- "-p", sensitive(Kamal::Utils.escape_shell_value(registry.password))
6
+ registry_config.server,
7
+ "-u", sensitive(Kamal::Utils.escape_shell_value(registry_config.username)),
8
+ "-p", sensitive(Kamal::Utils.escape_shell_value(registry_config.password))
9
9
  end
10
10
 
11
- def logout
12
- docker :logout, registry.server
11
+ def logout(registry_config: nil)
12
+ registry_config ||= config.registry
13
+
14
+ docker :logout, registry_config.server
13
15
  end
14
16
  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
@@ -1,9 +1,11 @@
1
1
  class Kamal::Configuration::Accessory
2
2
  include Kamal::Configuration::Validation
3
3
 
4
+ DEFAULT_NETWORK = "kamal"
5
+
4
6
  delegate :argumentize, :optionize, to: Kamal::Utils
5
7
 
6
- attr_reader :name, :accessory_config, :env
8
+ attr_reader :name, :env, :proxy, :registry
7
9
 
8
10
  def initialize(name, config:)
9
11
  @name, @config, @accessory_config = name.inquiry, config, config.raw_config["accessories"][name]
@@ -14,10 +16,11 @@ class Kamal::Configuration::Accessory
14
16
  context: "accessories/#{name}",
15
17
  with: Kamal::Configuration::Validator::Accessory
16
18
 
17
- @env = Kamal::Configuration::Env.new \
18
- config: accessory_config.fetch("env", {}),
19
- secrets_file: File.join(config.host_env_directory, "accessories", "#{service_name}.env"),
20
- context: "accessories/#{name}/env"
19
+ ensure_valid_roles
20
+
21
+ @env = initialize_env
22
+ @proxy = initialize_proxy if running_proxy?
23
+ @registry = initialize_registry if accessory_config["registry"].present?
21
24
  end
22
25
 
23
26
  def service_name
@@ -25,11 +28,11 @@ class Kamal::Configuration::Accessory
25
28
  end
26
29
 
27
30
  def image
28
- accessory_config["image"]
31
+ [ registry&.server, accessory_config["image"] ].compact.join("/")
29
32
  end
30
33
 
31
34
  def hosts
32
- hosts_from_host || hosts_from_hosts || hosts_from_roles
35
+ hosts_from_host || hosts_from_hosts || hosts_from_roles || hosts_from_tags
33
36
  end
34
37
 
35
38
  def port
@@ -38,6 +41,10 @@ class Kamal::Configuration::Accessory
38
41
  end
39
42
  end
40
43
 
44
+ def network_args
45
+ argumentize "--network", network
46
+ end
47
+
41
48
  def publish_args
42
49
  argumentize "--publish", port if port
43
50
  end
@@ -51,7 +58,19 @@ class Kamal::Configuration::Accessory
51
58
  end
52
59
 
53
60
  def env_args
54
- env.args
61
+ [ *env.clear_args, *argumentize("--env-file", secrets_path) ]
62
+ end
63
+
64
+ def env_directory
65
+ File.join(config.env_directory, "accessories")
66
+ end
67
+
68
+ def secrets_io
69
+ env.secrets_io
70
+ end
71
+
72
+ def secrets_path
73
+ File.join(config.env_directory, "accessories", "#{name}.env")
55
74
  end
56
75
 
57
76
  def files
@@ -88,8 +107,34 @@ class Kamal::Configuration::Accessory
88
107
  accessory_config["cmd"]
89
108
  end
90
109
 
110
+ def running_proxy?
111
+ accessory_config["proxy"].present?
112
+ end
113
+
91
114
  private
92
- attr_accessor :config
115
+ attr_reader :config, :accessory_config
116
+
117
+ def initialize_env
118
+ Kamal::Configuration::Env.new \
119
+ config: accessory_config.fetch("env", {}),
120
+ secrets: config.secrets,
121
+ context: "accessories/#{name}/env"
122
+ end
123
+
124
+ def initialize_proxy
125
+ Kamal::Configuration::Proxy.new \
126
+ config: config,
127
+ proxy_config: accessory_config["proxy"],
128
+ context: "accessories/#{name}/proxy",
129
+ secrets: config.secrets
130
+ end
131
+
132
+ def initialize_registry
133
+ Kamal::Configuration::Registry.new \
134
+ config: accessory_config,
135
+ secrets: config.secrets,
136
+ context: "accessories/#{name}/registry"
137
+ end
93
138
 
94
139
  def default_labels
95
140
  { "service" => service_name }
@@ -111,7 +156,7 @@ class Kamal::Configuration::Accessory
111
156
  end
112
157
 
113
158
  def read_dynamic_file(local_file)
114
- StringIO.new(ERB.new(IO.read(local_file)).result)
159
+ StringIO.new(ERB.new(File.read(local_file)).result)
115
160
  end
116
161
 
117
162
  def expand_remote_file(remote_file)
@@ -157,8 +202,40 @@ class Kamal::Configuration::Accessory
157
202
  end
158
203
 
159
204
  def hosts_from_roles
160
- if accessory_config.key?("roles")
161
- accessory_config["roles"].flat_map { |role| config.role(role).hosts }
205
+ if accessory_config.key?("role")
206
+ config.role(accessory_config["role"])&.hosts
207
+ elsif accessory_config.key?("roles")
208
+ accessory_config["roles"].flat_map { |role| config.role(role)&.hosts }
209
+ end
210
+ end
211
+
212
+ def hosts_from_tags
213
+ if accessory_config.key?("tag")
214
+ extract_hosts_from_config_with_tag(accessory_config["tag"])
215
+ elsif accessory_config.key?("tags")
216
+ accessory_config["tags"].flat_map { |tag| extract_hosts_from_config_with_tag(tag) }
217
+ end
218
+ end
219
+
220
+ def extract_hosts_from_config_with_tag(tag)
221
+ if (servers_with_roles = config.raw_config.servers).is_a?(Hash)
222
+ servers_with_roles.flat_map do |role, servers_in_role|
223
+ servers_in_role.filter_map do |host|
224
+ host.keys.first if host.is_a?(Hash) && host.values.first.include?(tag)
225
+ end
226
+ end
227
+ end
228
+ end
229
+
230
+ def network
231
+ accessory_config["network"] || DEFAULT_NETWORK
232
+ end
233
+
234
+ def ensure_valid_roles
235
+ if accessory_config["roles"] && (missing_roles = accessory_config["roles"] - config.roles.map(&:name)).any?
236
+ raise Kamal::ConfigurationError, "accessories/#{name}: unknown roles #{missing_roles.join(", ")}"
237
+ elsif accessory_config["role"] && !config.role(accessory_config["role"])
238
+ raise Kamal::ConfigurationError, "accessories/#{name}: unknown role #{accessory_config["role"]}"
162
239
  end
163
240
  end
164
241
  end
@@ -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
@@ -19,28 +19,58 @@ class Kamal::Configuration::Builder
19
19
  builder_config
20
20
  end
21
21
 
22
- def multiarch?
23
- builder_config["multiarch"] != false
22
+ def remote
23
+ builder_config["remote"]
24
24
  end
25
25
 
26
- def local?
27
- !!builder_config["local"]
26
+ def arches
27
+ Array(builder_config.fetch("arch", default_arch))
28
+ end
29
+
30
+ def local_arches
31
+ @local_arches ||= if local_disabled?
32
+ []
33
+ elsif remote
34
+ arches & [ Kamal::Utils.docker_arch ]
35
+ else
36
+ arches
37
+ end
38
+ end
39
+
40
+ def remote_arches
41
+ @remote_arches ||= if remote
42
+ arches - local_arches
43
+ else
44
+ []
45
+ end
28
46
  end
29
47
 
30
48
  def remote?
31
- !!builder_config["remote"]
49
+ remote_arches.any?
50
+ end
51
+
52
+ def local?
53
+ !local_disabled? && (arches.empty? || local_arches.any?)
54
+ end
55
+
56
+ def cloud?
57
+ driver.start_with? "cloud"
32
58
  end
33
59
 
34
60
  def cached?
35
61
  !!builder_config["cache"]
36
62
  end
37
63
 
64
+ def pack?
65
+ !!builder_config["pack"]
66
+ end
67
+
38
68
  def args
39
69
  builder_config["args"] || {}
40
70
  end
41
71
 
42
72
  def secrets
43
- builder_config["secrets"] || []
73
+ (builder_config["secrets"] || []).to_h { |key| [ key, config.secrets[key] ] }
44
74
  end
45
75
 
46
76
  def dockerfile
@@ -55,20 +85,20 @@ class Kamal::Configuration::Builder
55
85
  builder_config["context"] || "."
56
86
  end
57
87
 
58
- def local_arch
59
- builder_config["local"]["arch"] if local?
88
+ def driver
89
+ builder_config.fetch("driver", "docker-container")
60
90
  end
61
91
 
62
- def local_host
63
- builder_config["local"]["host"] if local?
92
+ def pack_builder
93
+ builder_config["pack"]["builder"] if pack?
64
94
  end
65
95
 
66
- def remote_arch
67
- builder_config["remote"]["arch"] if remote?
96
+ def pack_buildpacks
97
+ builder_config["pack"]["buildpacks"] if pack?
68
98
  end
69
99
 
70
- def remote_host
71
- builder_config["remote"]["host"] if remote?
100
+ def local_disabled?
101
+ builder_config["local"] == false
72
102
  end
73
103
 
74
104
  def cache_from
@@ -97,6 +127,14 @@ class Kamal::Configuration::Builder
97
127
  builder_config["ssh"]
98
128
  end
99
129
 
130
+ def provenance
131
+ builder_config["provenance"]
132
+ end
133
+
134
+ def sbom
135
+ builder_config["sbom"]
136
+ end
137
+
100
138
  def git_clone?
101
139
  Kamal::Git.used? && builder_config["context"].nil?
102
140
  end
@@ -114,7 +152,23 @@ class Kamal::Configuration::Builder
114
152
  end
115
153
  end
116
154
 
155
+ def docker_driver?
156
+ driver == "docker"
157
+ end
158
+
117
159
  private
160
+ def valid?
161
+ if docker_driver?
162
+ raise ArgumentError, "Invalid builder configuration: the `docker` driver does not not support remote builders" if remote
163
+ raise ArgumentError, "Invalid builder configuration: the `docker` driver does not not support caching" if cached?
164
+ raise ArgumentError, "Invalid builder configuration: the `docker` driver does not not support multiple arches" if arches.many?
165
+ end
166
+
167
+ if @options["cache"] && @options["cache"]["type"]
168
+ raise ArgumentError, "Invalid cache type: #{@options["cache"]["type"]}" unless [ "gha", "registry" ].include?(@options["cache"]["type"])
169
+ end
170
+ end
171
+
118
172
  def cache_image
119
173
  builder_config["cache"]&.fetch("image", nil) || "#{image}-build-cache"
120
174
  end
@@ -136,7 +190,7 @@ class Kamal::Configuration::Builder
136
190
  end
137
191
 
138
192
  def cache_to_config_for_registry
139
- [ "type=registry", builder_config["cache"]&.fetch("options", nil), "ref=#{cache_image_ref}" ].compact.join(",")
193
+ [ "type=registry", "ref=#{cache_image_ref}", builder_config["cache"]&.fetch("options", nil) ].compact.join(",")
140
194
  end
141
195
 
142
196
  def repo_basename
@@ -150,4 +204,8 @@ class Kamal::Configuration::Builder
150
204
  def pwd_sha
151
205
  Digest::SHA256.hexdigest(Dir.pwd)[0..12]
152
206
  end
207
+
208
+ def default_arch
209
+ docker_driver? ? [] : [ "amd64", "arm64" ]
210
+ end
153
211
  end
@@ -3,48 +3,71 @@
3
3
  # Accessories can be booted on a single host, a list of hosts, or on specific roles.
4
4
  # The hosts do not need to be defined in the Kamal servers configuration.
5
5
  #
6
- # Accessories are managed separately from the main service - they are not updated
7
- # when you deploy and they do not have zero-downtime deployments.
6
+ # Accessories are managed separately from the main service they are not updated
7
+ # when you deploy, and they do not have zero-downtime deployments.
8
8
  #
9
9
  # Run `kamal accessory boot <accessory>` to boot an accessory.
10
10
  # See `kamal accessory --help` for more information.
11
11
 
12
12
  # Configuring accessories
13
13
  #
14
- # First define the accessory in the `accessories`
14
+ # First, define the accessory in the `accessories`:
15
15
  accessories:
16
16
  mysql:
17
17
 
18
18
  # Service name
19
19
  #
20
- # This is used in the service label and defaults to `<service>-<accessory>`
21
- # where `<service>` is the main service name from the root configuration
20
+ # This is used in the service label and defaults to `<service>-<accessory>`,
21
+ # where `<service>` is the main service name from the root configuration:
22
22
  service: mysql
23
23
 
24
24
  # Image
25
25
  #
26
- # The Docker image to use, prefix with a registry if not using Docker hub
26
+ # The Docker image to use.
27
+ # Prefix it with its server when using root level registry different from Docker Hub.
28
+ # Define registry directly or via anchors when it differs from root level registry.
27
29
  image: mysql:8.0
28
30
 
31
+ # Registry
32
+ #
33
+ # By default accessories use Docker Hub registry.
34
+ # You can specify different registry per accessory with this option.
35
+ # Don't prefix image with this registry server.
36
+ # Use anchors if you need to set the same specific registry for several accessories.
37
+ #
38
+ # ```yml
39
+ # registry:
40
+ # <<: *specific-registry
41
+ # ```
42
+ #
43
+ # See kamal docs registry for more information:
44
+ registry:
45
+ ...
46
+
29
47
  # Accessory hosts
30
48
  #
31
- # Specify one of `host`, `hosts` or `roles`
49
+ # Specify one of `host`, `hosts`, `role`, `roles`, `tag` or `tags`:
32
50
  host: mysql-db1
33
51
  hosts:
34
52
  - mysql-db1
35
53
  - mysql-db2
54
+ role: mysql
36
55
  roles:
37
56
  - mysql
57
+ tag: writer
58
+ tags:
59
+ - writer
60
+ - reader
38
61
 
39
62
  # Custom command
40
63
  #
41
- # You can set a custom command to run in the container, if you do not want to use the default
64
+ # You can set a custom command to run in the container if you do not want to use the default:
42
65
  cmd: "bin/mysqld"
43
66
 
44
67
  # Port mappings
45
68
  #
46
- # See https://docs.docker.com/network/, especially note the warning about the security
47
- # implications of exposing ports publicly.
69
+ # See [https://docs.docker.com/network/](https://docs.docker.com/network/), and
70
+ # especially note the warning about the security implications of exposing ports publicly.
48
71
  port: "127.0.0.1:3306:3306"
49
72
 
50
73
  # Labels
@@ -52,20 +75,22 @@ accessories:
52
75
  app: myapp
53
76
 
54
77
  # Options
55
- # These are passed to the Docker run command in the form `--<name> <value>`
78
+ #
79
+ # These are passed to the Docker run command in the form `--<name> <value>`:
56
80
  options:
57
81
  restart: always
58
82
  cpus: 2
59
83
 
60
84
  # Environment variables
61
- # See kamal docs env for more information
85
+ #
86
+ # See kamal docs env for more information:
62
87
  env:
63
88
  ...
64
89
 
65
90
  # Copying files
66
91
  #
67
92
  # You can specify files to mount into the container.
68
- # The format is `local:remote` where `local` is the path to the file on the local machine
93
+ # The format is `local:remote`, where `local` is the path to the file on the local machine
69
94
  # and `remote` is the path to the file in the container.
70
95
  #
71
96
  # They will be uploaded from the local repo to the host and then mounted.
@@ -78,13 +103,26 @@ accessories:
78
103
  # Directories
79
104
  #
80
105
  # You can specify directories to mount into the container. They will be created on the host
81
- # before being mounted
106
+ # before being mounted:
82
107
  directories:
83
108
  - mysql-logs:/var/log/mysql
84
109
 
85
110
  # Volumes
86
111
  #
87
112
  # Any other volumes to mount, in addition to the files and directories.
88
- # They are not created or copied before mounting
113
+ # They are not created or copied before mounting:
89
114
  volumes:
90
115
  - /path/to/mysql-logs:/var/log/mysql
116
+
117
+ # Network
118
+ #
119
+ # The network the accessory will be attached to.
120
+ #
121
+ # Defaults to kamal:
122
+ network: custom
123
+
124
+ # Proxy
125
+ #
126
+ # You can run your accessory behind the Kamal proxy. See kamal docs proxy for more information
127
+ proxy:
128
+ ...
@@ -0,0 +1,26 @@
1
+ # Aliases
2
+ #
3
+ # Aliases are shortcuts for Kamal commands.
4
+ #
5
+ # For example, for a Rails app, you might open a console with:
6
+ #
7
+ # ```shell
8
+ # kamal app exec -i --reuse "bin/rails console"
9
+ # ```
10
+ #
11
+ # By defining an alias, like this:
12
+ aliases:
13
+ console: app exec -i --reuse "bin/rails console"
14
+ # You can now open the console with:
15
+ #
16
+ # ```shell
17
+ # kamal console
18
+ # ```
19
+
20
+ # Configuring aliases
21
+ #
22
+ # Aliases are defined in the root config under the alias key.
23
+ #
24
+ # Each alias is named and can only contain lowercase letters, numbers, dashes, and underscores:
25
+ aliases:
26
+ uname: app exec -p -q -r web "uname -a"
@@ -2,18 +2,18 @@
2
2
  #
3
3
  # When deploying to large numbers of hosts, you might prefer not to restart your services on every host at the same time.
4
4
  #
5
- # Kamal’s default is to boot new containers on all hosts in parallel. But you can control this with the boot configuration.
5
+ # Kamal’s default is to boot new containers on all hosts in parallel. However, you can control this with the boot configuration.
6
6
 
7
7
  # Fixed group sizes
8
8
  #
9
- # Here we boot 2 hosts at a time with a 10 second gap between each group.
9
+ # Here, we boot 2 hosts at a time with a 10-second gap between each group:
10
10
  boot:
11
11
  limit: 2
12
12
  wait: 10
13
13
 
14
14
  # Percentage of hosts
15
15
  #
16
- # Here we boot 25% of the hosts at a time with a 2 second gap between each group.
16
+ # Here, we boot 25% of the hosts at a time with a 2-second gap between each group:
17
17
  boot:
18
18
  limit: 25%
19
19
  wait: 2