dash 3.2.0 → 4.0.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 (178) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/bin/dash +2 -2
  4. data/lib/{kamal → dash}/cli/accessory.rb +24 -24
  5. data/lib/dash/cli/alias/command.rb +10 -0
  6. data/lib/{kamal → dash}/cli/app/assets.rb +2 -2
  7. data/lib/{kamal → dash}/cli/app/boot.rb +16 -16
  8. data/lib/{kamal → dash}/cli/app/error_pages.rb +6 -6
  9. data/lib/{kamal → dash}/cli/app/rollout_boot.rb +6 -6
  10. data/lib/{kamal → dash}/cli/app/ssl_certificates.rb +3 -3
  11. data/lib/{kamal → dash}/cli/app.rb +87 -87
  12. data/lib/{kamal → dash}/cli/base.rb +72 -48
  13. data/lib/dash/cli/build/clone.rb +59 -0
  14. data/lib/{kamal → dash}/cli/build/port_forwarding.rb +1 -1
  15. data/lib/{kamal → dash}/cli/build.rb +45 -45
  16. data/lib/{kamal → dash}/cli/doctor/config_checks.rb +3 -3
  17. data/lib/{kamal → dash}/cli/doctor/endpoint_checks.rb +26 -8
  18. data/lib/{kamal → dash}/cli/doctor/host_checks.rb +22 -22
  19. data/lib/{kamal → dash}/cli/doctor.rb +9 -9
  20. data/lib/{kamal → dash}/cli/healthcheck/barrier.rb +2 -2
  21. data/lib/{kamal → dash}/cli/healthcheck/drift_error.rb +2 -2
  22. data/lib/dash/cli/healthcheck/error.rb +2 -0
  23. data/lib/{kamal → dash}/cli/healthcheck/poller.rb +7 -7
  24. data/lib/{kamal → dash}/cli/lock.rb +1 -1
  25. data/lib/dash/cli/main/migrate.rb +77 -0
  26. data/lib/{kamal → dash}/cli/main.rb +82 -71
  27. data/lib/{kamal → dash}/cli/proxy/drift.rb +3 -3
  28. data/lib/dash/cli/proxy/legacy_rename.rb +58 -0
  29. data/lib/{kamal → dash}/cli/proxy/loadbalancer_claim.rb +3 -3
  30. data/lib/{kamal → dash}/cli/proxy/loadbalancer_reboot.rb +23 -23
  31. data/lib/{kamal → dash}/cli/proxy/reboot.rb +21 -21
  32. data/lib/{kamal → dash}/cli/proxy.rb +178 -162
  33. data/lib/{kamal → dash}/cli/prune.rb +10 -10
  34. data/lib/{kamal → dash}/cli/registry.rb +11 -11
  35. data/lib/{kamal → dash}/cli/secrets.rb +3 -3
  36. data/lib/{kamal → dash}/cli/server.rb +14 -14
  37. data/lib/{kamal → dash}/cli/templates/deploy.yml +4 -4
  38. data/lib/dash/cli/templates/sample_hooks/docker-setup.sample +3 -0
  39. data/lib/dash/cli/templates/sample_hooks/post-app-boot.sample +3 -0
  40. data/lib/dash/cli/templates/sample_hooks/post-app-stop.sample +9 -0
  41. data/lib/dash/cli/templates/sample_hooks/post-deploy.sample +14 -0
  42. data/lib/dash/cli/templates/sample_hooks/post-proxy-deploy.sample +3 -0
  43. data/lib/dash/cli/templates/sample_hooks/post-proxy-reboot.sample +3 -0
  44. data/lib/dash/cli/templates/sample_hooks/pre-app-boot.sample +3 -0
  45. data/lib/{kamal → dash}/cli/templates/sample_hooks/pre-app-stop.sample +2 -2
  46. data/lib/{kamal → dash}/cli/templates/sample_hooks/pre-build.sample +8 -8
  47. data/lib/{kamal → dash}/cli/templates/sample_hooks/pre-connect.sample +8 -8
  48. data/lib/{kamal → dash}/cli/templates/sample_hooks/pre-deploy.sample +9 -9
  49. data/lib/dash/cli/templates/sample_hooks/pre-proxy-deploy.sample +3 -0
  50. data/lib/dash/cli/templates/sample_hooks/pre-proxy-reboot.sample +3 -0
  51. data/lib/{kamal → dash}/cli/templates/secrets +6 -6
  52. data/lib/{kamal → dash}/cli.rb +2 -2
  53. data/lib/{kamal → dash}/commander/specifics.rb +2 -2
  54. data/lib/{kamal → dash}/commander.rb +32 -24
  55. data/lib/{kamal → dash}/commands/accessory/proxy.rb +2 -2
  56. data/lib/{kamal → dash}/commands/accessory.rb +2 -2
  57. data/lib/{kamal → dash}/commands/app/assets.rb +1 -1
  58. data/lib/{kamal → dash}/commands/app/containers.rb +1 -1
  59. data/lib/{kamal → dash}/commands/app/error_pages.rb +2 -2
  60. data/lib/{kamal → dash}/commands/app/execution.rb +2 -2
  61. data/lib/{kamal → dash}/commands/app/images.rb +1 -1
  62. data/lib/{kamal → dash}/commands/app/logging.rb +1 -1
  63. data/lib/{kamal → dash}/commands/app/proxy.rb +2 -2
  64. data/lib/{kamal → dash}/commands/app.rb +2 -2
  65. data/lib/{kamal → dash}/commands/auditor.rb +3 -7
  66. data/lib/{kamal → dash}/commands/base.rb +39 -3
  67. data/lib/{kamal → dash}/commands/builder/base.rb +2 -2
  68. data/lib/{kamal → dash}/commands/builder/clone.rb +3 -3
  69. data/lib/{kamal → dash}/commands/builder/cloud.rb +1 -1
  70. data/lib/{kamal → dash}/commands/builder/hybrid.rb +1 -1
  71. data/lib/{kamal → dash}/commands/builder/local.rb +1 -1
  72. data/lib/{kamal → dash}/commands/builder/pack.rb +1 -1
  73. data/lib/{kamal → dash}/commands/builder/remote.rb +1 -1
  74. data/lib/{kamal → dash}/commands/builder.rb +7 -7
  75. data/lib/dash/commands/docker.rb +89 -0
  76. data/lib/{kamal → dash}/commands/hook.rb +1 -1
  77. data/lib/{kamal → dash}/commands/loadbalancer.rb +55 -24
  78. data/lib/{kamal → dash}/commands/lock.rb +3 -3
  79. data/lib/{kamal → dash}/commands/proxy/cert_transfer.rb +6 -6
  80. data/lib/dash/commands/proxy.rb +375 -0
  81. data/lib/{kamal → dash}/commands/prune.rb +2 -2
  82. data/lib/dash/commands/registry.rb +44 -0
  83. data/lib/{kamal → dash}/commands/server.rb +1 -5
  84. data/lib/dash/commands.rb +2 -0
  85. data/lib/{kamal → dash}/configuration/accessory.rb +13 -13
  86. data/lib/{kamal → dash}/configuration/alias.rb +3 -3
  87. data/lib/{kamal → dash}/configuration/boot.rb +2 -2
  88. data/lib/{kamal → dash}/configuration/builder.rb +7 -7
  89. data/lib/{kamal → dash}/configuration/docs/accessory.yml +3 -3
  90. data/lib/{kamal → dash}/configuration/docs/builder.yml +3 -3
  91. data/lib/{kamal → dash}/configuration/docs/configuration.yml +13 -6
  92. data/lib/{kamal → dash}/configuration/docs/env.yml +10 -10
  93. data/lib/{kamal → dash}/configuration/docs/proxy.yml +68 -45
  94. data/lib/{kamal → dash}/configuration/docs/registry.yml +5 -5
  95. data/lib/{kamal → dash}/configuration/env/tag.rb +2 -2
  96. data/lib/{kamal → dash}/configuration/env.rb +5 -5
  97. data/lib/{kamal → dash}/configuration/loadbalancer.rb +5 -5
  98. data/lib/{kamal → dash}/configuration/logging.rb +3 -3
  99. data/lib/{kamal → dash}/configuration/output.rb +4 -4
  100. data/lib/{kamal → dash}/configuration/proxy/acme.rb +9 -8
  101. data/lib/{kamal → dash}/configuration/proxy/boot.rb +9 -11
  102. data/lib/{kamal → dash}/configuration/proxy/run.rb +20 -20
  103. data/lib/{kamal → dash}/configuration/proxy.rb +51 -29
  104. data/lib/{kamal → dash}/configuration/registry.rb +3 -3
  105. data/lib/{kamal → dash}/configuration/role/healthcheck.rb +3 -3
  106. data/lib/{kamal → dash}/configuration/role.rb +14 -14
  107. data/lib/{kamal → dash}/configuration/servers.rb +4 -4
  108. data/lib/{kamal → dash}/configuration/ssh.rb +2 -2
  109. data/lib/{kamal → dash}/configuration/sshkit.rb +2 -2
  110. data/lib/{kamal → dash}/configuration/validation.rb +2 -2
  111. data/lib/{kamal → dash}/configuration/validator/accessory.rb +1 -1
  112. data/lib/{kamal → dash}/configuration/validator/alias.rb +2 -2
  113. data/lib/{kamal → dash}/configuration/validator/builder.rb +1 -1
  114. data/lib/dash/configuration/validator/configuration.rb +6 -0
  115. data/lib/{kamal → dash}/configuration/validator/env.rb +2 -2
  116. data/lib/{kamal → dash}/configuration/validator/proxy.rb +31 -31
  117. data/lib/{kamal → dash}/configuration/validator/registry.rb +1 -1
  118. data/lib/{kamal → dash}/configuration/validator/role.rb +1 -1
  119. data/lib/{kamal → dash}/configuration/validator/servers.rb +1 -1
  120. data/lib/{kamal → dash}/configuration/validator.rb +4 -4
  121. data/lib/{kamal → dash}/configuration/volume.rb +2 -2
  122. data/lib/{kamal → dash}/configuration.rb +47 -37
  123. data/lib/{kamal → dash}/docker.rb +1 -1
  124. data/lib/{kamal → dash}/env_file.rb +1 -1
  125. data/lib/{kamal → dash}/git.rb +1 -1
  126. data/lib/{kamal → dash}/otel_shipper.rb +3 -3
  127. data/lib/{kamal → dash}/output/base_logger.rb +1 -1
  128. data/lib/{kamal → dash}/output/file_logger.rb +1 -1
  129. data/lib/{kamal → dash}/output/formatter.rb +1 -1
  130. data/lib/{kamal → dash}/output/otel_logger.rb +3 -3
  131. data/lib/dash/project_directory.rb +28 -0
  132. data/lib/{kamal → dash}/secrets/adapters/aws_secrets_manager.rb +1 -1
  133. data/lib/{kamal → dash}/secrets/adapters/base.rb +2 -2
  134. data/lib/{kamal → dash}/secrets/adapters/bitwarden.rb +1 -1
  135. data/lib/{kamal → dash}/secrets/adapters/bitwarden_secrets_manager.rb +1 -1
  136. data/lib/{kamal → dash}/secrets/adapters/doppler.rb +1 -1
  137. data/lib/{kamal → dash}/secrets/adapters/enpass.rb +1 -1
  138. data/lib/{kamal → dash}/secrets/adapters/gcp_secret_manager.rb +1 -1
  139. data/lib/{kamal → dash}/secrets/adapters/last_pass.rb +1 -1
  140. data/lib/{kamal → dash}/secrets/adapters/one_password.rb +2 -2
  141. data/lib/{kamal → dash}/secrets/adapters/passbolt.rb +1 -1
  142. data/lib/{kamal → dash}/secrets/adapters/test.rb +1 -1
  143. data/lib/{kamal → dash}/secrets/adapters.rb +2 -2
  144. data/lib/{kamal → dash}/secrets/dotenv/inline_command_substitution.rb +2 -2
  145. data/lib/{kamal → dash}/secrets.rb +6 -6
  146. data/lib/{kamal → dash}/tags.rb +8 -3
  147. data/lib/{kamal → dash}/utils/sensitive.rb +1 -1
  148. data/lib/{kamal → dash}/utils.rb +16 -6
  149. data/lib/dash/version.rb +3 -0
  150. data/lib/{kamal.rb → dash.rb} +4 -4
  151. metadata +157 -154
  152. data/lib/kamal/cli/alias/command.rb +0 -10
  153. data/lib/kamal/cli/build/clone.rb +0 -59
  154. data/lib/kamal/cli/healthcheck/error.rb +0 -2
  155. data/lib/kamal/cli/templates/sample_hooks/docker-setup.sample +0 -3
  156. data/lib/kamal/cli/templates/sample_hooks/post-app-boot.sample +0 -3
  157. data/lib/kamal/cli/templates/sample_hooks/post-app-stop.sample +0 -9
  158. data/lib/kamal/cli/templates/sample_hooks/post-deploy.sample +0 -14
  159. data/lib/kamal/cli/templates/sample_hooks/post-proxy-deploy.sample +0 -3
  160. data/lib/kamal/cli/templates/sample_hooks/post-proxy-reboot.sample +0 -3
  161. data/lib/kamal/cli/templates/sample_hooks/pre-app-boot.sample +0 -3
  162. data/lib/kamal/cli/templates/sample_hooks/pre-proxy-deploy.sample +0 -3
  163. data/lib/kamal/cli/templates/sample_hooks/pre-proxy-reboot.sample +0 -3
  164. data/lib/kamal/commands/docker.rb +0 -55
  165. data/lib/kamal/commands/proxy.rb +0 -266
  166. data/lib/kamal/commands/registry.rb +0 -38
  167. data/lib/kamal/commands.rb +0 -2
  168. data/lib/kamal/configuration/validator/configuration.rb +0 -6
  169. data/lib/kamal/version.rb +0 -3
  170. /data/lib/{kamal → dash}/configuration/docs/alias.yml +0 -0
  171. /data/lib/{kamal → dash}/configuration/docs/boot.yml +0 -0
  172. /data/lib/{kamal → dash}/configuration/docs/logging.yml +0 -0
  173. /data/lib/{kamal → dash}/configuration/docs/output.yml +0 -0
  174. /data/lib/{kamal → dash}/configuration/docs/role.yml +0 -0
  175. /data/lib/{kamal → dash}/configuration/docs/servers.yml +0 -0
  176. /data/lib/{kamal → dash}/configuration/docs/ssh.yml +0 -0
  177. /data/lib/{kamal → dash}/configuration/docs/sshkit.yml +0 -0
  178. /data/lib/{kamal → dash}/sshkit_with_ext.rb +0 -0
@@ -81,7 +81,7 @@ asset_path: /path/to/assets
81
81
 
82
82
  # Hooks path
83
83
  #
84
- # Path to hooks, defaults to `.kamal/hooks`.
84
+ # Path to hooks, defaults to `.dash/hooks` (`.kamal/hooks` is still read when only that exists).
85
85
  # See https://kamal-deploy.org/docs/hooks for more information:
86
86
  hooks_path: /user_home/kamal/hooks
87
87
 
@@ -106,8 +106,8 @@ hooks_output:
106
106
 
107
107
  # Secrets path
108
108
  #
109
- # Path to secrets, defaults to `.kamal/secrets`.
110
- # Kamal looks for `<secrets_path>-common` first and then `<secrets_path>`.
109
+ # Path to secrets, defaults to `.dash/secrets` (`.kamal/secrets` is still read when only that exists).
110
+ # dash looks for `<secrets_path>-common` first and then `<secrets_path>`.
111
111
  # When using destinations, it instead looks for `<secrets_path>-common` first and then
112
112
  # `<secrets_path>.<destination>`. Later files override earlier ones.
113
113
  secrets_path: /user_home/kamal/secrets
@@ -171,8 +171,15 @@ stop_timeout: 30
171
171
 
172
172
  # Run directory
173
173
  #
174
- # Directory to store dash runtime files in on the host, default `.kamal`:
175
- run_directory: /etc/kamal
174
+ # Where dash keeps its runtime files on each host — per-app env and assets, the
175
+ # proxy's boot files and apps-config mount, loadbalancer service claims, deploy
176
+ # locks, and the audit log. Resolved against the SSH user's home, default
177
+ # `.dash`. A host still holding the pre-3.4 `.kamal` directory is renamed to
178
+ # `.dash` in place the next time dash takes a lock on it; nothing is rebooted.
179
+ #
180
+ # The key is accepted but not yet honoured — the path is currently always
181
+ # `.dash`. Tracked separately from the stage-3 rename.
182
+ run_directory: .dash
176
183
 
177
184
  # SSH options
178
185
  #
@@ -194,7 +201,7 @@ accessories:
194
201
 
195
202
  # Proxy
196
203
  #
197
- # Configuration for kamal-proxy, see dash docs proxy:
204
+ # Configuration for dash-proxy, see dash docs proxy:
198
205
  proxy:
199
206
  ...
200
207
 
@@ -1,7 +1,7 @@
1
1
  # Environment variables
2
2
  #
3
- # Environment variables can be set directly in the Kamal configuration or
4
- # read from `.kamal/secrets`.
3
+ # Environment variables can be set directly in the dash configuration or
4
+ # read from `.dash/secrets`.
5
5
 
6
6
  # Reading environment variables from the configuration
7
7
  #
@@ -14,20 +14,20 @@ env:
14
14
 
15
15
  # Secrets
16
16
  #
17
- # Kamal uses dotenv to automatically load environment variables from the configured secrets files.
17
+ # dash uses dotenv to automatically load environment variables from the configured secrets files.
18
18
  #
19
- # Common secrets across all destinations can be set in `.kamal/secrets-common`. Kamal looks for
20
- # `.kamal/secrets-common` first, then `.kamal/secrets`, with later values overriding earlier ones.
19
+ # Common secrets across all destinations can be set in `.dash/secrets-common`. dash looks for
20
+ # `.dash/secrets-common` first, then `.dash/secrets`, with later values overriding earlier ones.
21
21
  #
22
- # If you are using destinations, Kamal looks for `.kamal/secrets-common` first, then
23
- # `.kamal/secrets.<destination>`. The non-destination `.kamal/secrets` file is not read when a
22
+ # If you are using destinations, dash looks for `.dash/secrets-common` first, then
23
+ # `.dash/secrets.<destination>`. The non-destination `.dash/secrets` file is not read when a
24
24
  # destination is selected.
25
25
  #
26
- # This file can be used to set variables like `KAMAL_REGISTRY_PASSWORD` or database passwords.
26
+ # This file can be used to set variables like `DASH_REGISTRY_PASSWORD` or database passwords.
27
27
  # You can use variable or command substitution in the secrets file.
28
28
  #
29
29
  # ```shell
30
- # KAMAL_REGISTRY_PASSWORD=$KAMAL_REGISTRY_PASSWORD
30
+ # DASH_REGISTRY_PASSWORD=$DASH_REGISTRY_PASSWORD
31
31
  # RAILS_MASTER_KEY=$(cat config/master.key)
32
32
  # ```
33
33
  #
@@ -40,7 +40,7 @@ env:
40
40
  # DB_PASSWORD=$(dash secrets extract DB_PASSWORD $SECRETS)
41
41
  # ```
42
42
  #
43
- # If you store secrets directly in `.kamal/secrets`, ensure that it is not checked into version control.
43
+ # If you store secrets directly in `.dash/secrets`, ensure that it is not checked into version control.
44
44
  #
45
45
  # To pass the secrets, you should list them under the `secret` key. When you do this, the
46
46
  # other variables need to be moved under the `clear` key.
@@ -1,6 +1,6 @@
1
1
  # Proxy
2
2
  #
3
- # Kamal uses [kamal-proxy](https://github.com/basecamp/kamal-proxy) to provide
3
+ # Kamal uses [dash-proxy](https://github.com/basecamp/dash-proxy) to provide
4
4
  # gapless deployments. It runs on ports 80 and 443 and forwards requests to the
5
5
  # application container.
6
6
  #
@@ -16,7 +16,7 @@ proxy:
16
16
  # Where each option lives when a loadbalancer fronts the fleet
17
17
  #
18
18
  # Every deploy option has exactly one home (see
19
- # Kamal::Configuration::Proxy::DEPLOY_OPTION_DISPOSITIONS - the layering
19
+ # Dash::Configuration::Proxy::DEPLOY_OPTION_DISPOSITIONS - the layering
20
20
  # contract that enforces this):
21
21
  #
22
22
  # edge - applied only by the loadbalancer, stripped from the per-host
@@ -74,13 +74,13 @@ proxy:
74
74
  # Sharing one loadbalancer between several dash apps
75
75
  #
76
76
  # More than one dash app may point `loadbalancer:` at the same host. Each app
77
- # registers its own service on the shared kamal-proxy and keeps its own
77
+ # registers its own service on the shared dash-proxy and keeps its own
78
78
  # deploy.yml; the load balancer multiplexes them by hostname.
79
79
  #
80
80
  # The rules dash enforces for that topology:
81
81
  #
82
- # * Service state survives a reboot. kamal-proxy persists its services in the
83
- # `kamal-loadbalancer-config` volume (or `kamal-proxy-config` when the
82
+ # * Service state survives a reboot. dash-proxy persists its services in the
83
+ # `dash-loadbalancer-config` volume (or `dash-proxy-config` when the
84
84
  # loadbalancer shares a proxy host), and `dash proxy reboot` only replaces
85
85
  # the container. Rebooting from app A does not drop app B's routes — the
86
86
  # surviving service list is printed after the restart.
@@ -88,13 +88,13 @@ proxy:
88
88
  # * Service names must be unique across apps. The loadbalancer registers a
89
89
  # service under the bare `service:` name, so two apps — or two destinations
90
90
  # of one app — sharing a name would take over each other's routes. The first
91
- # app to deploy claims the name in `.kamal/loadbalancer/services/<service>`
91
+ # app to deploy claims the name in `.dash/loadbalancer/services/<service>`
92
92
  # on the loadbalancer host; a second app deploying the same name fails at
93
93
  # deploy time instead of silently winning.
94
94
  #
95
95
  # * Apps sharing a loadbalancer must agree on `proxy/run`. All of them boot the
96
96
  # same container, so the first app to boot records its run configuration in
97
- # `.kamal/loadbalancer/run_config`. Another app booting with a different
97
+ # `.dash/loadbalancer/run_config`. Another app booting with a different
98
98
  # `proxy/run` fails; the same app changing its own gets the usual drift
99
99
  # warning and applies it on `dash proxy reboot`.
100
100
  #
@@ -104,7 +104,7 @@ proxy:
104
104
 
105
105
  # Automatic proxy reboot on deploy
106
106
  #
107
- # When `dash deploy` detects that the running kamal-proxy container was
107
+ # When `dash deploy` detects that the running dash-proxy container was
108
108
  # started with a different image, version or run options than the current
109
109
  # configuration, it reboots the proxy automatically — one host at a time —
110
110
  # before booting the app.
@@ -126,13 +126,13 @@ proxy:
126
126
 
127
127
  # SSL
128
128
  #
129
- # kamal-proxy can provide automatic HTTPS for your application via Let's Encrypt.
129
+ # dash-proxy can provide automatic HTTPS for your application via Let's Encrypt.
130
130
  #
131
131
  # This requires that we are deploying to one server and the host option is set.
132
132
  # The host value must point to the server we are deploying to, and port 443 must be
133
133
  # open for the Let's Encrypt challenge to succeed.
134
134
  #
135
- # If you set `ssl` to `true`, `kamal-proxy` will stop forwarding headers to your app,
135
+ # If you set `ssl` to `true`, `dash-proxy` will stop forwarding headers to your app,
136
136
  # unless you explicitly set `forward_headers: true`
137
137
  #
138
138
  # Defaults to `false`:
@@ -156,13 +156,13 @@ proxy:
156
156
  # absolute http(s) URL is called directly. Answer 2xx to approve. On-demand TLS
157
157
  # replaces the static hostname list, so it cannot be combined with
158
158
  # `host`/`hosts`, with `certificate_pem`, or with `ssl_domains` — dash rejects
159
- # those at config time, because kamal-proxy would reject the deploy and there
159
+ # those at config time, because dash-proxy would reject the deploy and there
160
160
  # is no sensible winner to pick.
161
161
  #
162
162
  # `client_ca_pem` requires mutual TLS: clients must present a certificate
163
163
  # signed by this CA bundle. Like `certificate_pem` it names a secret in
164
- # `.kamal/secrets`; the content is uploaded next to the app's TLS material
165
- # under `.kamal/proxy/apps-config`, and the proxy is given the path it sees
164
+ # `.dash/secrets`; the content is uploaded next to the app's TLS material
165
+ # under `.dash/proxy/apps-config`, and the proxy is given the path it sees
166
166
  # inside its own container. An empty secret fails the deploy rather than
167
167
  # silently turning mTLS off.
168
168
  ssl:
@@ -176,7 +176,7 @@ proxy:
176
176
 
177
177
  # SSL redirect
178
178
  #
179
- # By default, kamal-proxy will redirect all HTTP requests to HTTPS when SSL is enabled.
179
+ # By default, dash-proxy will redirect all HTTP requests to HTTPS when SSL is enabled.
180
180
  # If you prefer that HTTP traffic is passed through to your application (along with
181
181
  # HTTPS traffic), you can disable this redirect by setting `ssl_redirect: false`:
182
182
  ssl_redirect: false
@@ -244,7 +244,7 @@ proxy:
244
244
  #
245
245
  # If you are behind a trusted proxy, you can set this to `true` to forward the headers.
246
246
  #
247
- # By default, kamal-proxy will not forward the headers if the `ssl` option is set to `true`, and
247
+ # By default, dash-proxy will not forward the headers if the `ssl` option is set to `true`, and
248
248
  # will forward them if it is set to `false`.
249
249
  forward_headers: true
250
250
 
@@ -278,7 +278,7 @@ proxy:
278
278
  set:
279
279
  Strict-Transport-Security: max-age=31536000
280
280
  add:
281
- X-Served-By: kamal-proxy
281
+ X-Served-By: dash-proxy
282
282
  remove:
283
283
  - Server
284
284
 
@@ -329,7 +329,7 @@ proxy:
329
329
  #
330
330
  # Authentication tokens live in the PROXY's environment, not the app's: polls
331
331
  # send `KAMAL_PROXY_REDIRECTS_TOKEN` as a bearer token when set, and
332
- # `POST /.kamal-proxy/redirects/refresh` nudges an immediate re-poll when
332
+ # `POST /.dash-proxy/redirects/refresh` nudges an immediate re-poll when
333
333
  # authenticated with `KAMAL_PROXY_REFRESH_TOKEN`. Set both via
334
334
  # `proxy.run.options.env`, next to `KAMAL_PROXY_DOMAINS_TOKEN` — never as
335
335
  # deploy flags, which leak into process listings and audit logs.
@@ -377,7 +377,7 @@ proxy:
377
377
  #
378
378
  # Set exactly one of `password_secret` or `password` — never both.
379
379
  #
380
- # Prefer `password_secret`: it names an entry in `.kamal/secrets`, so the
380
+ # Prefer `password_secret`: it names an entry in `.dash/secrets`, so the
381
381
  # password never lives in this file.
382
382
  #
383
383
  # basic_auth:
@@ -397,19 +397,19 @@ proxy:
397
397
  password_secret: WEB_BASIC_AUTH_PASSWORD
398
398
  #
399
399
  # ### Notes
400
- # - Requires a kamal-proxy that supports `--basic-auth`. This is newer than
400
+ # - Requires a dash-proxy that supports `--basic-auth`. This is newer than
401
401
  # the current `MINIMUM_VERSION`, so make sure your proxy is up to date
402
402
  # before enabling it — an older proxy fails the deploy on an unknown flag.
403
403
  # - Basic credentials are replayable and are sent on every request. Use this
404
404
  # with `ssl: true`, or terminate TLS in front of the proxy.
405
- # - kamal-proxy removes the `Authorization` header before forwarding, so a
405
+ # - dash-proxy removes the `Authorization` header before forwarding, so a
406
406
  # service behind basic auth cannot also pass credentials through to its
407
407
  # target. When load balancing, the credentials are enforced by the load
408
408
  # balancer only.
409
409
 
410
410
  # Dynamic TLS domains
411
411
  #
412
- # kamal-proxy can learn TLS hostnames from your application at runtime
412
+ # dash-proxy can learn TLS hostnames from your application at runtime
413
413
  # instead of fixing them at deploy time. It polls `source` — a path
414
414
  # (resolved against a healthy app target) or an absolute http(s) URL —
415
415
  # for the domain list and manages Let's Encrypt certificates for it
@@ -434,21 +434,21 @@ proxy:
434
434
  # Who the client is
435
435
  #
436
436
  # Rate limiting and IP allow lists are both only as correct as the address they
437
- # key on, so configure this first if anything sits in front of kamal-proxy.
437
+ # key on, so configure this first if anything sits in front of dash-proxy.
438
438
  #
439
439
  # With no `trusted_proxies`, the client is always the address that opened the
440
440
  # connection — nothing a client sends can influence it, which is what makes the
441
441
  # allow list meaningful.
442
442
  #
443
443
  # Once you declare `trusted_proxies`, and only when the connecting address is
444
- # one of them, kamal-proxy reads the forwarded chain instead: it walks the
444
+ # one of them, dash-proxy reads the forwarded chain instead: it walks the
445
445
  # chain from the nearest hop backwards past every proxy you declared, and the
446
446
  # first address none of your proxies wrote is the client. **List every hop**,
447
- # not only the one that connects to kamal-proxy — a chain it cannot resolve
447
+ # not only the one that connects to dash-proxy — a chain it cannot resolve
448
448
  # denies the request rather than falling back to the connecting address.
449
449
  #
450
450
  # `header` names the header carrying the original client IP (`CF-Connecting-IP`
451
- # behind Cloudflare, `True-Client-IP` behind some others); kamal-proxy reads it
451
+ # behind Cloudflare, `True-Client-IP` behind some others); dash-proxy reads it
452
452
  # instead of `X-Forwarded-For`. It is only honoured when `trusted_proxies` is
453
453
  # set, because otherwise it is just something the client wrote — dash rejects
454
454
  # that combination rather than appearing to honour it.
@@ -501,7 +501,7 @@ proxy:
501
501
  #
502
502
  # Refuse requests whose full User-Agent matches one of these RE2 patterns,
503
503
  # checked after the IP rules. A missing User-Agent only matches an explicit
504
- # '^$' pattern. Patterns are matched by kamal-proxy (Go RE2), so dash checks
504
+ # '^$' pattern. Patterns are matched by dash-proxy (Go RE2), so dash checks
505
505
  # only their shape, not their syntax.
506
506
  deny_user_agents:
507
507
  - 'BadBot/.*'
@@ -661,7 +661,7 @@ proxy:
661
661
  # This block is the *policy*, and it is per service. Where the entries live is
662
662
  # proxy-wide and set under `run/cache` below.
663
663
  #
664
- # Only `enabled` is required. Everything else keeps kamal-proxy's own default
664
+ # Only `enabled` is required. Everything else keeps dash-proxy's own default
665
665
  # until you set it.
666
666
  #
667
667
  # `max_ttl` caps the lifetime the app asks for, in seconds, so one mistaken
@@ -690,7 +690,7 @@ proxy:
690
690
  # ### When it is not caching
691
691
  #
692
692
  # A cache that quietly stores nothing is the usual first surprise. Start with
693
- # `dash proxy cache stats`; kamal-proxy also explains every refusal — check
693
+ # `dash proxy cache stats`; dash-proxy also explains every refusal — check
694
694
  # `dash proxy logs` for the reason, and the `cache_refusals_total` metric
695
695
  # (by `reason`) if you run with `metrics_port`.
696
696
  # The common reasons are a missing `Cache-Control: public, max-age=...` on the
@@ -739,7 +739,7 @@ proxy:
739
739
 
740
740
  # Read-only targets
741
741
  #
742
- # kamal-proxy can split traffic between the deployed (writer) targets and a
742
+ # dash-proxy can split traffic between the deployed (writer) targets and a
743
743
  # set of read-only targets, e.g. app instances backed by database replicas.
744
744
  # Read requests are routed to the read targets; write requests always go to
745
745
  # the writers.
@@ -771,7 +771,7 @@ proxy:
771
771
  # re-pinned, so a deploy does not strand anybody. Reads served by a
772
772
  # `read_targets` replica are never pinned.
773
773
  #
774
- # `cookie` renames the pin cookie; kamal-proxy picks a sensible default.
774
+ # `cookie` renames the pin cookie; dash-proxy picks a sensible default.
775
775
  session_affinity:
776
776
  enabled: true
777
777
  cookie: _kamal_affinity
@@ -827,19 +827,19 @@ proxy:
827
827
  publish: false # Publish ports to the host (default: true)
828
828
  bind_ips: # List of IPs to bind to when publishing ports
829
829
  - 0.0.0.0
830
- registry: registry:4443 # Extra registry prefix for the kamal-proxy image
830
+ registry: registry:4443 # Extra registry prefix for the dash-proxy image
831
831
  # (default: none). If you set this, also override
832
832
  # `repository` to a host-less path (e.g.
833
- # myfork/kamal-proxy) - the default repository
833
+ # myfork/dash-proxy) - the default repository
834
834
  # below already embeds its ghcr.io host
835
835
  repository: ghcr.io/zoolutions/dash-proxy # Container repository for the
836
- # kamal-proxy image (this is the default)
837
- version: v1.0.0.6 # Version tag of the kamal-proxy image to use.
836
+ # dash-proxy image (this is the default)
837
+ version: v1.1.0.0 # Version tag of the dash-proxy image to use.
838
838
  # Defaults to the minimum version this gem
839
839
  # requires - only pin it to roll forward early,
840
840
  # never below the default
841
841
  port_holder: true # Zero-downtime proxy reboots (default: false).
842
- # Runs a minimal long-lived kamal-proxy-net container that
842
+ # Runs a minimal long-lived dash-proxy-net container that
843
843
  # owns the published ports; proxy generations join its
844
844
  # network namespace and overlap during a reboot, so config
845
845
  # and version changes apply without dropping requests.
@@ -857,7 +857,7 @@ proxy:
857
857
  # DNS-01 on their own. `auto` is an explicit opt-in that picks the provider
858
858
  # from the credentials it can see and logs at boot which one it armed;
859
859
  # `none` says "no DNS-01" explicitly. An unsupported name is rejected here,
860
- # at config time - kamal-proxy would only log a warning and then never
860
+ # at config time - dash-proxy would only log a warning and then never
861
861
  # issue a certificate.
862
862
  #
863
863
  # A plain string (`dns_provider: cloudflare`) uses one provider for every
@@ -866,7 +866,7 @@ proxy:
866
866
  # spread across registrars. Each provider's API credentials must be present
867
867
  # under `credentials` for its challenges to succeed.
868
868
  #
869
- # kamal-proxy also accepts short aliases for the canonical names - `cf`
869
+ # dash-proxy also accepts short aliases for the canonical names - `cf`
870
870
  # (cloudflare), `do` (digitalocean), `gcp`/`google`/`googledns` (gcloud),
871
871
  # `gd` (godaddy), `hz` (hetzner), `nc` (namecheap), `aws`/`r53` (route53)
872
872
  # and `vr` (vultr). Prefer the canonical name; the aliases exist so a
@@ -880,7 +880,29 @@ proxy:
880
880
  # staging environment while you are working out a DNS setup, so you do not
881
881
  # burn production rate limits on failed attempts.
882
882
  #
883
- # `credentials` names entries in `.kamal/secrets` to pass to the proxy
883
+ # `release_probe_interval` is how often, in seconds, the proxy re-checks a
884
+ # domain whose issuance is currently held - which is what decides how long
885
+ # after a DNS cutover the certificate appears (proxy v1.0.0.7+).
886
+ #
887
+ # You can point a host at dash before its DNS is repointed. No certificate
888
+ # is ordered until the first HTTPS request arrives, and the proxy first
889
+ # checks that the domain actually routes back to it - because until it does,
890
+ # an HTTP-01 challenge cannot succeed, and a failed attempt burns Let's
891
+ # Encrypt's limit of five failed authorizations per hostname per hour.
892
+ # Tripping that limit is what would otherwise delay the certificate at the
893
+ # moment of the cutover. Held domains are re-checked on this interval and
894
+ # issued as soon as the domain arrives, so the cutover costs one interval
895
+ # rather than a backoff step.
896
+ #
897
+ # The default is 60. A negative value switches release probing off, leaving
898
+ # a held domain to wait out its backoff. Zones covered by a DNS-01 provider
899
+ # skip all of this: DNS-01 never depends on where a domain points, so their
900
+ # certificates can be issued well before a cutover.
901
+ #
902
+ # `dash proxy domains list` shows what is held and why; `dash proxy domains
903
+ # retry HOST` clears a hold when you already know the cause is fixed.
904
+ #
905
+ # `credentials` names entries in `.dash/secrets` to pass to the proxy
884
906
  # container as environment variables - the API credentials your DNS provider
885
907
  # needs (`CF_DNS_API_TOKEN`, `LOOPIA_API_USER`, ...). Name them exactly as the
886
908
  # provider expects them, since the name is what reaches the container.
@@ -899,6 +921,7 @@ proxy:
899
921
  default: route53
900
922
  prefer_wildcard: true
901
923
  http_fallback: false
924
+ release_probe_interval: 60
902
925
  directory: https://acme-staging-v02.api.letsencrypt.org/directory
903
926
  credentials:
904
927
  - CF_DNS_API_TOKEN
@@ -995,15 +1018,15 @@ proxy:
995
1018
  # Defaults to false:
996
1019
  reuse_port: true
997
1020
 
998
- # Escape hatch for `kamal-proxy run`
1021
+ # Escape hatch for `dash-proxy run`
999
1022
  #
1000
- # Anything kamal-proxy accepts that has no key above. Note the difference
1023
+ # Anything dash-proxy accepts that has no key above. Note the difference
1001
1024
  # from `options` below, which many people expect to do this: `flags` goes to
1002
- # `kamal-proxy run`, `options` goes to `docker run`.
1025
+ # `dash-proxy run`, `options` goes to `docker run`.
1003
1026
  #
1004
1027
  # `true` renders a bare flag; anything else renders `--flag value`. No
1005
1028
  # translation is applied, so write Go durations and lists the way
1006
- # kamal-proxy wants them.
1029
+ # dash-proxy wants them.
1007
1030
  #
1008
1031
  # A key here that a named setting already emits is rejected rather than
1009
1032
  # passed twice — set one or the other.
@@ -1014,7 +1037,7 @@ proxy:
1014
1037
  #
1015
1038
  # Path to the container runtime socket, which is what `proxy/sleep` needs in
1016
1039
  # order to stop and start containers. Setting it does two things: it passes
1017
- # the path to kamal-proxy, and it mounts that path into the proxy container,
1040
+ # the path to dash-proxy, and it mounts that path into the proxy container,
1018
1041
  # since the flag alone only says where to look.
1019
1042
  #
1020
1043
  # **Reaching this socket is root-equivalent on the host.** It is a separate,
@@ -1050,11 +1073,11 @@ proxy:
1050
1073
  store_timeout: 2
1051
1074
  memory_size: 134_217_728
1052
1075
  # `options` are `docker run` options for the proxy container - resource
1053
- # limits, labels, extra mounts - NOT kamal-proxy flags. A kamal-proxy flag
1076
+ # limits, labels, extra mounts - NOT dash-proxy flags. A dash-proxy flag
1054
1077
  # the gem has no key for goes in `flags` above instead.
1055
1078
  options: # Additional options to pass to `docker run`
1056
1079
  label:
1057
- - custom.label=kamal-proxy
1080
+ - custom.label=dash-proxy
1058
1081
  memory: 512m
1059
1082
  cpus: 0.5
1060
1083
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  # Using a local container registry
6
6
  #
7
- # If the registry server starts with `localhost`, Kamal will start a local Docker registry
7
+ # If the registry server starts with `localhost`, dash will start a local Docker registry
8
8
  # on that port and push the app image to it.
9
9
  registry:
10
10
  server: localhost:5555
@@ -15,13 +15,13 @@ registry:
15
15
  # set up a private repository before deploying, or change the default repository privacy
16
16
  # settings to private in your [Docker Hub settings](https://hub.docker.com/repository-settings/default-privacy).
17
17
  #
18
- # A reference to a secret (in this case, `KAMAL_REGISTRY_PASSWORD`) will look up the secret
18
+ # A reference to a secret (in this case, `DASH_REGISTRY_PASSWORD`) will look up the secret
19
19
  # in the local environment:
20
20
  registry:
21
21
  username:
22
22
  - <your docker hub username>
23
23
  password:
24
- - KAMAL_REGISTRY_PASSWORD
24
+ - DASH_REGISTRY_PASSWORD
25
25
 
26
26
  # Using AWS ECR as the container registry
27
27
  #
@@ -45,7 +45,7 @@ registry:
45
45
  # base64 -i /path/to/key.json | tr -d "\\n"
46
46
  # ```
47
47
  #
48
- # You'll then need to set the `KAMAL_REGISTRY_PASSWORD` secret to that value.
48
+ # You'll then need to set the `DASH_REGISTRY_PASSWORD` secret to that value.
49
49
  #
50
50
  # Use the environment variable as the password along with `_json_key_base64` as the username.
51
51
  # Here’s the final configuration:
@@ -53,7 +53,7 @@ registry:
53
53
  server: <your registry region>-docker.pkg.dev
54
54
  username: _json_key_base64
55
55
  password:
56
- - KAMAL_REGISTRY_PASSWORD
56
+ - DASH_REGISTRY_PASSWORD
57
57
 
58
58
  # Validating the configuration
59
59
  #
@@ -1,4 +1,4 @@
1
- class Kamal::Configuration::Env::Tag
1
+ class Dash::Configuration::Env::Tag
2
2
  attr_reader :name, :config, :secrets
3
3
 
4
4
  def initialize(name, config:, secrets:)
@@ -8,6 +8,6 @@ class Kamal::Configuration::Env::Tag
8
8
  end
9
9
 
10
10
  def env
11
- Kamal::Configuration::Env.new(config: config, secrets: secrets)
11
+ Dash::Configuration::Env.new(config: config, secrets: secrets)
12
12
  end
13
13
  end
@@ -1,15 +1,15 @@
1
- class Kamal::Configuration::Env
2
- include Kamal::Configuration::Validation
1
+ class Dash::Configuration::Env
2
+ include Dash::Configuration::Validation
3
3
 
4
4
  attr_reader :context, :clear, :secrets, :secret_keys
5
- delegate :argumentize, to: Kamal::Utils
5
+ delegate :argumentize, to: Dash::Utils
6
6
 
7
7
  def initialize(config:, secrets:, context: "env")
8
8
  @clear = config.fetch("clear", config.key?("secret") || config.key?("tags") ? {} : config)
9
9
  @secrets = secrets
10
10
  @secret_keys = config.fetch("secret", [])
11
11
  @context = context
12
- validate! config, context: context, with: Kamal::Configuration::Validator::Env
12
+ validate! config, context: context, with: Dash::Configuration::Validator::Env
13
13
  end
14
14
 
15
15
  def clear_args
@@ -17,7 +17,7 @@ class Kamal::Configuration::Env
17
17
  end
18
18
 
19
19
  def secrets_io
20
- Kamal::EnvFile.new(aliased_secrets).to_io
20
+ Dash::EnvFile.new(aliased_secrets).to_io
21
21
  end
22
22
 
23
23
  def merge(other)
@@ -1,6 +1,6 @@
1
- class Kamal::Configuration::Loadbalancer < Kamal::Configuration::Proxy
1
+ class Dash::Configuration::Loadbalancer < Dash::Configuration::Proxy
2
2
  CONTAINER_NAME = "load-balancer".freeze
3
- SHARED_CONTAINER_NAME = "kamal-proxy".freeze
3
+ SHARED_CONTAINER_NAME = "dash-proxy".freeze
4
4
 
5
5
  def self.validation_config_key
6
6
  "proxy"
@@ -34,13 +34,13 @@ class Kamal::Configuration::Loadbalancer < Kamal::Configuration::Proxy
34
34
  File.join config.run_directory, "loadbalancer"
35
35
  end
36
36
 
37
- # The load balancer is a kamal-proxy container, so proxy/run applies to it
37
+ # The load balancer is a dash-proxy container, so proxy/run applies to it
38
38
  # exactly as it does to the per-host proxies. Without a run block it still
39
39
  # needs the default surface (published ports, log rotation, the apps-config
40
40
  # mount and the run command) to boot from, so fall back to an empty config
41
41
  # rather than to nil.
42
42
  def run
43
- @run ||= Kamal::Configuration::Proxy::Run.new(config, run_config: {})
43
+ @run ||= Dash::Configuration::Proxy::Run.new(config, run_config: {})
44
44
  end
45
45
 
46
46
  # Docker options for the load balancer container: publish/logging/options
@@ -100,7 +100,7 @@ class Kamal::Configuration::Loadbalancer < Kamal::Configuration::Proxy
100
100
 
101
101
  private
102
102
  # The edge half of the layering contract (see
103
- # Kamal::Configuration::Proxy::DEPLOY_OPTION_DISPOSITIONS): the load
103
+ # Dash::Configuration::Proxy::DEPLOY_OPTION_DISPOSITIONS): the load
104
104
  # balancer applies the edge and shared concerns, and leaves the per-app
105
105
  # ones to the per-host proxies it forwards to.
106
106
  def retained_dispositions
@@ -1,7 +1,7 @@
1
- class Kamal::Configuration::Logging
2
- delegate :optionize, :argumentize, to: Kamal::Utils
1
+ class Dash::Configuration::Logging
2
+ delegate :optionize, :argumentize, to: Dash::Utils
3
3
 
4
- include Kamal::Configuration::Validation
4
+ include Dash::Configuration::Validation
5
5
 
6
6
  attr_reader :logging_config
7
7
 
@@ -1,9 +1,9 @@
1
- class Kamal::Configuration::Output
2
- include Kamal::Configuration::Validation
1
+ class Dash::Configuration::Output
2
+ include Dash::Configuration::Validation
3
3
 
4
4
  LOGGER_TYPES = {
5
- "otel" => "Kamal::Output::OtelLogger",
6
- "file" => "Kamal::Output::FileLogger"
5
+ "otel" => "Dash::Output::OtelLogger",
6
+ "file" => "Dash::Output::FileLogger"
7
7
  }
8
8
 
9
9
  attr_reader :output_config, :loggers
@@ -1,22 +1,22 @@
1
- # ACME configuration for the kamal-proxy container, including the DNS-01
1
+ # ACME configuration for the dash-proxy container, including the DNS-01
2
2
  # challenge credentials.
3
3
  #
4
- # Everything here except the credentials becomes a `kamal-proxy run` flag, so it
4
+ # Everything here except the credentials becomes a `dash-proxy run` flag, so it
5
5
  # lands in the run command and therefore in Proxy::Run#config_digest — changing
6
6
  # the block reboots the proxy on the next deploy.
7
7
  #
8
8
  # Credentials go the other way, through an env file uploaded at mode 0600. A DNS
9
9
  # API token can rewrite your zone; `docker run --env TOKEN=...` would put it in
10
10
  # the host's process listing and in kamal's own audit log.
11
- class Kamal::Configuration::Proxy::Acme
12
- # The canonical provider names kamal-proxy MINIMUM_VERSION advertises. Kept in
11
+ class Dash::Configuration::Proxy::Acme
12
+ # The canonical provider names dash-proxy MINIMUM_VERSION advertises. Kept in
13
13
  # step with the proxy by test/proxy_flag_coverage_test.rb, which compares this
14
14
  # list against the manifest bin/sync-proxy-flags generates from the image.
15
15
  DNS_PROVIDERS = %w[
16
16
  auto cloudflare digitalocean gcloud godaddy hetzner namecheap none route53 vultr
17
17
  ].freeze
18
18
 
19
- # Short forms kamal-proxy's ParseProviderName accepts but does not advertise,
19
+ # Short forms dash-proxy's ParseProviderName accepts but does not advertise,
20
20
  # so they cannot be generated from --help and are not drift-checked.
21
21
  DNS_PROVIDER_ALIASES = %w[ cf do gcp google googledns gd hz nc aws r53 vr ].freeze
22
22
 
@@ -53,7 +53,7 @@ class Kamal::Configuration::Proxy::Acme
53
53
  # as a stray argument. Both booleans default to true in the proxy, which makes
54
54
  # false the value an operator actually writes.
55
55
  def run_command_args
56
- Kamal::Utils.optionize(run_command_options, with: "=")
56
+ Dash::Utils.optionize(run_command_options, with: "=")
57
57
  end
58
58
 
59
59
  # compact, not compact_blank: false is a meaningful value for both booleans.
@@ -63,13 +63,14 @@ class Kamal::Configuration::Proxy::Acme
63
63
  "acme-dns-provider": dns_provider_entries,
64
64
  "acme-directory": acme_config["directory"],
65
65
  "acme-prefer-wildcard": acme_config["prefer_wildcard"],
66
- "acme-http-fallback": acme_config["http_fallback"]
66
+ "acme-http-fallback": acme_config["http_fallback"],
67
+ "acme-release-probe-interval": Dash::Utils.seconds_duration(acme_config["release_probe_interval"])
67
68
  }.compact
68
69
  end
69
70
 
70
71
  private
71
72
  # The hash form pins zones to the DNS host that serves them; `default`
72
- # covers unmatched zones. kamal-proxy takes repeatable --acme-dns-provider
73
+ # covers unmatched zones. dash-proxy takes repeatable --acme-dns-provider
73
74
  # entries — zone=provider pairs plus at most one bare default — so the hash
74
75
  # becomes an array and Utils.optionize repeats the flag. The string form
75
76
  # passes through untouched and keeps meaning what it always has.