kamal 2.8.2 → 2.10.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/lib/kamal/cli/accessory.rb +14 -7
- data/lib/kamal/cli/app/boot.rb +1 -1
- data/lib/kamal/cli/app.rb +74 -115
- data/lib/kamal/cli/healthcheck/poller.rb +1 -1
- data/lib/kamal/cli/main.rb +2 -1
- data/lib/kamal/cli/proxy.rb +42 -35
- data/lib/kamal/cli/secrets.rb +2 -1
- data/lib/kamal/cli/server.rb +2 -1
- data/lib/kamal/cli/templates/secrets +1 -0
- data/lib/kamal/commander.rb +3 -2
- data/lib/kamal/commands/app/execution.rb +7 -1
- data/lib/kamal/commands/app.rb +1 -1
- data/lib/kamal/commands/proxy.rb +21 -2
- data/lib/kamal/configuration/accessory.rb +63 -26
- data/lib/kamal/configuration/boot.rb +4 -0
- data/lib/kamal/configuration/builder.rb +10 -3
- data/lib/kamal/configuration/docs/accessory.yml +37 -5
- data/lib/kamal/configuration/docs/boot.yml +12 -10
- data/lib/kamal/configuration/docs/configuration.yml +10 -1
- data/lib/kamal/configuration/docs/proxy.yml +24 -0
- data/lib/kamal/configuration/docs/ssh.yml +7 -4
- data/lib/kamal/configuration/docs/sshkit.yml +8 -0
- data/lib/kamal/configuration/env.rb +7 -3
- data/lib/kamal/configuration/proxy/boot.rb +4 -9
- data/lib/kamal/configuration/proxy/run.rb +143 -0
- data/lib/kamal/configuration/proxy.rb +2 -2
- data/lib/kamal/configuration/role.rb +15 -3
- data/lib/kamal/configuration/ssh.rb +18 -3
- data/lib/kamal/configuration/sshkit.rb +4 -0
- data/lib/kamal/configuration/validator/proxy.rb +20 -0
- data/lib/kamal/configuration/validator.rb +34 -1
- data/lib/kamal/configuration/volume.rb +11 -4
- data/lib/kamal/configuration.rb +32 -1
- data/lib/kamal/secrets/adapters/passbolt.rb +1 -2
- data/lib/kamal/secrets/adapters/test.rb +3 -1
- data/lib/kamal/secrets/dotenv/inline_command_substitution.rb +15 -1
- data/lib/kamal/secrets.rb +17 -6
- data/lib/kamal/sshkit_with_ext.rb +127 -10
- data/lib/kamal/utils.rb +3 -3
- data/lib/kamal/version.rb +1 -1
- metadata +2 -1
data/lib/kamal/cli/secrets.rb
CHANGED
|
@@ -12,8 +12,9 @@ class Kamal::Cli::Secrets < Kamal::Cli::Base
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
results = adapter.fetch(secrets, **options.slice(:account, :from).symbolize_keys)
|
|
15
|
+
json = JSON.dump(results)
|
|
15
16
|
|
|
16
|
-
return_or_puts
|
|
17
|
+
return_or_puts options[:inline] ? json.shellescape : json, inline: options[:inline]
|
|
17
18
|
end
|
|
18
19
|
|
|
19
20
|
desc "extract", "Extract a single secret from the results of a fetch call"
|
data/lib/kamal/cli/server.rb
CHANGED
|
@@ -6,6 +6,7 @@ class Kamal::Cli::Server < Kamal::Cli::Base
|
|
|
6
6
|
|
|
7
7
|
cmd = Kamal::Utils.join_commands(cmd)
|
|
8
8
|
hosts = KAMAL.hosts
|
|
9
|
+
quiet = options[:quiet]
|
|
9
10
|
|
|
10
11
|
case
|
|
11
12
|
when options[:interactive]
|
|
@@ -19,7 +20,7 @@ class Kamal::Cli::Server < Kamal::Cli::Base
|
|
|
19
20
|
|
|
20
21
|
on(hosts) do |host|
|
|
21
22
|
execute *KAMAL.auditor.record("Executed cmd '#{cmd}' on #{host}"), verbosity: :debug
|
|
22
|
-
puts_by_host host, capture_with_info(cmd)
|
|
23
|
+
puts_by_host host, capture_with_info(cmd), quiet: quiet
|
|
23
24
|
end
|
|
24
25
|
end
|
|
25
26
|
end
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
# Option 2: Read secrets via a command
|
|
9
9
|
# RAILS_MASTER_KEY=$(cat config/master.key)
|
|
10
|
+
# KAMAL_REGISTRY_PASSWORD=$(rails credentials:fetch kamal.registry_password)
|
|
10
11
|
|
|
11
12
|
# Option 3: Read secrets via kamal secrets helpers
|
|
12
13
|
# These will handle logging in and fetching the secrets in as few calls as possible
|
data/lib/kamal/commander.rb
CHANGED
|
@@ -109,8 +109,8 @@ class Kamal::Commander
|
|
|
109
109
|
@commands[:lock] ||= Kamal::Commands::Lock.new(config)
|
|
110
110
|
end
|
|
111
111
|
|
|
112
|
-
def proxy
|
|
113
|
-
|
|
112
|
+
def proxy(host)
|
|
113
|
+
Kamal::Commands::Proxy.new(config, host: host)
|
|
114
114
|
end
|
|
115
115
|
|
|
116
116
|
def prune
|
|
@@ -155,6 +155,7 @@ class Kamal::Commander
|
|
|
155
155
|
SSHKit::Backend::Netssh.pool.idle_timeout = config.sshkit.pool_idle_timeout
|
|
156
156
|
SSHKit::Backend::Netssh.configure do |sshkit|
|
|
157
157
|
sshkit.max_concurrent_starts = config.sshkit.max_concurrent_starts
|
|
158
|
+
sshkit.dns_retries = config.sshkit.dns_retries
|
|
158
159
|
sshkit.ssh_options = config.ssh.options
|
|
159
160
|
end
|
|
160
161
|
SSHKit.config.command_map[:docker] = "docker" # No need to use /usr/bin/env, just clogs up the logs
|
|
@@ -12,6 +12,7 @@ module Kamal::Commands::App::Execution
|
|
|
12
12
|
(docker_interactive_args if interactive),
|
|
13
13
|
("--detach" if detach),
|
|
14
14
|
("--rm" unless detach),
|
|
15
|
+
"--name", container_name_for_exec,
|
|
15
16
|
"--network", "kamal",
|
|
16
17
|
*role&.env_args(host),
|
|
17
18
|
*argumentize("--env", env),
|
|
@@ -22,11 +23,16 @@ module Kamal::Commands::App::Execution
|
|
|
22
23
|
*command
|
|
23
24
|
end
|
|
24
25
|
|
|
25
|
-
def execute_in_existing_container_over_ssh(*command,
|
|
26
|
+
def execute_in_existing_container_over_ssh(*command, env:)
|
|
26
27
|
run_over_ssh execute_in_existing_container(*command, interactive: true, env: env), host: host
|
|
27
28
|
end
|
|
28
29
|
|
|
29
30
|
def execute_in_new_container_over_ssh(*command, env:)
|
|
30
31
|
run_over_ssh execute_in_new_container(*command, interactive: true, env: env), host: host
|
|
31
32
|
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
def container_name_for_exec
|
|
36
|
+
[ role.container_prefix, "exec", config.version, SecureRandom.hex(3) ].compact.join("-")
|
|
37
|
+
end
|
|
32
38
|
end
|
data/lib/kamal/commands/app.rb
CHANGED
|
@@ -23,7 +23,7 @@ class Kamal::Commands::App < Kamal::Commands::Base
|
|
|
23
23
|
"--env", "KAMAL_CONTAINER_NAME=\"#{container_name}\"",
|
|
24
24
|
"--env", "KAMAL_VERSION=\"#{config.version}\"",
|
|
25
25
|
"--env", "KAMAL_HOST=\"#{host}\"",
|
|
26
|
-
"--env", "KAMAL_DESTINATION=\"#{config.destination}\"",
|
|
26
|
+
*([ "--env", "KAMAL_DESTINATION=\"#{config.destination}\"" ] if config.destination),
|
|
27
27
|
*role.env_args(host),
|
|
28
28
|
*role.logging_args,
|
|
29
29
|
*config.volume_args,
|
data/lib/kamal/commands/proxy.rb
CHANGED
|
@@ -1,8 +1,27 @@
|
|
|
1
1
|
class Kamal::Commands::Proxy < Kamal::Commands::Base
|
|
2
2
|
delegate :argumentize, :optionize, to: Kamal::Utils
|
|
3
|
+
attr_reader :proxy_run_config
|
|
4
|
+
|
|
5
|
+
def initialize(config, host:)
|
|
6
|
+
super(config)
|
|
7
|
+
@proxy_run_config = config.proxy_run(host)
|
|
8
|
+
end
|
|
3
9
|
|
|
4
10
|
def run
|
|
5
|
-
|
|
11
|
+
if proxy_run_config
|
|
12
|
+
docker \
|
|
13
|
+
:run,
|
|
14
|
+
"--name", container_name,
|
|
15
|
+
"--network", "kamal",
|
|
16
|
+
"--detach",
|
|
17
|
+
"--restart", "unless-stopped",
|
|
18
|
+
"--volume", "kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy",
|
|
19
|
+
*proxy_run_config.docker_options_args,
|
|
20
|
+
*proxy_run_config.image,
|
|
21
|
+
*proxy_run_config.run_command
|
|
22
|
+
else
|
|
23
|
+
pipe boot_config, xargs(docker_run)
|
|
24
|
+
end
|
|
6
25
|
end
|
|
7
26
|
|
|
8
27
|
def start
|
|
@@ -82,7 +101,7 @@ class Kamal::Commands::Proxy < Kamal::Commands::Base
|
|
|
82
101
|
end
|
|
83
102
|
|
|
84
103
|
def read_image_version
|
|
85
|
-
read_file(config.proxy_boot.image_version_file, default: Kamal::Configuration::Proxy::
|
|
104
|
+
read_file(config.proxy_boot.image_version_file, default: Kamal::Configuration::Proxy::Run::MINIMUM_VERSION)
|
|
86
105
|
end
|
|
87
106
|
|
|
88
107
|
def read_run_command
|
|
@@ -74,25 +74,31 @@ class Kamal::Configuration::Accessory
|
|
|
74
74
|
end
|
|
75
75
|
|
|
76
76
|
def files
|
|
77
|
-
accessory_config["files"]&.to_h do |
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
accessory_config["files"]&.to_h do |config|
|
|
78
|
+
parse_path_config(config, default_mode: "755") do |local, remote|
|
|
79
|
+
{
|
|
80
|
+
key: expand_local_file(local),
|
|
81
|
+
host_path: expand_remote_file(remote),
|
|
82
|
+
container_path: remote
|
|
83
|
+
}
|
|
84
|
+
end
|
|
80
85
|
end || {}
|
|
81
86
|
end
|
|
82
87
|
|
|
83
88
|
def directories
|
|
84
|
-
accessory_config["directories"]&.to_h do |
|
|
85
|
-
|
|
86
|
-
|
|
89
|
+
accessory_config["directories"]&.to_h do |config|
|
|
90
|
+
parse_path_config(config, default_mode: nil) do |local, remote|
|
|
91
|
+
{
|
|
92
|
+
key: expand_host_path(local),
|
|
93
|
+
host_path: expand_host_path_for_volume(local),
|
|
94
|
+
container_path: remote
|
|
95
|
+
}
|
|
96
|
+
end
|
|
87
97
|
end || {}
|
|
88
98
|
end
|
|
89
99
|
|
|
90
|
-
def volumes
|
|
91
|
-
specific_volumes + remote_files_as_volumes + remote_directories_as_volumes
|
|
92
|
-
end
|
|
93
|
-
|
|
94
100
|
def volume_args
|
|
95
|
-
|
|
101
|
+
(specific_volumes + path_volumes(files) + path_volumes(directories)).flat_map(&:docker_args)
|
|
96
102
|
end
|
|
97
103
|
|
|
98
104
|
def option_args
|
|
@@ -142,17 +148,17 @@ class Kamal::Configuration::Accessory
|
|
|
142
148
|
|
|
143
149
|
def expand_local_file(local_file)
|
|
144
150
|
if local_file.end_with?("erb")
|
|
145
|
-
|
|
151
|
+
with_env_loaded { read_dynamic_file(local_file) }
|
|
146
152
|
else
|
|
147
153
|
Pathname.new(File.expand_path(local_file)).to_s
|
|
148
154
|
end
|
|
149
155
|
end
|
|
150
156
|
|
|
151
|
-
def
|
|
152
|
-
env.
|
|
157
|
+
def with_env_loaded
|
|
158
|
+
env.to_h.each { |k, v| ENV[k] = v }
|
|
153
159
|
yield
|
|
154
160
|
ensure
|
|
155
|
-
env.
|
|
161
|
+
env.to_h.each { |k, v| ENV.delete(k) }
|
|
156
162
|
end
|
|
157
163
|
|
|
158
164
|
def read_dynamic_file(local_file)
|
|
@@ -164,27 +170,58 @@ class Kamal::Configuration::Accessory
|
|
|
164
170
|
end
|
|
165
171
|
|
|
166
172
|
def specific_volumes
|
|
167
|
-
accessory_config["volumes"] || []
|
|
173
|
+
(accessory_config["volumes"] || []).collect do |volume_string|
|
|
174
|
+
host_path, container_path, options = volume_string.split(":", 3)
|
|
175
|
+
Kamal::Configuration::Volume.new \
|
|
176
|
+
host_path: host_path,
|
|
177
|
+
container_path: container_path,
|
|
178
|
+
options: options
|
|
179
|
+
end
|
|
168
180
|
end
|
|
169
181
|
|
|
170
|
-
def
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
182
|
+
def path_volumes(paths)
|
|
183
|
+
paths.map do |local, config|
|
|
184
|
+
Kamal::Configuration::Volume.new \
|
|
185
|
+
host_path: config[:host_path],
|
|
186
|
+
container_path: config[:container_path],
|
|
187
|
+
options: config[:options]
|
|
188
|
+
end
|
|
175
189
|
end
|
|
176
190
|
|
|
177
|
-
def
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
191
|
+
def parse_path_config(config, default_mode:)
|
|
192
|
+
if config.is_a?(Hash)
|
|
193
|
+
local, remote = config["local"], config["remote"]
|
|
194
|
+
expanded = yield(local, remote)
|
|
195
|
+
[
|
|
196
|
+
expanded[:key],
|
|
197
|
+
expanded.except(:key).merge(
|
|
198
|
+
options: config["options"],
|
|
199
|
+
mode: config["mode"] || default_mode,
|
|
200
|
+
owner: config["owner"]
|
|
201
|
+
)
|
|
202
|
+
]
|
|
203
|
+
else
|
|
204
|
+
local, remote, options = config.split(":", 3)
|
|
205
|
+
expanded = yield(local, remote)
|
|
206
|
+
[
|
|
207
|
+
expanded[:key],
|
|
208
|
+
expanded.except(:key).merge(
|
|
209
|
+
options: options,
|
|
210
|
+
mode: default_mode,
|
|
211
|
+
owner: nil
|
|
212
|
+
)
|
|
213
|
+
]
|
|
214
|
+
end
|
|
182
215
|
end
|
|
183
216
|
|
|
184
217
|
def expand_host_path(host_path)
|
|
185
218
|
absolute_path?(host_path) ? host_path : File.join(service_data_directory, host_path)
|
|
186
219
|
end
|
|
187
220
|
|
|
221
|
+
def expand_host_path_for_volume(host_path)
|
|
222
|
+
absolute_path?(host_path) ? host_path : File.join(service_name, host_path)
|
|
223
|
+
end
|
|
224
|
+
|
|
188
225
|
def absolute_path?(path)
|
|
189
226
|
Pathname.new(path).absolute?
|
|
190
227
|
end
|
|
@@ -177,8 +177,15 @@ class Kamal::Configuration::Builder
|
|
|
177
177
|
[ server, cache_image ].compact.join("/")
|
|
178
178
|
end
|
|
179
179
|
|
|
180
|
+
def cache_options
|
|
181
|
+
builder_config["cache"]&.fetch("options", nil)
|
|
182
|
+
end
|
|
183
|
+
|
|
180
184
|
def cache_from_config_for_gha
|
|
181
|
-
|
|
185
|
+
individual_options = cache_options&.split(",") || []
|
|
186
|
+
allowed_options = individual_options.select { |option| option =~ /^(url|url_v2|token|scope|timeout)=/ }
|
|
187
|
+
|
|
188
|
+
[ "type=gha", *allowed_options ].compact.join(",")
|
|
182
189
|
end
|
|
183
190
|
|
|
184
191
|
def cache_from_config_for_registry
|
|
@@ -186,11 +193,11 @@ class Kamal::Configuration::Builder
|
|
|
186
193
|
end
|
|
187
194
|
|
|
188
195
|
def cache_to_config_for_gha
|
|
189
|
-
[ "type=gha",
|
|
196
|
+
[ "type=gha", cache_options ].compact.join(",")
|
|
190
197
|
end
|
|
191
198
|
|
|
192
199
|
def cache_to_config_for_registry
|
|
193
|
-
[ "type=registry", "ref=#{cache_image_ref}",
|
|
200
|
+
[ "type=registry", "ref=#{cache_image_ref}", cache_options ].compact.join(",")
|
|
194
201
|
end
|
|
195
202
|
|
|
196
203
|
def repo_basename
|
|
@@ -90,22 +90,54 @@ accessories:
|
|
|
90
90
|
# Copying files
|
|
91
91
|
#
|
|
92
92
|
# You can specify files to mount into the container.
|
|
93
|
-
# The format is `local:remote`, where `local` is the path to the file on the local machine
|
|
94
|
-
# and `remote` is the path to the file in the container.
|
|
95
93
|
#
|
|
96
94
|
# They will be uploaded from the local repo to the host and then mounted.
|
|
97
|
-
#
|
|
98
95
|
# ERB files will be evaluated before being copied.
|
|
96
|
+
#
|
|
97
|
+
# You can use the string format: `local:remote` or `local:remote:options`
|
|
98
|
+
# where the options can be `ro` for read-only or `z`/`Z` for SELinux labels
|
|
99
99
|
files:
|
|
100
100
|
- config/my.cnf.erb:/etc/mysql/my.cnf
|
|
101
|
-
- config/myoptions.cnf:/etc/mysql/myoptions.cnf
|
|
101
|
+
- config/myoptions.cnf:/etc/mysql/myoptions.cnf:ro
|
|
102
|
+
- config/certs:/etc/mysql/certs:ro,Z
|
|
103
|
+
#
|
|
104
|
+
# Or you can use the hash format for custom mode and ownership.
|
|
105
|
+
#
|
|
106
|
+
# Note: Setting `owner` requires root access:
|
|
107
|
+
files:
|
|
108
|
+
- local: config/secret.key
|
|
109
|
+
remote: /etc/mysql/secret.key
|
|
110
|
+
mode: "0600"
|
|
111
|
+
owner: "mysql:mysql"
|
|
112
|
+
- local: config/ca-cert.pem
|
|
113
|
+
remote: /etc/mysql/certs/ca-cert.pem
|
|
114
|
+
mode: "0644"
|
|
115
|
+
owner: "1000:1000"
|
|
116
|
+
options: "Z"
|
|
102
117
|
|
|
103
118
|
# Directories
|
|
104
119
|
#
|
|
105
120
|
# You can specify directories to mount into the container. They will be created on the host
|
|
106
|
-
# before being mounted
|
|
121
|
+
# before being mounted.
|
|
122
|
+
#
|
|
123
|
+
# You can use the string format: `local:remote` or `local:remote:options`
|
|
124
|
+
# where the options can be `ro` for read-only or `z`/`Z` for SELinux labels
|
|
107
125
|
directories:
|
|
108
126
|
- mysql-logs:/var/log/mysql
|
|
127
|
+
- mysql-data:/var/lib/mysql:z
|
|
128
|
+
#
|
|
129
|
+
# Or you can use the hash format for custom mode and ownership.
|
|
130
|
+
#
|
|
131
|
+
# Note: Setting `owner` requires root access:
|
|
132
|
+
directories:
|
|
133
|
+
- local: mysql-data
|
|
134
|
+
remote: /var/lib/mysql
|
|
135
|
+
mode: "0750"
|
|
136
|
+
owner: "mysql:mysql"
|
|
137
|
+
- local: mysql-logs
|
|
138
|
+
remote: /var/log/mysql
|
|
139
|
+
mode: "0755"
|
|
140
|
+
options: "z"
|
|
109
141
|
|
|
110
142
|
# Volumes
|
|
111
143
|
#
|
|
@@ -4,16 +4,18 @@
|
|
|
4
4
|
#
|
|
5
5
|
# Kamal’s default is to boot new containers on all hosts in parallel. However, you can control this with the boot configuration.
|
|
6
6
|
|
|
7
|
-
# Fixed group sizes
|
|
8
|
-
#
|
|
9
|
-
# Here, we boot 2 hosts at a time with a 10-second gap between each group:
|
|
10
7
|
boot:
|
|
11
|
-
limit: 2
|
|
12
|
-
wait: 10
|
|
13
8
|
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
# Here, we boot 25% of the hosts at a time with a 2-second gap between each group:
|
|
17
|
-
boot:
|
|
9
|
+
# The number or percentage of hosts to boot at a time.
|
|
10
|
+
# This can be an integer (e.g., 3) or a percentage string (e.g., 25%).
|
|
18
11
|
limit: 25%
|
|
19
|
-
|
|
12
|
+
|
|
13
|
+
# The number of seconds to wait between booting each group of hosts.
|
|
14
|
+
wait: 10
|
|
15
|
+
|
|
16
|
+
# Whether to boot roles in parallel on a host.
|
|
17
|
+
#
|
|
18
|
+
# If a host has multiple roles, control whether they are booted in parallel or sequentially on that host.
|
|
19
|
+
#
|
|
20
|
+
# Defaults to false.
|
|
21
|
+
parallel_roles: true
|
|
@@ -73,7 +73,10 @@ env:
|
|
|
73
73
|
# This requires that file names change when the contents change
|
|
74
74
|
# (e.g., by including a hash of the contents in the name).
|
|
75
75
|
#
|
|
76
|
-
# To configure this, set the path to the assets
|
|
76
|
+
# To configure this, set the path to the assets.
|
|
77
|
+
#
|
|
78
|
+
# You can also specify mount options after a colon, such as `ro` for read-only
|
|
79
|
+
# or `z`/`Z` for SELinux labels
|
|
77
80
|
asset_path: /path/to/assets
|
|
78
81
|
|
|
79
82
|
# Hooks path
|
|
@@ -82,6 +85,12 @@ asset_path: /path/to/assets
|
|
|
82
85
|
# See https://kamal-deploy.org/docs/hooks for more information:
|
|
83
86
|
hooks_path: /user_home/kamal/hooks
|
|
84
87
|
|
|
88
|
+
# Secrets path
|
|
89
|
+
#
|
|
90
|
+
# Path to secrets, defaults to `.kamal/secrets`.
|
|
91
|
+
# Kamal will look for `<secrets_path>-common` and `<secrets_path>` (or `<secrets_path>.<destination>` when using destinations):
|
|
92
|
+
secrets_path: /user_home/kamal/secrets
|
|
93
|
+
|
|
85
94
|
# Error pages
|
|
86
95
|
#
|
|
87
96
|
# A directory relative to the app root to find error pages for the proxy to serve.
|
|
@@ -148,6 +148,30 @@ proxy:
|
|
|
148
148
|
- X-Request-ID
|
|
149
149
|
- X-Request-Start
|
|
150
150
|
|
|
151
|
+
# Run configuration
|
|
152
|
+
#
|
|
153
|
+
# These options are used when booting the proxy container.
|
|
154
|
+
#
|
|
155
|
+
run:
|
|
156
|
+
http_port: 8080 # HTTP port to use (default 80)
|
|
157
|
+
https_port: 8443 # HTTPS port to use (default 443)
|
|
158
|
+
metrics_port: 9090 # Port for Prometheus metrics
|
|
159
|
+
debug: true # Debug logging (default: false)
|
|
160
|
+
log_max_size: "30m" # Maximum log file size (default: "10m")
|
|
161
|
+
publish: false # Publish ports to the host (default: true)
|
|
162
|
+
bind_ips: # List of IPs to bind to when publishing ports
|
|
163
|
+
- 0.0.0.0
|
|
164
|
+
registry: registry:4443 # Container registry for the kamal-proxy image
|
|
165
|
+
# (defaults to Docker Hub)
|
|
166
|
+
repository: myrepo/kamal-proxy # Container repository for the kamal-proxy image
|
|
167
|
+
# (defaults to `basecamp/kamal-proxy`)
|
|
168
|
+
version: v0.8.0 # Version tag of the kamal-proxy image to use
|
|
169
|
+
options: # Additional options to pass to `docker run`
|
|
170
|
+
label:
|
|
171
|
+
- custom.label=kamal-proxy
|
|
172
|
+
memory: 512m
|
|
173
|
+
cpus: 0.5
|
|
174
|
+
|
|
151
175
|
# Enabling/disabling the proxy on roles
|
|
152
176
|
#
|
|
153
177
|
# The proxy is enabled by default on the primary role but can be disabled by
|
|
@@ -58,13 +58,16 @@ ssh:
|
|
|
58
58
|
|
|
59
59
|
# Key data
|
|
60
60
|
#
|
|
61
|
-
# An array of strings, with each element of the array being
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
# An array of strings, with each element of the array being a secret name.
|
|
62
|
+
key_data:
|
|
63
|
+
- SSH_PRIVATE_KEY
|
|
64
|
+
# You can also provide raw private key in PEM format, but this is deprecated.
|
|
65
|
+
key_data:
|
|
66
|
+
- "-----BEGIN OPENSSH PRIVATE KEY----- ..."
|
|
64
67
|
|
|
65
68
|
# Config
|
|
66
69
|
#
|
|
67
70
|
# Set to true to load the default OpenSSH config files (~/.ssh/config,
|
|
68
71
|
# /etc/ssh_config), to false ignore config files, or to a file path
|
|
69
72
|
# (or array of paths) to load specific configuration. Defaults to true.
|
|
70
|
-
config:
|
|
73
|
+
config: [ "~/.ssh/myconfig" ]
|
|
@@ -21,3 +21,11 @@ sshkit:
|
|
|
21
21
|
# Kamal sets a long idle timeout of 900 seconds on connections to try to avoid
|
|
22
22
|
# re-connection storms after an idle period, such as building an image or waiting for CI.
|
|
23
23
|
pool_idle_timeout: 300
|
|
24
|
+
|
|
25
|
+
# DNS retry settings
|
|
26
|
+
#
|
|
27
|
+
# Some resolvers (mDNSResponder, systemd-resolved, Tailscale) can drop lookups during
|
|
28
|
+
# bursts of concurrent SSH starts. Kamal will retry DNS failures automatically.
|
|
29
|
+
#
|
|
30
|
+
# Number of retries after the initial attempt. Set to 0 to disable.
|
|
31
|
+
dns_retries: 3
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
class Kamal::Configuration::Env
|
|
2
2
|
include Kamal::Configuration::Validation
|
|
3
3
|
|
|
4
|
-
attr_reader :context, :clear, :secret_keys
|
|
4
|
+
attr_reader :context, :clear, :secrets, :secret_keys
|
|
5
5
|
delegate :argumentize, to: Kamal::Utils
|
|
6
6
|
|
|
7
7
|
def initialize(config:, secrets:, context: "env")
|
|
@@ -23,12 +23,16 @@ class Kamal::Configuration::Env
|
|
|
23
23
|
def merge(other)
|
|
24
24
|
self.class.new \
|
|
25
25
|
config: { "clear" => clear.merge(other.clear), "secret" => secret_keys | other.secret_keys },
|
|
26
|
-
secrets:
|
|
26
|
+
secrets: secrets
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def to_h
|
|
30
|
+
clear.merge(aliased_secrets)
|
|
27
31
|
end
|
|
28
32
|
|
|
29
33
|
private
|
|
30
34
|
def aliased_secrets
|
|
31
|
-
secret_keys.to_h { |key| extract_alias(key) }.transform_values { |secret_key|
|
|
35
|
+
secret_keys.to_h { |key| extract_alias(key) }.transform_values { |secret_key| secrets[secret_key] }
|
|
32
36
|
end
|
|
33
37
|
|
|
34
38
|
def extract_alias(key)
|
|
@@ -1,9 +1,4 @@
|
|
|
1
1
|
class Kamal::Configuration::Proxy::Boot
|
|
2
|
-
MINIMUM_VERSION = "v0.9.0"
|
|
3
|
-
DEFAULT_HTTP_PORT = 80
|
|
4
|
-
DEFAULT_HTTPS_PORT = 443
|
|
5
|
-
DEFAULT_LOG_MAX_SIZE = "10m"
|
|
6
|
-
|
|
7
2
|
attr_reader :config
|
|
8
3
|
delegate :argumentize, :optionize, to: Kamal::Utils
|
|
9
4
|
|
|
@@ -16,8 +11,8 @@ class Kamal::Configuration::Proxy::Boot
|
|
|
16
11
|
|
|
17
12
|
(bind_ips || [ nil ]).map do |bind_ip|
|
|
18
13
|
bind_ip = format_bind_ip(bind_ip)
|
|
19
|
-
publish_http = [ bind_ip, http_port, DEFAULT_HTTP_PORT ].compact.join(":")
|
|
20
|
-
publish_https = [ bind_ip, https_port, DEFAULT_HTTPS_PORT ].compact.join(":")
|
|
14
|
+
publish_http = [ bind_ip, http_port, Kamal::Configuration::Proxy::Run::DEFAULT_HTTP_PORT ].compact.join(":")
|
|
15
|
+
publish_https = [ bind_ip, https_port, Kamal::Configuration::Proxy::Run::DEFAULT_HTTPS_PORT ].compact.join(":")
|
|
21
16
|
|
|
22
17
|
argumentize "--publish", [ publish_http, publish_https ]
|
|
23
18
|
end.join(" ")
|
|
@@ -29,8 +24,8 @@ class Kamal::Configuration::Proxy::Boot
|
|
|
29
24
|
|
|
30
25
|
def default_boot_options
|
|
31
26
|
[
|
|
32
|
-
*(publish_args(DEFAULT_HTTP_PORT, DEFAULT_HTTPS_PORT, nil)),
|
|
33
|
-
*(logging_args(DEFAULT_LOG_MAX_SIZE))
|
|
27
|
+
*(publish_args(Kamal::Configuration::Proxy::Run::DEFAULT_HTTP_PORT, Kamal::Configuration::Proxy::Run::DEFAULT_HTTPS_PORT, nil)),
|
|
28
|
+
*(logging_args(Kamal::Configuration::Proxy::Run::DEFAULT_LOG_MAX_SIZE))
|
|
34
29
|
]
|
|
35
30
|
end
|
|
36
31
|
|