kamal 1.8.2 → 2.0.0.beta1
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 +1 -1
- data/lib/kamal/cli/accessory.rb +44 -20
- data/lib/kamal/cli/alias/command.rb +9 -0
- data/lib/kamal/cli/app/boot.rb +22 -16
- data/lib/kamal/cli/app.rb +40 -5
- data/lib/kamal/cli/base.rb +19 -51
- data/lib/kamal/cli/build.rb +12 -13
- data/lib/kamal/cli/healthcheck/barrier.rb +2 -0
- data/lib/kamal/cli/healthcheck/poller.rb +18 -39
- data/lib/kamal/cli/lock.rb +2 -3
- data/lib/kamal/cli/main.rb +54 -51
- data/lib/kamal/cli/proxy.rb +224 -0
- data/lib/kamal/cli/prune.rb +0 -1
- data/lib/kamal/cli/secrets.rb +36 -0
- data/lib/kamal/cli/server.rb +2 -3
- data/lib/kamal/cli/templates/deploy.yml +4 -21
- data/lib/kamal/cli/templates/sample_hooks/post-proxy-reboot.sample +3 -0
- data/lib/kamal/cli/templates/secrets +16 -0
- data/lib/kamal/cli.rb +1 -0
- data/lib/kamal/commander/specifics.rb +3 -3
- data/lib/kamal/commander.rb +24 -8
- data/lib/kamal/commands/accessory.rb +7 -7
- data/lib/kamal/commands/app/assets.rb +8 -8
- data/lib/kamal/commands/app/proxy.rb +16 -0
- data/lib/kamal/commands/app.rb +7 -15
- data/lib/kamal/commands/auditor.rb +6 -3
- data/lib/kamal/commands/base.rb +8 -0
- data/lib/kamal/commands/builder/base.rb +26 -13
- data/lib/kamal/commands/builder/hybrid.rb +21 -0
- data/lib/kamal/commands/builder/local.rb +14 -0
- data/lib/kamal/commands/builder/remote.rb +63 -0
- data/lib/kamal/commands/builder.rb +13 -29
- data/lib/kamal/commands/docker.rb +4 -0
- data/lib/kamal/commands/hook.rb +5 -2
- data/lib/kamal/commands/lock.rb +2 -6
- data/lib/kamal/commands/proxy.rb +77 -0
- data/lib/kamal/commands/prune.rb +1 -9
- data/lib/kamal/commands/server.rb +11 -1
- data/lib/kamal/configuration/accessory.rb +14 -2
- data/lib/kamal/configuration/alias.rb +15 -0
- data/lib/kamal/configuration/builder.rb +52 -18
- data/lib/kamal/configuration/docs/alias.yml +26 -0
- data/lib/kamal/configuration/docs/builder.yml +26 -23
- data/lib/kamal/configuration/docs/configuration.yml +22 -16
- data/lib/kamal/configuration/docs/env.yml +10 -11
- data/lib/kamal/configuration/docs/proxy.yml +100 -0
- data/lib/kamal/configuration/docs/registry.yml +4 -2
- data/lib/kamal/configuration/docs/role.yml +3 -5
- data/lib/kamal/configuration/env/tag.rb +4 -3
- data/lib/kamal/configuration/env.rb +10 -17
- data/lib/kamal/configuration/proxy.rb +66 -0
- data/lib/kamal/configuration/registry.rb +3 -2
- data/lib/kamal/configuration/role.rb +63 -94
- data/lib/kamal/configuration/validator/alias.rb +15 -0
- data/lib/kamal/configuration/validator/builder.rb +4 -0
- data/lib/kamal/configuration/validator/proxy.rb +11 -0
- data/lib/kamal/configuration/validator.rb +42 -24
- data/lib/kamal/configuration.rb +91 -33
- data/lib/kamal/env_file.rb +4 -0
- data/lib/kamal/secrets/adapters/base.rb +18 -0
- data/lib/kamal/secrets/adapters/bitwarden.rb +64 -0
- data/lib/kamal/secrets/adapters/last_pass.rb +30 -0
- data/lib/kamal/secrets/adapters/one_password.rb +61 -0
- data/lib/kamal/secrets/adapters/test.rb +10 -0
- data/lib/kamal/secrets/adapters.rb +14 -0
- data/lib/kamal/secrets/dotenv/inline_command_substitution.rb +32 -0
- data/lib/kamal/secrets.rb +37 -0
- data/lib/kamal/sshkit_with_ext.rb +1 -0
- data/lib/kamal/utils.rb +28 -0
- data/lib/kamal/version.rb +1 -1
- data/lib/kamal.rb +3 -1
- metadata +32 -23
- data/lib/kamal/cli/env.rb +0 -54
- data/lib/kamal/cli/templates/sample_hooks/post-traefik-reboot.sample +0 -3
- data/lib/kamal/cli/templates/template.env +0 -2
- data/lib/kamal/cli/traefik.rb +0 -122
- data/lib/kamal/commands/app/cord.rb +0 -22
- data/lib/kamal/commands/builder/multiarch/remote.rb +0 -61
- data/lib/kamal/commands/builder/multiarch.rb +0 -41
- data/lib/kamal/commands/builder/native/cached.rb +0 -25
- data/lib/kamal/commands/builder/native/remote.rb +0 -67
- data/lib/kamal/commands/builder/native.rb +0 -20
- data/lib/kamal/commands/traefik.rb +0 -85
- data/lib/kamal/configuration/docs/healthcheck.yml +0 -59
- data/lib/kamal/configuration/docs/traefik.yml +0 -62
- data/lib/kamal/configuration/healthcheck.rb +0 -63
- data/lib/kamal/configuration/traefik.rb +0 -60
- /data/lib/kamal/cli/templates/sample_hooks/{pre-traefik-reboot.sample → pre-proxy-reboot.sample} +0 -0
@@ -19,16 +19,38 @@ class Kamal::Configuration::Builder
|
|
19
19
|
builder_config
|
20
20
|
end
|
21
21
|
|
22
|
-
def
|
23
|
-
builder_config["
|
22
|
+
def remote
|
23
|
+
builder_config["remote"]
|
24
24
|
end
|
25
25
|
|
26
|
-
def
|
27
|
-
|
26
|
+
def arches
|
27
|
+
Array(builder_config.fetch("arch", default_arch))
|
28
|
+
end
|
29
|
+
|
30
|
+
def local_arches
|
31
|
+
@local_arches ||= if local_disabled?
|
32
|
+
[]
|
33
|
+
elsif remote
|
34
|
+
arches & [ Kamal::Utils.docker_arch ]
|
35
|
+
else
|
36
|
+
arches
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def remote_arches
|
41
|
+
@remote_arches ||= if remote
|
42
|
+
arches - local_arches
|
43
|
+
else
|
44
|
+
[]
|
45
|
+
end
|
28
46
|
end
|
29
47
|
|
30
48
|
def remote?
|
31
|
-
|
49
|
+
remote_arches.any?
|
50
|
+
end
|
51
|
+
|
52
|
+
def local?
|
53
|
+
!local_disabled? && (arches.empty? || local_arches.any?)
|
32
54
|
end
|
33
55
|
|
34
56
|
def cached?
|
@@ -40,7 +62,7 @@ class Kamal::Configuration::Builder
|
|
40
62
|
end
|
41
63
|
|
42
64
|
def secrets
|
43
|
-
builder_config["secrets"] || []
|
65
|
+
(builder_config["secrets"] || []).to_h { |key| [ key, config.secrets[key] ] }
|
44
66
|
end
|
45
67
|
|
46
68
|
def dockerfile
|
@@ -55,20 +77,12 @@ class Kamal::Configuration::Builder
|
|
55
77
|
builder_config["context"] || "."
|
56
78
|
end
|
57
79
|
|
58
|
-
def
|
59
|
-
builder_config
|
60
|
-
end
|
61
|
-
|
62
|
-
def local_host
|
63
|
-
builder_config["local"]["host"] if local?
|
80
|
+
def driver
|
81
|
+
builder_config.fetch("driver", "docker-container")
|
64
82
|
end
|
65
83
|
|
66
|
-
def
|
67
|
-
builder_config["
|
68
|
-
end
|
69
|
-
|
70
|
-
def remote_host
|
71
|
-
builder_config["remote"]["host"] if remote?
|
84
|
+
def local_disabled?
|
85
|
+
builder_config["local"] == false
|
72
86
|
end
|
73
87
|
|
74
88
|
def cache_from
|
@@ -114,7 +128,23 @@ class Kamal::Configuration::Builder
|
|
114
128
|
end
|
115
129
|
end
|
116
130
|
|
131
|
+
def docker_driver?
|
132
|
+
driver == "docker"
|
133
|
+
end
|
134
|
+
|
117
135
|
private
|
136
|
+
def valid?
|
137
|
+
if docker_driver?
|
138
|
+
raise ArgumentError, "Invalid builder configuration: the `docker` driver does not not support remote builders" if remote
|
139
|
+
raise ArgumentError, "Invalid builder configuration: the `docker` driver does not not support caching" if cached?
|
140
|
+
raise ArgumentError, "Invalid builder configuration: the `docker` driver does not not support multiple arches" if arches.many?
|
141
|
+
end
|
142
|
+
|
143
|
+
if @options["cache"] && @options["cache"]["type"]
|
144
|
+
raise ArgumentError, "Invalid cache type: #{@options["cache"]["type"]}" unless [ "gha", "registry" ].include?(@options["cache"]["type"])
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
118
148
|
def cache_image
|
119
149
|
builder_config["cache"]&.fetch("image", nil) || "#{image}-build-cache"
|
120
150
|
end
|
@@ -150,4 +180,8 @@ class Kamal::Configuration::Builder
|
|
150
180
|
def pwd_sha
|
151
181
|
Digest::SHA256.hexdigest(Dir.pwd)[0..12]
|
152
182
|
end
|
183
|
+
|
184
|
+
def default_arch
|
185
|
+
docker_driver? ? [] : [ "amd64", "arm64" ]
|
186
|
+
end
|
153
187
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# Aliases
|
2
|
+
#
|
3
|
+
# Aliases are shortcuts for Kamal commands.
|
4
|
+
#
|
5
|
+
# For example, for a Rails app, you might open a console with:
|
6
|
+
#
|
7
|
+
# ```shell
|
8
|
+
# kamal app exec -i -r console "rails console"
|
9
|
+
# ```
|
10
|
+
#
|
11
|
+
# By defining an alias, like this:
|
12
|
+
aliases:
|
13
|
+
console: app exec -r console -i "rails console"
|
14
|
+
# You can now open the console with:
|
15
|
+
# ```shell
|
16
|
+
# kamal console
|
17
|
+
# ```
|
18
|
+
|
19
|
+
# Configuring aliases
|
20
|
+
#
|
21
|
+
# Aliases are defined in the root config under the alias key
|
22
|
+
#
|
23
|
+
# Each alias is named and can only contain lowercase letters, numbers, dashes and underscores.
|
24
|
+
|
25
|
+
aliases:
|
26
|
+
uname: app exec -p -q -r web "uname -a"
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# Builder
|
2
2
|
#
|
3
|
-
# The builder configuration controls how the application is built with `docker build`
|
3
|
+
# The builder configuration controls how the application is built with `docker build`
|
4
4
|
#
|
5
5
|
# If no configuration is specified, Kamal will:
|
6
|
-
# 1. Create a buildx context called `kamal
|
7
|
-
# 2. Use `docker
|
6
|
+
# 1. Create a buildx context called `kamal-local-docker-container`, using the docker-container driver
|
7
|
+
# 2. Use `docker build` to build a multiarch image for linux/amd64,linux/arm64 with that context
|
8
8
|
#
|
9
9
|
# See https://kamal-deploy.org/docs/configuration/builder-examples/ for more information
|
10
10
|
|
@@ -13,35 +13,33 @@
|
|
13
13
|
# Options go under the builder key in the root configuration.
|
14
14
|
builder:
|
15
15
|
|
16
|
-
#
|
16
|
+
# Arch
|
17
17
|
#
|
18
|
-
#
|
19
|
-
multiarch: false
|
20
|
-
|
21
|
-
# Local configuration
|
18
|
+
# The architectures to build for - you can set an array or just a single value.
|
22
19
|
#
|
23
|
-
#
|
20
|
+
# Allowed values are `amd64` and `arm64`
|
21
|
+
arch:
|
22
|
+
- amd64
|
23
|
+
|
24
|
+
# Remote
|
24
25
|
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
|
28
|
-
local:
|
29
|
-
arch: amd64
|
30
|
-
host: /var/run/docker.sock
|
26
|
+
# The connection string for a remote builder. If supplied Kamal will use this
|
27
|
+
# for builds that do not match the local architecture of the deployment host.
|
28
|
+
remote: ssh://docker@docker-builder
|
31
29
|
|
32
|
-
#
|
30
|
+
# Local
|
31
|
+
#
|
32
|
+
# If set to false, Kamal will always use the remote builder even when building
|
33
|
+
# the local architecture.
|
33
34
|
#
|
34
|
-
#
|
35
|
-
|
36
|
-
remote:
|
37
|
-
arch: arm64
|
38
|
-
host: ssh://docker@docker-builder
|
35
|
+
# Defaults to true
|
36
|
+
local: true
|
39
37
|
|
40
38
|
# Builder cache
|
41
39
|
#
|
42
40
|
# The type must be either 'gha' or 'registry'
|
43
41
|
#
|
44
|
-
# The image is only used for registry cache
|
42
|
+
# The image is only used for registry cache. Not compatible with the docker driver
|
45
43
|
cache:
|
46
44
|
type: registry
|
47
45
|
options: mode=max
|
@@ -80,7 +78,7 @@ builder:
|
|
80
78
|
|
81
79
|
# Build secrets
|
82
80
|
#
|
83
|
-
# Values are read from the
|
81
|
+
# Values are read from the .kamal/secrets.
|
84
82
|
#
|
85
83
|
secrets:
|
86
84
|
- SECRET1
|
@@ -105,3 +103,8 @@ builder:
|
|
105
103
|
#
|
106
104
|
# SSH agent socket or keys to expose to the build
|
107
105
|
ssh: default=$SSH_AUTH_SOCK
|
106
|
+
|
107
|
+
# Driver
|
108
|
+
#
|
109
|
+
# The build driver to use, defaults to `docker-container`
|
110
|
+
driver: docker
|
@@ -70,7 +70,7 @@ env:
|
|
70
70
|
# volume containing both sets of files.
|
71
71
|
# This requires that file names change when the contents change
|
72
72
|
# (e.g. by including a hash of the contents in the name).
|
73
|
-
|
73
|
+
#
|
74
74
|
# To configure this, set the path to the assets:
|
75
75
|
asset_path: /path/to/assets
|
76
76
|
|
@@ -93,11 +93,6 @@ primary_role: workers
|
|
93
93
|
# Whether roles with no servers are allowed. Defaults to `false`.
|
94
94
|
allow_empty_roles: false
|
95
95
|
|
96
|
-
# Stop wait time
|
97
|
-
#
|
98
|
-
# How long we wait for a container to stop before killing it, defaults to 30 seconds
|
99
|
-
stop_wait_time: 60
|
100
|
-
|
101
96
|
# Retain containers
|
102
97
|
#
|
103
98
|
# How many old containers and images we retain, defaults to 5
|
@@ -111,9 +106,20 @@ minimum_version: 1.3.0
|
|
111
106
|
# Readiness delay
|
112
107
|
#
|
113
108
|
# Seconds to wait for a container to boot after is running, default 7
|
114
|
-
#
|
109
|
+
#
|
110
|
+
# This only applies to containers that do not run a proxy or specify a healthcheck
|
115
111
|
readiness_delay: 4
|
116
112
|
|
113
|
+
# Deploy timeout
|
114
|
+
#
|
115
|
+
# How long to wait for a container to become ready, default 30
|
116
|
+
deploy_timeout: 10
|
117
|
+
|
118
|
+
# Drain timeout
|
119
|
+
#
|
120
|
+
# How long to wait for a containers to drain, default 30
|
121
|
+
drain_timeout: 10
|
122
|
+
|
117
123
|
# Run directory
|
118
124
|
#
|
119
125
|
# Directory to store kamal runtime files in on the host, default `.kamal`
|
@@ -137,10 +143,10 @@ builder:
|
|
137
143
|
accessories:
|
138
144
|
...
|
139
145
|
|
140
|
-
#
|
146
|
+
# Proxy
|
141
147
|
#
|
142
|
-
#
|
143
|
-
|
148
|
+
# Configuration for kamal-proxy, see kamal docs proxy
|
149
|
+
proxy:
|
144
150
|
...
|
145
151
|
|
146
152
|
# SSHKit
|
@@ -155,14 +161,14 @@ sshkit:
|
|
155
161
|
boot:
|
156
162
|
...
|
157
163
|
|
158
|
-
# Healthcheck
|
159
|
-
#
|
160
|
-
# Configuring healthcheck commands, intervals and timeouts, see kamal docs healthcheck
|
161
|
-
healthcheck:
|
162
|
-
...
|
163
|
-
|
164
164
|
# Logging
|
165
165
|
#
|
166
166
|
# Docker logging configuration, see kamal docs logging
|
167
167
|
logging:
|
168
168
|
...
|
169
|
+
|
170
|
+
# Aliases
|
171
|
+
#
|
172
|
+
# Alias configuration, see kamal docs alias
|
173
|
+
aliases:
|
174
|
+
...
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# Environment variables
|
2
2
|
#
|
3
|
-
# Environment variables can be set
|
4
|
-
#
|
3
|
+
# Environment variables can be set directly in the Kamal configuration or
|
4
|
+
# read from .kamal/secrets.
|
5
5
|
|
6
6
|
# Reading environment variables from the configuration
|
7
7
|
#
|
@@ -12,26 +12,25 @@ env:
|
|
12
12
|
DATABASE_HOST: mysql-db1
|
13
13
|
DATABASE_PORT: 3306
|
14
14
|
|
15
|
-
# Using .
|
15
|
+
# Using .kamal/secrets file to load required environment variables
|
16
16
|
#
|
17
|
-
# Kamal uses dotenv to automatically load environment variables set in the .
|
18
|
-
# in the application root.
|
17
|
+
# Kamal uses dotenv to automatically load environment variables set in the .kamal/secrets file.
|
19
18
|
#
|
20
19
|
# This file can be used to set variables like KAMAL_REGISTRY_PASSWORD or database passwords.
|
21
|
-
#
|
22
|
-
#
|
20
|
+
# You can use variable or command substitution in the secrets file.
|
21
|
+
#
|
23
22
|
# ```
|
24
|
-
# KAMAL_REGISTRY_PASSWORD
|
25
|
-
#
|
23
|
+
# KAMAL_REGISTRY_PASSWORD=$KAMAL_REGISTRY_PASSWORD
|
24
|
+
# RAILS_MASTER_KEY=$(cat config/master.key)
|
26
25
|
# ```
|
27
|
-
#
|
26
|
+
#
|
27
|
+
# If you store secrets directly in .kamal/secrets, ensure that it is not checked into version control.
|
28
28
|
#
|
29
29
|
# To pass the secrets you should list them under the `secret` key. When you do this the
|
30
30
|
# other variables need to be moved under the `clear` key.
|
31
31
|
#
|
32
32
|
# Unlike clear values, secrets are not passed directly to the container,
|
33
33
|
# but are stored in an env file on the host
|
34
|
-
# The file is not updated when deploying, only when running `kamal envify` or `kamal env push`.
|
35
34
|
env:
|
36
35
|
clear:
|
37
36
|
DB_USER: app
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# Proxy
|
2
|
+
#
|
3
|
+
# Kamal uses [kamal-proxy](https://github.com/basecamp/kamal-proxy) to provide
|
4
|
+
# gapless deployments. It runs on ports 80 and 443 and forwards requests to the
|
5
|
+
# application container.
|
6
|
+
#
|
7
|
+
# The proxy is configured in the root configuration under `proxy`. These are
|
8
|
+
# options that are set when deploying the application, not when booting the proxy
|
9
|
+
#
|
10
|
+
# They are application specific, so are not shared when multiple applications
|
11
|
+
# run on the same proxy.
|
12
|
+
#
|
13
|
+
# The proxy is enabled by default on the primary role, but can be disabled by
|
14
|
+
# setting `proxy: false`.
|
15
|
+
#
|
16
|
+
# It is disabled by default on all other roles, but can be enabled by setting
|
17
|
+
# `proxy: true`, or providing a proxy configuration.
|
18
|
+
proxy:
|
19
|
+
|
20
|
+
# Host
|
21
|
+
#
|
22
|
+
# The hosts that will be used to serve the app. The proxy will only route requests
|
23
|
+
# to this host to your app.
|
24
|
+
#
|
25
|
+
# If no hosts are set, then all requests will be forwarded, except for matching
|
26
|
+
# requests for other apps deployed on that server that do have a host set.
|
27
|
+
host: foo.example.com
|
28
|
+
|
29
|
+
# App port
|
30
|
+
#
|
31
|
+
# The port the application container is exposed on
|
32
|
+
#
|
33
|
+
# Defaults to 80
|
34
|
+
app_port: 3000
|
35
|
+
|
36
|
+
# SSL
|
37
|
+
#
|
38
|
+
# kamal-proxy can provide automatic HTTPS for your application via Let's Encrypt.
|
39
|
+
#
|
40
|
+
# This requires that we are deploying to a one server and the host option is set.
|
41
|
+
# The host value must point to the server we are deploying to and port 443 must be
|
42
|
+
# open for the Let's Encrypt challenge to succeed.
|
43
|
+
#
|
44
|
+
# Defaults to false
|
45
|
+
ssl: true
|
46
|
+
|
47
|
+
# Response timeout
|
48
|
+
#
|
49
|
+
# How long to wait for requests to complete before timing out, defaults to 30 seconds
|
50
|
+
response_timeout: 10s
|
51
|
+
|
52
|
+
# Healthcheck
|
53
|
+
#
|
54
|
+
# When deploying, the proxy will by default hit /up once every second until we hit
|
55
|
+
# the deploy timeout, with a 5 second timeout for each request.
|
56
|
+
#
|
57
|
+
# Once the app is up, the proxy will stop hitting the healthcheck endpoint.
|
58
|
+
healthcheck:
|
59
|
+
interval: 3
|
60
|
+
path: /health
|
61
|
+
timeout: 3
|
62
|
+
|
63
|
+
# Buffering
|
64
|
+
#
|
65
|
+
# Whether to buffer request and response bodies in the proxy
|
66
|
+
#
|
67
|
+
# By default buffering is enabled with a max request body size of 1GB and no limit
|
68
|
+
# for response size.
|
69
|
+
#
|
70
|
+
# You can also set the memory limit for buffering, which defaults to 1MB, anything
|
71
|
+
# larger than that is written to disk.
|
72
|
+
buffering:
|
73
|
+
requests: true
|
74
|
+
responses: true
|
75
|
+
max_request_body: 40_000_000
|
76
|
+
max_response_body: 0
|
77
|
+
memory: 2_000_000
|
78
|
+
|
79
|
+
# Logging
|
80
|
+
#
|
81
|
+
# Configure request logging for the proxy
|
82
|
+
# You can specify request and response headers to log.
|
83
|
+
# By default, Cache-Control, Last-Modified and User-Agent request headers are logged
|
84
|
+
logging:
|
85
|
+
request_headers:
|
86
|
+
- Cache-Control
|
87
|
+
- X-Forwarded-Proto
|
88
|
+
response_headers:
|
89
|
+
- X-Request-ID
|
90
|
+
- X-Request-Start
|
91
|
+
|
92
|
+
# Forward headers
|
93
|
+
#
|
94
|
+
# Whether to forward the X-Forwarded-For and X-Forwarded-Proto headers (defaults to false)
|
95
|
+
#
|
96
|
+
# If you are behind a trusted proxy, you can set this to true to forward the headers.
|
97
|
+
#
|
98
|
+
# By default kamal-proxy will not forward the headers the ssl option is set to true, and
|
99
|
+
# will forward them if it is set to false.
|
100
|
+
forward_headers: true
|
@@ -27,11 +27,13 @@ registry:
|
|
27
27
|
# and [set up roles and permissions](https://cloud.google.com/artifact-registry/docs/access-control#permissions).
|
28
28
|
# Normally, assigning a roles/artifactregistry.writer role should be sufficient.
|
29
29
|
#
|
30
|
-
# Once the service account is ready, you need to generate and download a JSON key
|
30
|
+
# Once the service account is ready, you need to generate and download a JSON key and base64 encode it:
|
31
31
|
#
|
32
32
|
# ```shell
|
33
|
-
#
|
33
|
+
# base64 -i /path/to/key.json | tr -d "\\n")
|
34
34
|
# ```
|
35
|
+
# You'll then need to set the KAMAL_REGISTRY_PASSWORD secret to that value.
|
36
|
+
#
|
35
37
|
# Use the env variable as password along with _json_key_base64 as username.
|
36
38
|
# Here’s the final configuration:
|
37
39
|
|
@@ -26,7 +26,7 @@ servers:
|
|
26
26
|
#
|
27
27
|
# When there are other options to set, the list of hosts goes under the `hosts` key
|
28
28
|
#
|
29
|
-
# By default only the primary role uses
|
29
|
+
# By default only the primary role uses a proxy, but you can set `proxy` to change
|
30
30
|
# it.
|
31
31
|
#
|
32
32
|
# You can also set a custom cmd to run in the container, and overwrite other settings
|
@@ -35,18 +35,16 @@ servers:
|
|
35
35
|
hosts:
|
36
36
|
- 172.1.0.3
|
37
37
|
- 172.1.0.4: experiment1
|
38
|
-
traefik: true
|
39
38
|
cmd: "bin/jobs"
|
40
39
|
options:
|
41
40
|
memory: 2g
|
42
41
|
cpus: 4
|
43
|
-
healthcheck:
|
44
|
-
...
|
45
42
|
logging:
|
46
43
|
...
|
44
|
+
proxy:
|
45
|
+
...
|
47
46
|
labels:
|
48
47
|
my-label: workers
|
49
48
|
env:
|
50
49
|
...
|
51
50
|
asset_path: /public
|
52
|
-
|
@@ -1,12 +1,13 @@
|
|
1
1
|
class Kamal::Configuration::Env::Tag
|
2
|
-
attr_reader :name, :config
|
2
|
+
attr_reader :name, :config, :secrets
|
3
3
|
|
4
|
-
def initialize(name, config:)
|
4
|
+
def initialize(name, config:, secrets:)
|
5
5
|
@name = name
|
6
6
|
@config = config
|
7
|
+
@secrets = secrets
|
7
8
|
end
|
8
9
|
|
9
10
|
def env
|
10
|
-
Kamal::Configuration::Env.new(config: config)
|
11
|
+
Kamal::Configuration::Env.new(config: config, secrets: secrets)
|
11
12
|
end
|
12
13
|
end
|
@@ -1,36 +1,29 @@
|
|
1
1
|
class Kamal::Configuration::Env
|
2
2
|
include Kamal::Configuration::Validation
|
3
3
|
|
4
|
-
attr_reader :
|
4
|
+
attr_reader :context, :secrets
|
5
|
+
attr_reader :clear, :secret_keys
|
5
6
|
delegate :argumentize, to: Kamal::Utils
|
6
7
|
|
7
|
-
def initialize(config:,
|
8
|
+
def initialize(config:, secrets:, context: "env")
|
8
9
|
@clear = config.fetch("clear", config.key?("secret") || config.key?("tags") ? {} : config)
|
9
|
-
@
|
10
|
-
@
|
10
|
+
@secrets = secrets
|
11
|
+
@secret_keys = config.fetch("secret", [])
|
11
12
|
@context = context
|
12
13
|
validate! config, context: context, with: Kamal::Configuration::Validator::Env
|
13
14
|
end
|
14
15
|
|
15
|
-
def
|
16
|
-
|
16
|
+
def clear_args
|
17
|
+
argumentize("--env", clear)
|
17
18
|
end
|
18
19
|
|
19
20
|
def secrets_io
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
def secrets
|
24
|
-
@secrets ||= secrets_keys.to_h { |key| [ key, ENV.fetch(key) ] }
|
25
|
-
end
|
26
|
-
|
27
|
-
def secrets_directory
|
28
|
-
File.dirname(secrets_file)
|
21
|
+
Kamal::EnvFile.new(secret_keys.to_h { |key| [ key, secrets[key] ] }).to_io
|
29
22
|
end
|
30
23
|
|
31
24
|
def merge(other)
|
32
25
|
self.class.new \
|
33
|
-
config: { "clear" => clear.merge(other.clear), "secret" =>
|
34
|
-
|
26
|
+
config: { "clear" => clear.merge(other.clear), "secret" => secret_keys | other.secret_keys },
|
27
|
+
secrets: secrets
|
35
28
|
end
|
36
29
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
class Kamal::Configuration::Proxy
|
2
|
+
include Kamal::Configuration::Validation
|
3
|
+
|
4
|
+
DEFAULT_LOG_REQUEST_HEADERS = [ "Cache-Control", "Last-Modified", "User-Agent" ]
|
5
|
+
CONTAINER_NAME = "kamal-proxy"
|
6
|
+
|
7
|
+
delegate :argumentize, :optionize, to: Kamal::Utils
|
8
|
+
|
9
|
+
attr_reader :config, :proxy_config
|
10
|
+
|
11
|
+
def initialize(config:, proxy_config:, context: "proxy")
|
12
|
+
@config = config
|
13
|
+
@proxy_config = proxy_config
|
14
|
+
validate! @proxy_config, with: Kamal::Configuration::Validator::Proxy, context: context
|
15
|
+
end
|
16
|
+
|
17
|
+
def app_port
|
18
|
+
proxy_config.fetch("app_port", 80)
|
19
|
+
end
|
20
|
+
|
21
|
+
def ssl?
|
22
|
+
proxy_config.fetch("ssl", false)
|
23
|
+
end
|
24
|
+
|
25
|
+
def host
|
26
|
+
proxy_config["host"]
|
27
|
+
end
|
28
|
+
|
29
|
+
def deploy_options
|
30
|
+
{
|
31
|
+
host: proxy_config["host"],
|
32
|
+
tls: proxy_config["ssl"],
|
33
|
+
"deploy-timeout": seconds_duration(config.deploy_timeout),
|
34
|
+
"drain-timeout": seconds_duration(config.drain_timeout),
|
35
|
+
"health-check-interval": seconds_duration(proxy_config.dig("healthcheck", "interval")),
|
36
|
+
"health-check-timeout": seconds_duration(proxy_config.dig("healthcheck", "timeout")),
|
37
|
+
"health-check-path": proxy_config.dig("healthcheck", "path"),
|
38
|
+
"target-timeout": seconds_duration(proxy_config["response_timeout"]),
|
39
|
+
"buffer-requests": proxy_config.fetch("buffering", { "requests": true }).fetch("requests", true),
|
40
|
+
"buffer-responses": proxy_config.fetch("buffering", { "responses": true }).fetch("responses", true),
|
41
|
+
"buffer-memory": proxy_config.dig("buffering", "memory"),
|
42
|
+
"max-request-body": proxy_config.dig("buffering", "max_request_body"),
|
43
|
+
"max-response-body": proxy_config.dig("buffering", "max_response_body"),
|
44
|
+
"forward-headers": proxy_config.dig("forward_headers"),
|
45
|
+
"log-request-header": proxy_config.dig("logging", "request_headers") || DEFAULT_LOG_REQUEST_HEADERS,
|
46
|
+
"log-response-header": proxy_config.dig("logging", "response_headers")
|
47
|
+
}.compact
|
48
|
+
end
|
49
|
+
|
50
|
+
def deploy_command_args(target:)
|
51
|
+
optionize ({ target: "#{target}:#{app_port}" }).merge(deploy_options)
|
52
|
+
end
|
53
|
+
|
54
|
+
def remove_command_args(target:)
|
55
|
+
optionize({ target: "#{target}:#{app_port}" })
|
56
|
+
end
|
57
|
+
|
58
|
+
def merge(other)
|
59
|
+
self.class.new config: config, proxy_config: proxy_config.deep_merge(other.proxy_config)
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
def seconds_duration(value)
|
64
|
+
value ? "#{value}s" : nil
|
65
|
+
end
|
66
|
+
end
|
@@ -1,10 +1,11 @@
|
|
1
1
|
class Kamal::Configuration::Registry
|
2
2
|
include Kamal::Configuration::Validation
|
3
3
|
|
4
|
-
attr_reader :registry_config
|
4
|
+
attr_reader :registry_config, :secrets
|
5
5
|
|
6
6
|
def initialize(config:)
|
7
7
|
@registry_config = config.raw_config.registry || {}
|
8
|
+
@secrets = config.secrets
|
8
9
|
validate! registry_config, with: Kamal::Configuration::Validator::Registry
|
9
10
|
end
|
10
11
|
|
@@ -23,7 +24,7 @@ class Kamal::Configuration::Registry
|
|
23
24
|
private
|
24
25
|
def lookup(key)
|
25
26
|
if registry_config[key].is_a?(Array)
|
26
|
-
|
27
|
+
secrets[registry_config[key].first]
|
27
28
|
else
|
28
29
|
registry_config[key]
|
29
30
|
end
|