dash 3.1.5 → 3.2.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.
- checksums.yaml +4 -4
- data/README.md +26 -6
- data/lib/kamal/cli/app.rb +1 -1
- data/lib/kamal/cli/base.rb +2 -2
- data/lib/kamal/cli/doctor/host_checks.rb +5 -5
- data/lib/kamal/cli/main.rb +10 -10
- data/lib/kamal/cli/proxy/drift.rb +1 -1
- data/lib/kamal/cli/proxy/loadbalancer_claim.rb +3 -3
- data/lib/kamal/cli/proxy/loadbalancer_reboot.rb +1 -1
- data/lib/kamal/cli/proxy.rb +7 -7
- data/lib/kamal/cli/registry.rb +2 -2
- data/lib/kamal/cli/server.rb +1 -1
- data/lib/kamal/cli/templates/deploy.yml +2 -2
- data/lib/kamal/cli/templates/secrets +4 -4
- data/lib/kamal/commands/proxy/cert_transfer.rb +1 -1
- data/lib/kamal/configuration/docs/accessory.yml +6 -6
- data/lib/kamal/configuration/docs/alias.yml +2 -2
- data/lib/kamal/configuration/docs/boot.yml +1 -1
- data/lib/kamal/configuration/docs/configuration.yml +14 -14
- data/lib/kamal/configuration/docs/env.yml +7 -7
- data/lib/kamal/configuration/docs/proxy.yml +23 -23
- data/lib/kamal/configuration/docs/registry.yml +1 -1
- data/lib/kamal/configuration/docs/role.yml +1 -1
- data/lib/kamal/configuration/docs/servers.yml +2 -2
- data/lib/kamal/configuration/proxy/boot.rb +3 -1
- data/lib/kamal/configuration/proxy/run.rb +4 -4
- data/lib/kamal/configuration/proxy.rb +1 -1
- data/lib/kamal/configuration/role.rb +1 -1
- data/lib/kamal/configuration/ssh.rb +1 -1
- data/lib/kamal/configuration.rb +1 -1
- data/lib/kamal/secrets/adapters/enpass.rb +2 -2
- data/lib/kamal/secrets/dotenv/inline_command_substitution.rb +3 -1
- data/lib/kamal/version.rb +1 -1
- data/lib/kamal.rb +1 -1
- metadata +16 -63
- data/bin/kamal +0 -18
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5f607b635a7a5840d0bf9c4e6e4377d2ca86a17ed8a619510e08f487eb69da2e
|
|
4
|
+
data.tar.gz: cdc6b6d1ffd33421f54ff48d73c43f69926505f8686c82cf9c0f8734766bd35e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6958eebf303bac9ca6eb09a41a16c8db0b885f23b2e6b52c1f8f711c6e1e5406429d4c12a77f5ecf012f4b9c8a2c349f8721312df95ae733fc3960a08b5ea523
|
|
7
|
+
data.tar.gz: 1aab7f0ee631c4447e0ad396821e81bbb623777e8205b55544492d3b4ae13806733aaecbb5efdaae144a8df8217354369c133668b0cc82b0036c24e93e5194b7
|
data/README.md
CHANGED
|
@@ -1,13 +1,33 @@
|
|
|
1
|
-
#
|
|
1
|
+
# dash: Deploy web apps anywhere
|
|
2
2
|
|
|
3
|
-
From bare metal to cloud VMs, deploy web apps anywhere with zero downtime.
|
|
3
|
+
From bare metal to cloud VMs, deploy web apps anywhere with zero downtime. dash uses [dash-proxy](https://github.com/zoolutions/dash-proxy) to seamlessly switch requests between containers, load-balance across multiple hosts, batch SAN certificates, and issue wildcard certs via DNS-01. Works across multiple servers, using SSHKit to execute commands. Originally built for Rails apps, dash works with any type of web app that can be containerized with Docker.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
dash began as a fork of [basecamp/kamal](https://github.com/basecamp/kamal) and made a clean break in 2026 — it ships the features upstream wouldn't merge (proxy load balancing, readiness gates, response caching, traffic shaping, and more) and moves at its own pace. Existing kamal deployments upgrade in place: the on-server artifacts (`.kamal/` directory, `kamal-proxy` container, `KAMAL_*` secrets) are unchanged.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Installation
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
```bash
|
|
10
|
+
gem install dash
|
|
11
|
+
dash init
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Or in a Gemfile-managed app:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
bundle add dash
|
|
18
|
+
bundle binstubs dash
|
|
19
|
+
bin/dash init
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Configure your deployment in `config/deploy.yml`, then:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
dash setup # first deploy: bootstraps Docker, boots the proxy, deploys
|
|
26
|
+
dash deploy # every deploy after that
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`dash docs` prints the full, always-current configuration reference. Upstream kamal's docs at [kamal-deploy.org](https://kamal-deploy.org) still cover the shared basics.
|
|
10
30
|
|
|
11
31
|
## License
|
|
12
32
|
|
|
13
|
-
|
|
33
|
+
dash is released under the [MIT License](https://opensource.org/licenses/MIT), preserving the license of the kamal codebase it descends from.
|
data/lib/kamal/cli/app.rb
CHANGED
|
@@ -194,7 +194,7 @@ class Kamal::Cli::App < Kamal::Cli::Base
|
|
|
194
194
|
puts_by_host host, "Stopping stale container for role #{role} with version #{version}", quiet: quiet
|
|
195
195
|
execute *app.stop(version: version), raise_on_non_zero_exit: false
|
|
196
196
|
else
|
|
197
|
-
puts_by_host host, "Detected stale container for role #{role} with version #{version} (use `
|
|
197
|
+
puts_by_host host, "Detected stale container for role #{role} with version #{version} (use `dash app stale_containers --stop` to stop)", quiet: quiet
|
|
198
198
|
end
|
|
199
199
|
end
|
|
200
200
|
end
|
data/lib/kamal/cli/base.rb
CHANGED
|
@@ -317,7 +317,7 @@ module Kamal::Cli
|
|
|
317
317
|
puts status
|
|
318
318
|
|
|
319
319
|
unless status.include?(AUTOMATIC_DEPLOY_LOCK_MESSAGE)
|
|
320
|
-
raise LockError, "Deploy lock held manually, not waiting. Run '
|
|
320
|
+
raise LockError, "Deploy lock held manually, not waiting. Run 'dash lock help' for more information"
|
|
321
321
|
end
|
|
322
322
|
|
|
323
323
|
details_shown = true
|
|
@@ -346,7 +346,7 @@ module Kamal::Cli
|
|
|
346
346
|
rescue LockHeldError
|
|
347
347
|
say "Deploy lock already in place!", :red
|
|
348
348
|
puts capture_lock_status
|
|
349
|
-
raise LockError, "Deploy lock found. Run '
|
|
349
|
+
raise LockError, "Deploy lock found. Run 'dash lock help' for more information"
|
|
350
350
|
end
|
|
351
351
|
|
|
352
352
|
def execute_lock_acquire(message, lock: KAMAL.lock, hosts: KAMAL.primary_host)
|
|
@@ -41,7 +41,7 @@ class Kamal::Cli::Doctor::HostChecks
|
|
|
41
41
|
if execute(*KAMAL.docker.running?, raise_on_non_zero_exit: false)
|
|
42
42
|
result :docker, :ok, "docker is installed and running"
|
|
43
43
|
else
|
|
44
|
-
result :docker, :fail, "docker is not installed or not running (run `
|
|
44
|
+
result :docker, :fail, "docker is not installed or not running (run `dash server bootstrap`)"
|
|
45
45
|
end
|
|
46
46
|
rescue StandardError => e
|
|
47
47
|
result :docker, :fail, "#{e.class}: #{e.message}"
|
|
@@ -96,7 +96,7 @@ class Kamal::Cli::Doctor::HostChecks
|
|
|
96
96
|
elsif version.nil?
|
|
97
97
|
result :proxy_version, :ok, "not running (will be started on deploy)"
|
|
98
98
|
elsif Kamal::Utils.older_version?(version, minimum)
|
|
99
|
-
result :proxy_version, :fail, "#{version} is older than the minimum #{minimum}, run `
|
|
99
|
+
result :proxy_version, :fail, "#{version} is older than the minimum #{minimum}, run `dash proxy reboot` to update"
|
|
100
100
|
else
|
|
101
101
|
result :proxy_version, :ok, "#{version} (minimum #{minimum})"
|
|
102
102
|
end
|
|
@@ -127,14 +127,14 @@ class Kamal::Cli::Doctor::HostChecks
|
|
|
127
127
|
if mounted.include?(expected)
|
|
128
128
|
result :proxy_socket, :ok, "docker socket #{expected} is mounted"
|
|
129
129
|
elsif sleep_configured?
|
|
130
|
-
result :proxy_socket, :fail, "the running kamal-proxy has no #{expected} mount, so sleeping services never wake - run `
|
|
130
|
+
result :proxy_socket, :fail, "the running kamal-proxy has no #{expected} mount, so sleeping services never wake - run `dash proxy reboot`"
|
|
131
131
|
else
|
|
132
132
|
# Nothing sleeps yet, so nothing hangs - drift rather than breakage.
|
|
133
|
-
result :proxy_socket, :warn, "the running kamal-proxy has no #{expected} mount - run `
|
|
133
|
+
result :proxy_socket, :warn, "the running kamal-proxy has no #{expected} mount - run `dash proxy reboot` to apply the current configuration"
|
|
134
134
|
end
|
|
135
135
|
elsif (stray = mounted.grep(DOCKER_SOCKET_PATTERN).first)
|
|
136
136
|
result :proxy_socket, :warn, "the running kamal-proxy mounts #{stray} but the config no longer asks for it - " \
|
|
137
|
-
"the socket is root-equivalent host access; `
|
|
137
|
+
"the socket is root-equivalent host access; `dash proxy reboot` removes it"
|
|
138
138
|
else
|
|
139
139
|
result :proxy_socket, :ok, "no docker socket configured or mounted"
|
|
140
140
|
end
|
data/lib/kamal/cli/main.rb
CHANGED
|
@@ -120,7 +120,7 @@ class Kamal::Cli::Main < Kamal::Cli::Base
|
|
|
120
120
|
invoke "kamal:cli:app:boot", [], invoke_options.merge(version: version)
|
|
121
121
|
rolled_back = true
|
|
122
122
|
else
|
|
123
|
-
say "The app version '#{version}' is not available as a container (use '
|
|
123
|
+
say "The app version '#{version}' is not available as a container (use 'dash app containers' for available versions)", :red
|
|
124
124
|
end
|
|
125
125
|
end
|
|
126
126
|
end
|
|
@@ -151,7 +151,7 @@ class Kamal::Cli::Main < Kamal::Cli::Base
|
|
|
151
151
|
end
|
|
152
152
|
end
|
|
153
153
|
|
|
154
|
-
desc "docs [SECTION]", "Show
|
|
154
|
+
desc "docs [SECTION]", "Show dash configuration documentation"
|
|
155
155
|
def docs(section = nil)
|
|
156
156
|
case section
|
|
157
157
|
when NilClass
|
|
@@ -181,7 +181,7 @@ class Kamal::Cli::Main < Kamal::Cli::Base
|
|
|
181
181
|
end
|
|
182
182
|
|
|
183
183
|
desc "init", "Create config stub in config/deploy.yml and secrets stub in .kamal"
|
|
184
|
-
option :bundle, type: :boolean, default: false, desc: "Add
|
|
184
|
+
option :bundle, type: :boolean, default: false, desc: "Add dash to the Gemfile and create a bin/dash binstub"
|
|
185
185
|
def init
|
|
186
186
|
require "fileutils"
|
|
187
187
|
|
|
@@ -208,15 +208,15 @@ class Kamal::Cli::Main < Kamal::Cli::Base
|
|
|
208
208
|
end
|
|
209
209
|
|
|
210
210
|
if options[:bundle]
|
|
211
|
-
if (binstub = Pathname.new(File.expand_path("bin/
|
|
212
|
-
puts "Binstub already exists in bin/
|
|
211
|
+
if (binstub = Pathname.new(File.expand_path("bin/dash"))).exist?
|
|
212
|
+
puts "Binstub already exists in bin/dash (remove first to create a new one)"
|
|
213
213
|
else
|
|
214
|
-
puts "Adding
|
|
214
|
+
puts "Adding dash to Gemfile and bundle..."
|
|
215
215
|
run_locally do
|
|
216
|
-
execute :bundle, :add, :
|
|
217
|
-
execute :bundle, :binstubs, :
|
|
216
|
+
execute :bundle, :add, :dash
|
|
217
|
+
execute :bundle, :binstubs, :dash
|
|
218
218
|
end
|
|
219
|
-
puts "Created binstub file in bin/
|
|
219
|
+
puts "Created binstub file in bin/dash"
|
|
220
220
|
end
|
|
221
221
|
end
|
|
222
222
|
end
|
|
@@ -265,7 +265,7 @@ class Kamal::Cli::Main < Kamal::Cli::Base
|
|
|
265
265
|
end
|
|
266
266
|
end
|
|
267
267
|
|
|
268
|
-
desc "version", "Show
|
|
268
|
+
desc "version", "Show dash version"
|
|
269
269
|
def version
|
|
270
270
|
puts Kamal::VERSION
|
|
271
271
|
end
|
|
@@ -13,7 +13,7 @@ class Kamal::Cli::Proxy::Drift
|
|
|
13
13
|
|
|
14
14
|
# A proxy container has drifted when it was started with a different config
|
|
15
15
|
# digest than the one the current configuration produces. Containers booted
|
|
16
|
-
# by older
|
|
16
|
+
# by older dash versions carry no digest label and count as drifted, so
|
|
17
17
|
# they converge on the first deploy after upgrading.
|
|
18
18
|
def drifted?
|
|
19
19
|
return @drifted if defined?(@drifted)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Ownership bookkeeping for a load balancer host that more than one
|
|
1
|
+
# Ownership bookkeeping for a load balancer host that more than one dash app
|
|
2
2
|
# may be deploying to. Kamal only ever sees one deploy.yml at a time, so the
|
|
3
3
|
# other apps are visible solely through the files they left on the host.
|
|
4
4
|
class Kamal::Cli::Proxy::LoadbalancerClaim
|
|
@@ -29,7 +29,7 @@ class Kamal::Cli::Proxy::LoadbalancerClaim
|
|
|
29
29
|
# Every app sharing a load balancer boots the same container, so their
|
|
30
30
|
# proxy/run configurations have to agree. A mismatch owned by another app is
|
|
31
31
|
# an error; a mismatch owned by this app is ordinary drift, reported the same
|
|
32
|
-
# way the per-host proxy reports it and fixed by `
|
|
32
|
+
# way the per-host proxy reports it and fixed by `dash proxy reboot`.
|
|
33
33
|
def claim_run_config(replace: false)
|
|
34
34
|
record = capture_with_info(*commands.read_run_config_record, raise_on_non_zero_exit: false).strip
|
|
35
35
|
|
|
@@ -43,7 +43,7 @@ class Kamal::Cli::Proxy::LoadbalancerClaim
|
|
|
43
43
|
"Apps sharing a load balancer must agree on proxy/run - align the configurations or use a different load balancer host."
|
|
44
44
|
elsif !replace
|
|
45
45
|
warn "The load balancer on #{host} is running with a configuration that no longer matches the deploy config - " \
|
|
46
|
-
"run `
|
|
46
|
+
"run `dash proxy reboot` to apply the new configuration."
|
|
47
47
|
return
|
|
48
48
|
end
|
|
49
49
|
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Replaces the loadbalancer container with one booted from the current
|
|
2
|
-
# configuration. Shared by `
|
|
2
|
+
# configuration. Shared by `dash proxy reboot` and the drift-detected reboot
|
|
3
3
|
# on boot - the same sequence either way, so the two paths cannot diverge.
|
|
4
4
|
#
|
|
5
5
|
# Unlike the proxy hosts' port-holder handoff this is stop -> run: the
|
data/lib/kamal/cli/proxy.rb
CHANGED
|
@@ -33,7 +33,7 @@ class Kamal::Cli::Proxy < Kamal::Cli::Base
|
|
|
33
33
|
version = capture_with_info(*proxy.version).strip.presence
|
|
34
34
|
|
|
35
35
|
if version && Kamal::Utils.older_version?(version, Kamal::Configuration::Proxy::Run::MINIMUM_VERSION)
|
|
36
|
-
raise "kamal-proxy version #{version} is too old, run `
|
|
36
|
+
raise "kamal-proxy version #{version} is too old, run `dash proxy reboot` in order to update to at least #{Kamal::Configuration::Proxy::Run::MINIMUM_VERSION}"
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
if (run_config = proxy.proxy_run_config)&.secrets?
|
|
@@ -52,7 +52,7 @@ class Kamal::Cli::Proxy < Kamal::Cli::Base
|
|
|
52
52
|
|
|
53
53
|
if stale_hosts.any?
|
|
54
54
|
say "kamal-proxy on #{stale_hosts.sort.join(", ")} is running with a configuration that no longer matches the deploy config. " \
|
|
55
|
-
"Automatic reboot is disabled (proxy: reboot_on_deploy: false) - run `
|
|
55
|
+
"Automatic reboot is disabled (proxy: reboot_on_deploy: false) - run `dash proxy reboot` to apply the new configuration.", :yellow
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
drifted_hosts.sort.each do |host|
|
|
@@ -114,7 +114,7 @@ class Kamal::Cli::Proxy < Kamal::Cli::Base
|
|
|
114
114
|
|
|
115
115
|
if lb_stale.any?
|
|
116
116
|
say "The loadbalancer on #{lb_stale.sort.join(", ")} is running with a configuration that no longer matches the deploy config. " \
|
|
117
|
-
"Automatic reboot is disabled (proxy: reboot_on_deploy: false) - run `
|
|
117
|
+
"Automatic reboot is disabled (proxy: reboot_on_deploy: false) - run `dash proxy reboot` to apply the new configuration.", :yellow
|
|
118
118
|
end
|
|
119
119
|
|
|
120
120
|
lb_drifted.sort.each do |host|
|
|
@@ -316,7 +316,7 @@ class Kamal::Cli::Proxy < Kamal::Cli::Base
|
|
|
316
316
|
end
|
|
317
317
|
|
|
318
318
|
# `docker container prune` only collects stopped containers, so leaving the
|
|
319
|
-
# loadbalancer running would also leave `
|
|
319
|
+
# loadbalancer running would also leave `dash proxy remove` unable to
|
|
320
320
|
# remove it.
|
|
321
321
|
if KAMAL.config.proxy.load_balancing?
|
|
322
322
|
on(KAMAL.config.proxy.effective_loadbalancer) do
|
|
@@ -539,7 +539,7 @@ class Kamal::Cli::Proxy < Kamal::Cli::Base
|
|
|
539
539
|
|
|
540
540
|
desc "import_certs", "Import certificates into the TLS certificate store from a Traefik acme.json or an exported archive"
|
|
541
541
|
option :traefik_acme, type: :string, default: nil, desc: "Local path of a Traefik acme.json to import from"
|
|
542
|
-
option :archive, type: :string, default: nil, desc: "Local path of an archive written by
|
|
542
|
+
option :archive, type: :string, default: nil, desc: "Local path of an archive written by dash proxy export_certs"
|
|
543
543
|
option :resolver, type: :string, default: nil, desc: "Import only this Traefik resolver's certificates (default: all, last writer wins per domain)"
|
|
544
544
|
option :force, type: :boolean, default: false, desc: "Overwrite a non-empty certificate store when restoring an archive"
|
|
545
545
|
option :verify, type: :boolean, default: false, desc: "Only verify the archive: report domains and expiries without touching the store"
|
|
@@ -560,7 +560,7 @@ class Kamal::Cli::Proxy < Kamal::Cli::Base
|
|
|
560
560
|
if capture_with_info(*commands.container_id(only_running: true), raise_on_non_zero_exit: false).strip.present?
|
|
561
561
|
raise "Cannot import certificates while the #{load_balancing ? "loadbalancer" : "proxy"} " \
|
|
562
562
|
"is running on #{host} - stop it first " \
|
|
563
|
-
"(
|
|
563
|
+
"(dash proxy #{load_balancing ? "loadbalancer stop" : "stop"}), import, then start it again"
|
|
564
564
|
end
|
|
565
565
|
end
|
|
566
566
|
|
|
@@ -682,7 +682,7 @@ class Kamal::Cli::Proxy < Kamal::Cli::Base
|
|
|
682
682
|
if force
|
|
683
683
|
say "Forcing, so removing the proxy, even though other apps are installed", :magenta
|
|
684
684
|
else
|
|
685
|
-
say "Not removing the proxy, as other apps are installed, ignore this check with
|
|
685
|
+
say "Not removing the proxy, as other apps are installed, ignore this check with dash proxy remove --force", :magenta
|
|
686
686
|
end
|
|
687
687
|
|
|
688
688
|
force
|
data/lib/kamal/cli/registry.rb
CHANGED
|
@@ -30,7 +30,7 @@ class Kamal::Cli::Registry < Kamal::Cli::Base
|
|
|
30
30
|
option :skip_remote, aliases: "-R", type: :boolean, default: false, desc: "Skip remote login"
|
|
31
31
|
def login
|
|
32
32
|
if KAMAL.registry.local?
|
|
33
|
-
raise "Cannot use login command with a local registry. Use `
|
|
33
|
+
raise "Cannot use login command with a local registry. Use `dash registry setup` instead."
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
setup
|
|
@@ -41,7 +41,7 @@ class Kamal::Cli::Registry < Kamal::Cli::Base
|
|
|
41
41
|
option :skip_remote, aliases: "-R", type: :boolean, default: false, desc: "Skip remote login"
|
|
42
42
|
def logout
|
|
43
43
|
if KAMAL.registry.local?
|
|
44
|
-
raise "Cannot use logout command with a local registry. Use `
|
|
44
|
+
raise "Cannot use logout command with a local registry. Use `dash registry remove` instead."
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
remove
|
data/lib/kamal/cli/server.rb
CHANGED
|
@@ -49,8 +49,8 @@ builder:
|
|
|
49
49
|
# secret:
|
|
50
50
|
# - RAILS_MASTER_KEY
|
|
51
51
|
|
|
52
|
-
# Aliases are triggered with "bin/
|
|
53
|
-
# "bin/
|
|
52
|
+
# Aliases are triggered with "bin/dash <alias>". You can overwrite arguments on invocation:
|
|
53
|
+
# "bin/dash app logs -r job" will tail logs from the first server in the job section.
|
|
54
54
|
#
|
|
55
55
|
# aliases:
|
|
56
56
|
# shell: app exec --interactive --reuse "bash"
|
|
@@ -13,10 +13,10 @@
|
|
|
13
13
|
# RAILS_MASTER_KEY=$(cat config/master.key)
|
|
14
14
|
# KAMAL_REGISTRY_PASSWORD=$(rails credentials:fetch kamal.registry_password)
|
|
15
15
|
|
|
16
|
-
# Option 3: Read secrets via
|
|
16
|
+
# Option 3: Read secrets via dash secrets helpers
|
|
17
17
|
# These will handle logging in and fetching the secrets in as few calls as possible
|
|
18
18
|
# There are adapters for 1Password, LastPass + Bitwarden
|
|
19
19
|
#
|
|
20
|
-
# SECRETS=$(
|
|
21
|
-
# KAMAL_REGISTRY_PASSWORD=$(
|
|
22
|
-
# RAILS_MASTER_KEY=$(
|
|
20
|
+
# SECRETS=$(dash secrets fetch --adapter 1password --account my-account --from MyVault/MyItem KAMAL_REGISTRY_PASSWORD RAILS_MASTER_KEY)
|
|
21
|
+
# KAMAL_REGISTRY_PASSWORD=$(dash secrets extract KAMAL_REGISTRY_PASSWORD $SECRETS)
|
|
22
|
+
# RAILS_MASTER_KEY=$(dash secrets extract RAILS_MASTER_KEY $SECRETS)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Certificate store transfer, shared by the proxy and loadbalancer command
|
|
2
|
-
# builders (
|
|
2
|
+
# builders (dash proxy export_certs / import_certs).
|
|
3
3
|
#
|
|
4
4
|
# Archives leave through the apps-config bind mount — the one container path
|
|
5
5
|
# that is also a host path — and arrive through stdin into a one-off container:
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
# Accessories are managed separately from the main service — they are not updated
|
|
7
7
|
# when you deploy, and they do not have zero-downtime deployments.
|
|
8
8
|
#
|
|
9
|
-
# Run `
|
|
10
|
-
# See `
|
|
9
|
+
# Run `dash accessory boot <accessory>` to boot an accessory.
|
|
10
|
+
# See `dash accessory --help` for more information.
|
|
11
11
|
|
|
12
12
|
# Configuring accessories
|
|
13
13
|
#
|
|
@@ -40,7 +40,7 @@ accessories:
|
|
|
40
40
|
# <<: *specific-registry
|
|
41
41
|
# ```
|
|
42
42
|
#
|
|
43
|
-
# See
|
|
43
|
+
# See dash docs registry for more information:
|
|
44
44
|
registry:
|
|
45
45
|
...
|
|
46
46
|
|
|
@@ -83,7 +83,7 @@ accessories:
|
|
|
83
83
|
|
|
84
84
|
# Environment variables
|
|
85
85
|
#
|
|
86
|
-
# See
|
|
86
|
+
# See dash docs env for more information:
|
|
87
87
|
env:
|
|
88
88
|
...
|
|
89
89
|
|
|
@@ -157,10 +157,10 @@ accessories:
|
|
|
157
157
|
#
|
|
158
158
|
# You can run your accessory behind the Kamal proxy for hostname-based
|
|
159
159
|
# routing and automatic SSL. The block accepts the same schema as the
|
|
160
|
-
# app-level `proxy:` (see `
|
|
160
|
+
# app-level `proxy:` (see `dash docs proxy`), though root-only keys such as
|
|
161
161
|
# `loadbalancer` and `reboot_on_deploy` have no effect inside an accessory.
|
|
162
162
|
# Declaring a proxy here makes the accessory's hosts proxy hosts:
|
|
163
|
-
# `
|
|
163
|
+
# `dash proxy boot` (and `dash deploy`) will run kamal-proxy on them
|
|
164
164
|
# automatically.
|
|
165
165
|
#
|
|
166
166
|
# Accessories are never load balanced. The loadbalancer fans the app's own
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# For example, for a Rails app, you might open a console with:
|
|
6
6
|
#
|
|
7
7
|
# ```shell
|
|
8
|
-
#
|
|
8
|
+
# dash app exec -i --reuse "bin/rails console"
|
|
9
9
|
# ```
|
|
10
10
|
#
|
|
11
11
|
# By defining an alias, like this:
|
|
@@ -14,7 +14,7 @@ aliases:
|
|
|
14
14
|
# You can now open the console with:
|
|
15
15
|
#
|
|
16
16
|
# ```shell
|
|
17
|
-
#
|
|
17
|
+
# dash console
|
|
18
18
|
# ```
|
|
19
19
|
|
|
20
20
|
# Configuring aliases
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
#
|
|
7
7
|
# This is a whole-deploy setting: `limit` slices the combined host list of every role, so it cannot
|
|
8
8
|
# hold one role back while another keeps booting. To pace a single role's hosts, set `boot` on that
|
|
9
|
-
# role instead (see
|
|
9
|
+
# role instead (see dash docs role).
|
|
10
10
|
|
|
11
11
|
boot:
|
|
12
12
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# Destinations
|
|
6
6
|
#
|
|
7
7
|
# When running commands, you can specify a destination with the `-d` flag,
|
|
8
|
-
# e.g., `
|
|
8
|
+
# e.g., `dash deploy -d staging`.
|
|
9
9
|
#
|
|
10
10
|
# In this case, the configuration will also be read from `config/deploy.staging.yml`
|
|
11
11
|
# and merged with the base configuration.
|
|
@@ -44,19 +44,19 @@ volumes:
|
|
|
44
44
|
|
|
45
45
|
# Registry
|
|
46
46
|
#
|
|
47
|
-
# The Docker registry configuration, see
|
|
47
|
+
# The Docker registry configuration, see dash docs registry:
|
|
48
48
|
registry:
|
|
49
49
|
...
|
|
50
50
|
|
|
51
51
|
# Servers
|
|
52
52
|
#
|
|
53
|
-
# The servers to deploy to, optionally with custom roles, see
|
|
53
|
+
# The servers to deploy to, optionally with custom roles, see dash docs servers:
|
|
54
54
|
servers:
|
|
55
55
|
...
|
|
56
56
|
|
|
57
57
|
# Environment variables
|
|
58
58
|
#
|
|
59
|
-
# See
|
|
59
|
+
# See dash docs env:
|
|
60
60
|
env:
|
|
61
61
|
...
|
|
62
62
|
|
|
@@ -171,59 +171,59 @@ stop_timeout: 30
|
|
|
171
171
|
|
|
172
172
|
# Run directory
|
|
173
173
|
#
|
|
174
|
-
# Directory to store
|
|
174
|
+
# Directory to store dash runtime files in on the host, default `.kamal`:
|
|
175
175
|
run_directory: /etc/kamal
|
|
176
176
|
|
|
177
177
|
# SSH options
|
|
178
178
|
#
|
|
179
|
-
# See
|
|
179
|
+
# See dash docs ssh:
|
|
180
180
|
ssh:
|
|
181
181
|
...
|
|
182
182
|
|
|
183
183
|
# Builder options
|
|
184
184
|
#
|
|
185
|
-
# See
|
|
185
|
+
# See dash docs builder:
|
|
186
186
|
builder:
|
|
187
187
|
...
|
|
188
188
|
|
|
189
189
|
# Accessories
|
|
190
190
|
#
|
|
191
|
-
# Additional services to run in Docker, see
|
|
191
|
+
# Additional services to run in Docker, see dash docs accessory:
|
|
192
192
|
accessories:
|
|
193
193
|
...
|
|
194
194
|
|
|
195
195
|
# Proxy
|
|
196
196
|
#
|
|
197
|
-
# Configuration for kamal-proxy, see
|
|
197
|
+
# Configuration for kamal-proxy, see dash docs proxy:
|
|
198
198
|
proxy:
|
|
199
199
|
...
|
|
200
200
|
|
|
201
201
|
# SSHKit
|
|
202
202
|
#
|
|
203
|
-
# See
|
|
203
|
+
# See dash docs sshkit:
|
|
204
204
|
sshkit:
|
|
205
205
|
...
|
|
206
206
|
|
|
207
207
|
# Boot options
|
|
208
208
|
#
|
|
209
|
-
# See
|
|
209
|
+
# See dash docs boot:
|
|
210
210
|
boot:
|
|
211
211
|
...
|
|
212
212
|
|
|
213
213
|
# Logging
|
|
214
214
|
#
|
|
215
|
-
# Docker logging configuration, see
|
|
215
|
+
# Docker logging configuration, see dash docs logging:
|
|
216
216
|
logging:
|
|
217
217
|
...
|
|
218
218
|
|
|
219
219
|
# Output
|
|
220
220
|
#
|
|
221
|
-
# Configure output loggers (OTel, file), see
|
|
221
|
+
# Configure output loggers (OTel, file), see dash docs output:
|
|
222
222
|
output:
|
|
223
223
|
...
|
|
224
224
|
|
|
225
225
|
# Aliases
|
|
226
226
|
#
|
|
227
|
-
# Alias configuration, see
|
|
227
|
+
# Alias configuration, see dash docs alias:
|
|
228
228
|
aliases:
|
|
229
229
|
...
|
|
@@ -34,10 +34,10 @@ env:
|
|
|
34
34
|
# You can also use [secret helpers](../../commands/secrets) for some common password managers.
|
|
35
35
|
#
|
|
36
36
|
# ```shell
|
|
37
|
-
# SECRETS=$(
|
|
37
|
+
# SECRETS=$(dash secrets fetch ...)
|
|
38
38
|
#
|
|
39
|
-
# REGISTRY_PASSWORD=$(
|
|
40
|
-
# DB_PASSWORD=$(
|
|
39
|
+
# REGISTRY_PASSWORD=$(dash secrets extract REGISTRY_PASSWORD $SECRETS)
|
|
40
|
+
# DB_PASSWORD=$(dash secrets extract DB_PASSWORD $SECRETS)
|
|
41
41
|
# ```
|
|
42
42
|
#
|
|
43
43
|
# If you store secrets directly in `.kamal/secrets`, ensure that it is not checked into version control.
|
|
@@ -62,10 +62,10 @@ env:
|
|
|
62
62
|
# on the context.
|
|
63
63
|
#
|
|
64
64
|
# ```shell
|
|
65
|
-
# SECRETS=$(
|
|
65
|
+
# SECRETS=$(dash secrets fetch ...)
|
|
66
66
|
#
|
|
67
|
-
# MAIN_DB_PASSWORD=$(
|
|
68
|
-
# SECONDARY_DB_PASSWORD=$(
|
|
67
|
+
# MAIN_DB_PASSWORD=$(dash secrets extract MAIN_DB_PASSWORD $SECRETS)
|
|
68
|
+
# SECONDARY_DB_PASSWORD=$(dash secrets extract SECONDARY_DB_PASSWORD $SECRETS)
|
|
69
69
|
# ```
|
|
70
70
|
env:
|
|
71
71
|
secret:
|
|
@@ -87,7 +87,7 @@ accessories:
|
|
|
87
87
|
# Tags
|
|
88
88
|
#
|
|
89
89
|
# Tags are used to add extra env variables to specific hosts.
|
|
90
|
-
# See
|
|
90
|
+
# See dash docs servers for how to tag hosts.
|
|
91
91
|
#
|
|
92
92
|
# Tags are only allowed in the top-level env configuration (i.e., not under a role-specific env).
|
|
93
93
|
#
|
|
@@ -71,17 +71,17 @@ proxy:
|
|
|
71
71
|
# for multi-host primary roles.
|
|
72
72
|
loadbalancer: lb.example.com
|
|
73
73
|
|
|
74
|
-
# Sharing one loadbalancer between several
|
|
74
|
+
# Sharing one loadbalancer between several dash apps
|
|
75
75
|
#
|
|
76
|
-
# More than one
|
|
76
|
+
# More than one dash app may point `loadbalancer:` at the same host. Each app
|
|
77
77
|
# registers its own service on the shared kamal-proxy and keeps its own
|
|
78
78
|
# deploy.yml; the load balancer multiplexes them by hostname.
|
|
79
79
|
#
|
|
80
|
-
# The rules
|
|
80
|
+
# The rules dash enforces for that topology:
|
|
81
81
|
#
|
|
82
82
|
# * Service state survives a reboot. kamal-proxy persists its services in the
|
|
83
83
|
# `kamal-loadbalancer-config` volume (or `kamal-proxy-config` when the
|
|
84
|
-
# loadbalancer shares a proxy host), and `
|
|
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.
|
|
87
87
|
#
|
|
@@ -96,21 +96,21 @@ proxy:
|
|
|
96
96
|
# same container, so the first app to boot records its run configuration in
|
|
97
97
|
# `.kamal/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
|
-
# warning and applies it on `
|
|
99
|
+
# warning and applies it on `dash proxy reboot`.
|
|
100
100
|
#
|
|
101
|
-
# * `
|
|
101
|
+
# * `dash proxy remove` refuses while other apps are installed on the
|
|
102
102
|
# loadbalancer host, exactly as it does for a proxy host. Use `--force` to
|
|
103
103
|
# override, which removes the shared loadbalancer for every app on it.
|
|
104
104
|
|
|
105
105
|
# Automatic proxy reboot on deploy
|
|
106
106
|
#
|
|
107
|
-
# When `
|
|
107
|
+
# When `dash deploy` detects that the running kamal-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.
|
|
111
111
|
#
|
|
112
112
|
# Set to false to opt out. Kamal will then print a warning when drift is
|
|
113
|
-
# detected and leave the proxy untouched until you run `
|
|
113
|
+
# detected and leave the proxy untouched until you run `dash proxy reboot`.
|
|
114
114
|
#
|
|
115
115
|
# Root-level `proxy` setting only; ignored inside role-specific proxy blocks.
|
|
116
116
|
#
|
|
@@ -155,7 +155,7 @@ proxy:
|
|
|
155
155
|
# in an incoming handshake. A path is resolved against a healthy app target; an
|
|
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
|
-
# `host`/`hosts`, with `certificate_pem`, or with `ssl_domains` —
|
|
158
|
+
# `host`/`hosts`, with `certificate_pem`, or with `ssl_domains` — dash rejects
|
|
159
159
|
# those at config time, because kamal-proxy would reject the deploy and there
|
|
160
160
|
# is no sensible winner to pick.
|
|
161
161
|
#
|
|
@@ -258,7 +258,7 @@ proxy:
|
|
|
258
258
|
# whitespace trimmed. A value may contain colons — a CSP naming a scheme or a
|
|
259
259
|
# port survives intact.
|
|
260
260
|
#
|
|
261
|
-
# Two things
|
|
261
|
+
# Two things dash rejects rather than letting them fail late: a value with a
|
|
262
262
|
# newline or carriage return in it (that is response splitting, and shell
|
|
263
263
|
# escaping would silently turn it into a literal backslash-n), and a *request*
|
|
264
264
|
# rule naming `Host` — Go carries the host outside the header map, so the rule
|
|
@@ -450,7 +450,7 @@ proxy:
|
|
|
450
450
|
# `header` names the header carrying the original client IP (`CF-Connecting-IP`
|
|
451
451
|
# behind Cloudflare, `True-Client-IP` behind some others); kamal-proxy reads it
|
|
452
452
|
# instead of `X-Forwarded-For`. It is only honoured when `trusted_proxies` is
|
|
453
|
-
# set, because otherwise it is just something the client wrote —
|
|
453
|
+
# set, because otherwise it is just something the client wrote — dash rejects
|
|
454
454
|
# that combination rather than appearing to honour it.
|
|
455
455
|
#
|
|
456
456
|
# Addresses and ranges are plain IPv4/IPv6 or CIDR. Write IPv4 as IPv4, not as
|
|
@@ -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
|
|
504
|
+
# '^$' pattern. Patterns are matched by kamal-proxy (Go RE2), so dash checks
|
|
505
505
|
# only their shape, not their syntax.
|
|
506
506
|
deny_user_agents:
|
|
507
507
|
- 'BadBot/.*'
|
|
@@ -509,7 +509,7 @@ proxy:
|
|
|
509
509
|
# ### Notes
|
|
510
510
|
# - The health check path is served without an address check and without a rate
|
|
511
511
|
# limit, so it stays reachable during a deploy. That means it cannot be `/` —
|
|
512
|
-
#
|
|
512
|
+
# dash rejects `healthcheck: path: /` while either feature is on, because it
|
|
513
513
|
# would leave the whole service open. The default `/up` is fine.
|
|
514
514
|
# - When a loadbalancer is configured, all of this moves to the loadbalancer:
|
|
515
515
|
# the per-host proxies see the loadbalancer as their peer, so an allow list
|
|
@@ -681,17 +681,17 @@ proxy:
|
|
|
681
681
|
#
|
|
682
682
|
# ### Administering it
|
|
683
683
|
#
|
|
684
|
-
# `
|
|
684
|
+
# `dash proxy cache stats` reports what the cache is holding (add `--count`
|
|
685
685
|
# to measure entries and bytes per service, `--json` for the raw report),
|
|
686
|
-
# and `
|
|
686
|
+
# and `dash proxy cache purge` drops this app's cached responses
|
|
687
687
|
# (`--path-prefix /assets` to narrow it). Both run on the layer that owns
|
|
688
688
|
# the cache - the loadbalancer when load balancing, else each proxy host.
|
|
689
689
|
#
|
|
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
|
-
# `
|
|
694
|
-
# `
|
|
693
|
+
# `dash proxy cache stats`; kamal-proxy also explains every refusal — check
|
|
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
|
|
697
697
|
# app's response, a `Set-Cookie` header, a body over `max_body`, and
|
|
@@ -792,7 +792,7 @@ proxy:
|
|
|
792
792
|
#
|
|
793
793
|
# Stopping and starting containers means talking to the runtime, so the proxy
|
|
794
794
|
# must have been booted with `run/docker_socket` set. That is a boot-time
|
|
795
|
-
# prerequisite for a deploy-time setting, so
|
|
795
|
+
# prerequisite for a deploy-time setting, so dash checks it while reading this
|
|
796
796
|
# file rather than letting the first request hang.
|
|
797
797
|
#
|
|
798
798
|
# Setting `run/docker_socket` also mounts that socket into the proxy container
|
|
@@ -832,9 +832,9 @@ proxy:
|
|
|
832
832
|
# `repository` to a host-less path (e.g.
|
|
833
833
|
# myfork/kamal-proxy) - the default repository
|
|
834
834
|
# below already embeds its ghcr.io host
|
|
835
|
-
repository: ghcr.io/zoolutions/
|
|
835
|
+
repository: ghcr.io/zoolutions/dash-proxy # Container repository for the
|
|
836
836
|
# kamal-proxy image (this is the default)
|
|
837
|
-
version: v1.0.0.
|
|
837
|
+
version: v1.0.0.6 # Version tag of the kamal-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
|
|
@@ -890,7 +890,7 @@ proxy:
|
|
|
890
890
|
# zone, and `docker run --env` would leave it in process listings and audit
|
|
891
891
|
# logs. Adding or renaming one changes the proxy's config digest, so the next
|
|
892
892
|
# deploy reboots the proxy to pick it up; rotating a value does not, so run
|
|
893
|
-
# `
|
|
893
|
+
# `dash proxy reboot` yourself after a rotation.
|
|
894
894
|
acme:
|
|
895
895
|
email: admin@example.com
|
|
896
896
|
dns_provider:
|
|
@@ -1035,12 +1035,12 @@ proxy:
|
|
|
1035
1035
|
# `rediss://` URL that every proxy pointed at it shares, so one fetch warms
|
|
1036
1036
|
# the whole fleet.
|
|
1037
1037
|
#
|
|
1038
|
-
# The URL never appears on the proxy's command line:
|
|
1038
|
+
# The URL never appears on the proxy's command line: dash delivers it as
|
|
1039
1039
|
# `CACHE_STORE` in a 0600 env file on the host (alongside any ACME
|
|
1040
1040
|
# credentials), so a password in the URL stays out of process listings and
|
|
1041
1041
|
# kamal's audit log. The trade-off, same as the ACME credentials: changing
|
|
1042
1042
|
# only the URL's *value* does not move the drift digest — run
|
|
1043
|
-
# `
|
|
1043
|
+
# `dash proxy reboot` after rotating it.
|
|
1044
1044
|
#
|
|
1045
1045
|
# `store_timeout` only matters with a shared store, in seconds: how long
|
|
1046
1046
|
# the store may take to answer before the request goes to the app instead —
|
|
@@ -15,7 +15,7 @@ servers:
|
|
|
15
15
|
#
|
|
16
16
|
# This can be a list of hosts if you don't need custom configuration for the role.
|
|
17
17
|
#
|
|
18
|
-
# You can set tags on the hosts for custom env variables (see
|
|
18
|
+
# You can set tags on the hosts for custom env variables (see dash docs env):
|
|
19
19
|
web:
|
|
20
20
|
- 172.1.0.1
|
|
21
21
|
- 172.1.0.2: experiment1
|
|
@@ -11,7 +11,7 @@ servers:
|
|
|
11
11
|
|
|
12
12
|
# Tagging servers
|
|
13
13
|
#
|
|
14
|
-
# Servers can be tagged, with the tags used to add custom env variables (see
|
|
14
|
+
# Servers can be tagged, with the tags used to add custom env variables (see dash docs env).
|
|
15
15
|
servers:
|
|
16
16
|
- 172.0.0.1
|
|
17
17
|
- 172.0.0.2: experiments
|
|
@@ -19,7 +19,7 @@ servers:
|
|
|
19
19
|
|
|
20
20
|
# Roles
|
|
21
21
|
#
|
|
22
|
-
# For more complex deployments (e.g., if you are running job hosts), you can specify roles and configure each separately (see
|
|
22
|
+
# For more complex deployments (e.g., if you are running job hosts), you can specify roles and configure each separately (see dash docs role):
|
|
23
23
|
servers:
|
|
24
24
|
web:
|
|
25
25
|
...
|
|
@@ -34,13 +34,15 @@ class Kamal::Configuration::Proxy::Boot
|
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
def image_name
|
|
37
|
-
"
|
|
37
|
+
"dash-proxy"
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
def image_default
|
|
41
41
|
"#{repository_name}/#{image_name}"
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
+
# Stays kamal-proxy until the server-artifact rename ships a migration
|
|
45
|
+
# bridge — every deployed host has a running container by this name.
|
|
44
46
|
def container_name
|
|
45
47
|
"kamal-proxy"
|
|
46
48
|
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
class Kamal::Configuration::Proxy::Run
|
|
2
|
-
MINIMUM_VERSION = "v1.0.0.
|
|
2
|
+
MINIMUM_VERSION = "v1.0.0.6"
|
|
3
3
|
DEFAULT_HTTP_PORT = 80
|
|
4
4
|
DEFAULT_HTTPS_PORT = 443
|
|
5
5
|
DEFAULT_LOG_MAX_SIZE = "10m"
|
|
@@ -37,7 +37,7 @@ class Kamal::Configuration::Proxy::Run
|
|
|
37
37
|
# running. The values deliberately stay out — the digest is published as a
|
|
38
38
|
# docker label, and hashing secret material into a world-readable label buys
|
|
39
39
|
# an offline guessing target for nothing. Rotating a credential's value or
|
|
40
|
-
# the store URL still needs an explicit `
|
|
40
|
+
# the store URL still needs an explicit `dash proxy reboot`.
|
|
41
41
|
def config_digest
|
|
42
42
|
self.class.digest(image, run_command, *docker_options_args, *secret_names)
|
|
43
43
|
end
|
|
@@ -95,7 +95,7 @@ class Kamal::Configuration::Proxy::Run
|
|
|
95
95
|
end
|
|
96
96
|
|
|
97
97
|
def repository
|
|
98
|
-
run_config.fetch("repository", "ghcr.io/zoolutions/
|
|
98
|
+
run_config.fetch("repository", "ghcr.io/zoolutions/dash-proxy")
|
|
99
99
|
end
|
|
100
100
|
|
|
101
101
|
def image
|
|
@@ -201,7 +201,7 @@ class Kamal::Configuration::Proxy::Run
|
|
|
201
201
|
# Where the proxy's secrets land on the host - the ACME DNS credentials and
|
|
202
202
|
# the cache store URL, which may embed one. Under the proxy's own directory
|
|
203
203
|
# rather than the app's env directory, because the container is host-scoped
|
|
204
|
-
# and shared by every app on the host - and so `
|
|
204
|
+
# and shared by every app on the host - and so `dash proxy remove` takes
|
|
205
205
|
# the secrets with it.
|
|
206
206
|
def secrets_path
|
|
207
207
|
File.join host_directory, SECRETS_FILENAME
|
|
@@ -287,7 +287,7 @@ class Kamal::Configuration::Proxy
|
|
|
287
287
|
client_ca_pem.present?
|
|
288
288
|
end
|
|
289
289
|
|
|
290
|
-
# Resolved at upload time, not config time, so `
|
|
290
|
+
# Resolved at upload time, not config time, so `dash app logs` and friends
|
|
291
291
|
# work on machines without the secret. A blank secret raises like
|
|
292
292
|
# basic_auth.password_secret - silently deploying without the client CA
|
|
293
293
|
# would turn mTLS off.
|
|
@@ -79,7 +79,7 @@ class Kamal::Configuration::Role
|
|
|
79
79
|
end
|
|
80
80
|
|
|
81
81
|
# Kept out of option_args on purpose: Commands::App::Execution splats those into
|
|
82
|
-
# one-shot `
|
|
82
|
+
# one-shot `dash app exec` containers, which must not inherit a service healthcheck.
|
|
83
83
|
def healthcheck_args
|
|
84
84
|
healthcheck&.args || []
|
|
85
85
|
end
|
|
@@ -43,7 +43,7 @@ class Kamal::Configuration::Ssh
|
|
|
43
43
|
if secrets.key?(k)
|
|
44
44
|
secrets[k]
|
|
45
45
|
else
|
|
46
|
-
warn "Inline key_data usage is deprecated and will be removed in
|
|
46
|
+
warn "Inline key_data usage is deprecated and will be removed in a future dash release. Please store your key_data in a secret."
|
|
47
47
|
k
|
|
48
48
|
end
|
|
49
49
|
end
|
data/lib/kamal/configuration.rb
CHANGED
|
@@ -451,7 +451,7 @@ class Kamal::Configuration
|
|
|
451
451
|
return true if offenders.empty?
|
|
452
452
|
|
|
453
453
|
warn "Non-proxied role(s) #{offenders.map(&:name).join(", ")} have no healthcheck. " \
|
|
454
|
-
"Without one,
|
|
454
|
+
"Without one, dash accepts the container as ready #{readiness_delay}s after it merely starts " \
|
|
455
455
|
"and then stops the previous container — traffic can be dropped. Add a `healthcheck:` block, " \
|
|
456
456
|
"or opt out explicitly with `healthcheck: false`. This warning will become an error in a future release."
|
|
457
457
|
|
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
# Usage
|
|
5
5
|
#
|
|
6
6
|
# Fetch all password from FooBar item
|
|
7
|
-
# `
|
|
7
|
+
# `dash secrets fetch --adapter enpass --from /Users/YOUR_USERNAME/Library/Containers/in.sinew.Enpass-Desktop/Data/Documents/Vaults/primary FooBar`
|
|
8
8
|
#
|
|
9
9
|
# Fetch only DB_PASSWORD from FooBar item
|
|
10
|
-
# `
|
|
10
|
+
# `dash secrets fetch --adapter enpass --from /Users/YOUR_USERNAME/Library/Containers/in.sinew.Enpass-Desktop/Data/Documents/Vaults/primary FooBar/DB_PASSWORD`
|
|
11
11
|
class Kamal::Secrets::Adapters::Enpass < Kamal::Secrets::Adapters::Base
|
|
12
12
|
def requires_account?
|
|
13
13
|
false
|
|
@@ -29,7 +29,9 @@ class Kamal::Secrets::Dotenv::InlineCommandSubstitution
|
|
|
29
29
|
$LAST_MATCH_INFO[0][1..]
|
|
30
30
|
else
|
|
31
31
|
command = ::Dotenv::Substitutions::Variable.call(command, env)
|
|
32
|
-
|
|
32
|
+
# Accept the legacy `kamal secrets` spelling too — secrets files
|
|
33
|
+
# written before the dash rename still use it.
|
|
34
|
+
if command =~ /\A\s*(dash|kamal)\s*secrets\s+/
|
|
33
35
|
# Inline the command
|
|
34
36
|
inline_secrets_command(command)
|
|
35
37
|
else
|
data/lib/kamal/version.rb
CHANGED
data/lib/kamal.rb
CHANGED
|
@@ -12,7 +12,7 @@ require "uri"
|
|
|
12
12
|
# so the first reference happens in several SSHKit threads at once. Digest defines
|
|
13
13
|
# SHA256 lazily — `Digest.const_missing(:SHA256)` runs `require "digest/sha2"`, and
|
|
14
14
|
# that path is not mutex-guarded — so the threads race it and one loses with
|
|
15
|
-
# "Digest::Base cannot be directly inherited in Ruby", failing `
|
|
15
|
+
# "Digest::Base cannot be directly inherited in Ruby", failing `dash proxy boot`
|
|
16
16
|
# on a random host.
|
|
17
17
|
#
|
|
18
18
|
# Requiring "digest" alone does NOT fix this: it defines the module but leaves
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dash
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mikael Henriksson
|
|
@@ -16,6 +16,9 @@ dependencies:
|
|
|
16
16
|
- - ">="
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
18
|
version: '7.0'
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '10'
|
|
19
22
|
type: :runtime
|
|
20
23
|
prerelease: false
|
|
21
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -23,6 +26,9 @@ dependencies:
|
|
|
23
26
|
- - ">="
|
|
24
27
|
- !ruby/object:Gem::Version
|
|
25
28
|
version: '7.0'
|
|
29
|
+
- - "<"
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: '10'
|
|
26
32
|
- !ruby/object:Gem::Dependency
|
|
27
33
|
name: sshkit
|
|
28
34
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -161,73 +167,15 @@ dependencies:
|
|
|
161
167
|
- - "~>"
|
|
162
168
|
- !ruby/object:Gem::Version
|
|
163
169
|
version: '0.2'
|
|
164
|
-
|
|
165
|
-
name: debug
|
|
166
|
-
requirement: !ruby/object:Gem::Requirement
|
|
167
|
-
requirements:
|
|
168
|
-
- - ">="
|
|
169
|
-
- !ruby/object:Gem::Version
|
|
170
|
-
version: '0'
|
|
171
|
-
type: :development
|
|
172
|
-
prerelease: false
|
|
173
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
174
|
-
requirements:
|
|
175
|
-
- - ">="
|
|
176
|
-
- !ruby/object:Gem::Version
|
|
177
|
-
version: '0'
|
|
178
|
-
- !ruby/object:Gem::Dependency
|
|
179
|
-
name: minitest
|
|
180
|
-
requirement: !ruby/object:Gem::Requirement
|
|
181
|
-
requirements:
|
|
182
|
-
- - "<"
|
|
183
|
-
- !ruby/object:Gem::Version
|
|
184
|
-
version: '6'
|
|
185
|
-
type: :development
|
|
186
|
-
prerelease: false
|
|
187
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
188
|
-
requirements:
|
|
189
|
-
- - "<"
|
|
190
|
-
- !ruby/object:Gem::Version
|
|
191
|
-
version: '6'
|
|
192
|
-
- !ruby/object:Gem::Dependency
|
|
193
|
-
name: mocha
|
|
194
|
-
requirement: !ruby/object:Gem::Requirement
|
|
195
|
-
requirements:
|
|
196
|
-
- - ">="
|
|
197
|
-
- !ruby/object:Gem::Version
|
|
198
|
-
version: '0'
|
|
199
|
-
type: :development
|
|
200
|
-
prerelease: false
|
|
201
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
202
|
-
requirements:
|
|
203
|
-
- - ">="
|
|
204
|
-
- !ruby/object:Gem::Version
|
|
205
|
-
version: '0'
|
|
206
|
-
- !ruby/object:Gem::Dependency
|
|
207
|
-
name: railties
|
|
208
|
-
requirement: !ruby/object:Gem::Requirement
|
|
209
|
-
requirements:
|
|
210
|
-
- - ">="
|
|
211
|
-
- !ruby/object:Gem::Version
|
|
212
|
-
version: '0'
|
|
213
|
-
type: :development
|
|
214
|
-
prerelease: false
|
|
215
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
216
|
-
requirements:
|
|
217
|
-
- - ">="
|
|
218
|
-
- !ruby/object:Gem::Version
|
|
219
|
-
version: '0'
|
|
220
|
-
email: mikael@mhenrixon.com
|
|
170
|
+
email: mikael@zoolutions.llc
|
|
221
171
|
executables:
|
|
222
172
|
- dash
|
|
223
|
-
- kamal
|
|
224
173
|
extensions: []
|
|
225
174
|
extra_rdoc_files: []
|
|
226
175
|
files:
|
|
227
176
|
- MIT-LICENSE
|
|
228
177
|
- README.md
|
|
229
178
|
- bin/dash
|
|
230
|
-
- bin/kamal
|
|
231
179
|
- lib/kamal.rb
|
|
232
180
|
- lib/kamal/cli.rb
|
|
233
181
|
- lib/kamal/cli/accessory.rb
|
|
@@ -381,10 +329,15 @@ files:
|
|
|
381
329
|
- lib/kamal/utils.rb
|
|
382
330
|
- lib/kamal/utils/sensitive.rb
|
|
383
331
|
- lib/kamal/version.rb
|
|
384
|
-
homepage: https://github.com/
|
|
332
|
+
homepage: https://github.com/zoolutions/dash
|
|
385
333
|
licenses:
|
|
386
334
|
- MIT
|
|
387
|
-
metadata:
|
|
335
|
+
metadata:
|
|
336
|
+
homepage_uri: https://github.com/zoolutions/dash
|
|
337
|
+
source_code_uri: https://github.com/zoolutions/dash/tree/main
|
|
338
|
+
changelog_uri: https://github.com/zoolutions/dash/releases
|
|
339
|
+
bug_tracker_uri: https://github.com/zoolutions/dash/issues
|
|
340
|
+
rubygems_mfa_required: 'true'
|
|
388
341
|
rdoc_options: []
|
|
389
342
|
require_paths:
|
|
390
343
|
- lib
|
|
@@ -399,7 +352,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
399
352
|
- !ruby/object:Gem::Version
|
|
400
353
|
version: '0'
|
|
401
354
|
requirements: []
|
|
402
|
-
rubygems_version:
|
|
355
|
+
rubygems_version: 3.6.9
|
|
403
356
|
specification_version: 4
|
|
404
357
|
summary: Deploy web apps in containers to servers running Docker with zero downtime.
|
|
405
358
|
test_files: []
|
data/bin/kamal
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
|
|
3
|
-
# Prevent failures from being reported twice.
|
|
4
|
-
Thread.report_on_exception = false
|
|
5
|
-
|
|
6
|
-
require "kamal"
|
|
7
|
-
|
|
8
|
-
begin
|
|
9
|
-
Kamal::Cli::Main.start(ARGV)
|
|
10
|
-
rescue SSHKit::Runner::ExecuteError => e
|
|
11
|
-
puts " \e[31mERROR (#{e.cause.class}): #{e.message}\e[0m"
|
|
12
|
-
puts e.cause.backtrace if ENV["VERBOSE"]
|
|
13
|
-
exit 1
|
|
14
|
-
rescue => e
|
|
15
|
-
puts " \e[31mERROR (#{e.class}): #{e.message}\e[0m"
|
|
16
|
-
puts e.backtrace if ENV["VERBOSE"]
|
|
17
|
-
exit 1
|
|
18
|
-
end
|