kamal 1.8.2 → 2.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|