kamal 1.8.3 → 2.7.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 +1 -1
- data/lib/kamal/cli/accessory.rb +92 -38
- data/lib/kamal/cli/alias/command.rb +10 -0
- data/lib/kamal/cli/app/{prepare_assets.rb → assets.rb} +1 -1
- data/lib/kamal/cli/app/boot.rb +23 -16
- data/lib/kamal/cli/app/error_pages.rb +33 -0
- data/lib/kamal/cli/app/ssl_certificates.rb +28 -0
- data/lib/kamal/cli/app.rb +132 -30
- data/lib/kamal/cli/base.rb +57 -53
- data/lib/kamal/cli/build.rb +81 -38
- 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 +60 -59
- data/lib/kamal/cli/proxy.rb +290 -0
- data/lib/kamal/cli/prune.rb +0 -1
- data/lib/kamal/cli/registry.rb +2 -0
- data/lib/kamal/cli/secrets.rb +49 -0
- data/lib/kamal/cli/server.rb +6 -5
- data/lib/kamal/cli/templates/deploy.yml +53 -53
- data/lib/kamal/cli/templates/sample_hooks/docker-setup.sample +2 -12
- data/lib/kamal/cli/templates/sample_hooks/post-app-boot.sample +3 -0
- data/lib/kamal/cli/templates/sample_hooks/post-deploy.sample +1 -1
- data/lib/kamal/cli/templates/sample_hooks/post-proxy-reboot.sample +3 -0
- data/lib/kamal/cli/templates/sample_hooks/pre-app-boot.sample +3 -0
- data/lib/kamal/cli/templates/sample_hooks/pre-build.sample +1 -1
- data/lib/kamal/cli/templates/sample_hooks/pre-connect.sample +1 -1
- data/lib/kamal/cli/templates/sample_hooks/pre-deploy.sample +19 -6
- data/lib/kamal/cli/templates/sample_hooks/pre-proxy-reboot.sample +3 -0
- data/lib/kamal/cli/templates/secrets +17 -0
- data/lib/kamal/cli.rb +2 -0
- data/lib/kamal/commander/specifics.rb +19 -6
- data/lib/kamal/commander.rb +39 -32
- data/lib/kamal/commands/accessory/proxy.rb +16 -0
- data/lib/kamal/commands/accessory.rb +19 -19
- data/lib/kamal/commands/app/assets.rb +10 -10
- data/lib/kamal/commands/app/containers.rb +2 -2
- data/lib/kamal/commands/app/error_pages.rb +9 -0
- data/lib/kamal/commands/app/execution.rb +7 -4
- data/lib/kamal/commands/app/images.rb +1 -1
- data/lib/kamal/commands/app/logging.rb +16 -6
- data/lib/kamal/commands/app/proxy.rb +32 -0
- data/lib/kamal/commands/app.rb +25 -24
- data/lib/kamal/commands/auditor.rb +12 -3
- data/lib/kamal/commands/base.rb +54 -8
- data/lib/kamal/commands/builder/base.rb +46 -16
- data/lib/kamal/commands/builder/clone.rb +16 -14
- data/lib/kamal/commands/builder/cloud.rb +22 -0
- data/lib/kamal/commands/builder/hybrid.rb +21 -0
- data/lib/kamal/commands/builder/local.rb +14 -0
- data/lib/kamal/commands/builder/pack.rb +46 -0
- data/lib/kamal/commands/builder/remote.rb +63 -0
- data/lib/kamal/commands/builder.rb +21 -45
- data/lib/kamal/commands/docker.rb +4 -0
- data/lib/kamal/commands/hook.rb +8 -2
- data/lib/kamal/commands/lock.rb +2 -6
- data/lib/kamal/commands/proxy.rb +127 -0
- data/lib/kamal/commands/prune.rb +1 -9
- data/lib/kamal/commands/registry.rb +9 -7
- data/lib/kamal/commands/server.rb +11 -1
- data/lib/kamal/configuration/accessory.rb +89 -12
- data/lib/kamal/configuration/alias.rb +15 -0
- data/lib/kamal/configuration/builder.rb +73 -15
- data/lib/kamal/configuration/docs/accessory.yml +53 -15
- data/lib/kamal/configuration/docs/alias.yml +26 -0
- data/lib/kamal/configuration/docs/boot.yml +3 -3
- data/lib/kamal/configuration/docs/builder.yml +63 -38
- data/lib/kamal/configuration/docs/configuration.yml +62 -46
- data/lib/kamal/configuration/docs/env.yml +61 -17
- data/lib/kamal/configuration/docs/logging.yml +3 -3
- data/lib/kamal/configuration/docs/proxy.yml +168 -0
- data/lib/kamal/configuration/docs/registry.yml +20 -13
- data/lib/kamal/configuration/docs/role.yml +14 -13
- data/lib/kamal/configuration/docs/servers.yml +2 -2
- data/lib/kamal/configuration/docs/ssh.yml +23 -19
- data/lib/kamal/configuration/docs/sshkit.yml +4 -4
- data/lib/kamal/configuration/env/tag.rb +4 -3
- data/lib/kamal/configuration/env.rb +19 -17
- data/lib/kamal/configuration/proxy/boot.rb +129 -0
- data/lib/kamal/configuration/proxy.rb +124 -0
- data/lib/kamal/configuration/registry.rb +7 -6
- data/lib/kamal/configuration/role.rb +69 -98
- data/lib/kamal/configuration/servers.rb +8 -1
- data/lib/kamal/configuration/validator/accessory.rb +6 -2
- data/lib/kamal/configuration/validator/alias.rb +15 -0
- data/lib/kamal/configuration/validator/builder.rb +6 -0
- data/lib/kamal/configuration/validator/proxy.rb +25 -0
- data/lib/kamal/configuration/validator/role.rb +3 -1
- data/lib/kamal/configuration/validator/servers.rb +1 -1
- data/lib/kamal/configuration/validator.rb +62 -24
- data/lib/kamal/configuration.rb +96 -50
- data/lib/kamal/docker.rb +30 -0
- data/lib/kamal/env_file.rb +7 -1
- data/lib/kamal/git.rb +10 -0
- data/lib/kamal/secrets/adapters/aws_secrets_manager.rb +51 -0
- data/lib/kamal/secrets/adapters/base.rb +33 -0
- data/lib/kamal/secrets/adapters/bitwarden.rb +81 -0
- data/lib/kamal/secrets/adapters/bitwarden_secrets_manager.rb +66 -0
- data/lib/kamal/secrets/adapters/doppler.rb +57 -0
- data/lib/kamal/secrets/adapters/enpass.rb +71 -0
- data/lib/kamal/secrets/adapters/gcp_secret_manager.rb +112 -0
- data/lib/kamal/secrets/adapters/last_pass.rb +40 -0
- data/lib/kamal/secrets/adapters/one_password.rb +104 -0
- data/lib/kamal/secrets/adapters/passbolt.rb +130 -0
- data/lib/kamal/secrets/adapters/test.rb +14 -0
- data/lib/kamal/secrets/adapters.rb +16 -0
- data/lib/kamal/secrets/dotenv/inline_command_substitution.rb +33 -0
- data/lib/kamal/secrets.rb +42 -0
- data/lib/kamal/sshkit_with_ext.rb +1 -0
- data/lib/kamal/utils.rb +30 -0
- data/lib/kamal/version.rb +1 -1
- data/lib/kamal.rb +3 -1
- metadata +63 -36
- 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/sample_hooks/pre-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 -65
- 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
@@ -1,20 +0,0 @@
|
|
1
|
-
class Kamal::Commands::Builder::Native < Kamal::Commands::Builder::Base
|
2
|
-
def create
|
3
|
-
# No-op on native without cache
|
4
|
-
end
|
5
|
-
|
6
|
-
def remove
|
7
|
-
# No-op on native without cache
|
8
|
-
end
|
9
|
-
|
10
|
-
def info
|
11
|
-
# No-op on native
|
12
|
-
end
|
13
|
-
|
14
|
-
def push
|
15
|
-
combine \
|
16
|
-
docker(:build, *build_options, build_context),
|
17
|
-
docker(:push, config.absolute_image),
|
18
|
-
docker(:push, config.latest_image)
|
19
|
-
end
|
20
|
-
end
|
@@ -1,85 +0,0 @@
|
|
1
|
-
class Kamal::Commands::Traefik < Kamal::Commands::Base
|
2
|
-
delegate :argumentize, :optionize, to: Kamal::Utils
|
3
|
-
delegate :port, :publish?, :labels, :env, :image, :options, :args, to: :"config.traefik"
|
4
|
-
|
5
|
-
def run
|
6
|
-
docker :run, "--name traefik",
|
7
|
-
"--detach",
|
8
|
-
"--restart", "unless-stopped",
|
9
|
-
*publish_args,
|
10
|
-
"--volume", "/var/run/docker.sock:/var/run/docker.sock",
|
11
|
-
*env_args,
|
12
|
-
*config.logging_args,
|
13
|
-
*label_args,
|
14
|
-
*docker_options_args,
|
15
|
-
image,
|
16
|
-
"--providers.docker",
|
17
|
-
*cmd_option_args
|
18
|
-
end
|
19
|
-
|
20
|
-
def start
|
21
|
-
docker :container, :start, "traefik"
|
22
|
-
end
|
23
|
-
|
24
|
-
def stop
|
25
|
-
docker :container, :stop, "traefik"
|
26
|
-
end
|
27
|
-
|
28
|
-
def start_or_run
|
29
|
-
any start, run
|
30
|
-
end
|
31
|
-
|
32
|
-
def info
|
33
|
-
docker :ps, "--filter", "name=^traefik$"
|
34
|
-
end
|
35
|
-
|
36
|
-
def logs(since: nil, lines: nil, grep: nil, grep_options: nil)
|
37
|
-
pipe \
|
38
|
-
docker(:logs, "traefik", (" --since #{since}" if since), (" --tail #{lines}" if lines), "--timestamps", "2>&1"),
|
39
|
-
("grep '#{grep}'#{" #{grep_options}" if grep_options}" if grep)
|
40
|
-
end
|
41
|
-
|
42
|
-
def follow_logs(host:, grep: nil, grep_options: nil)
|
43
|
-
run_over_ssh pipe(
|
44
|
-
docker(:logs, "traefik", "--timestamps", "--tail", "10", "--follow", "2>&1"),
|
45
|
-
(%(grep "#{grep}"#{" #{grep_options}" if grep_options}) if grep)
|
46
|
-
).join(" "), host: host
|
47
|
-
end
|
48
|
-
|
49
|
-
def remove_container
|
50
|
-
docker :container, :prune, "--force", "--filter", "label=org.opencontainers.image.title=Traefik"
|
51
|
-
end
|
52
|
-
|
53
|
-
def remove_image
|
54
|
-
docker :image, :prune, "--all", "--force", "--filter", "label=org.opencontainers.image.title=Traefik"
|
55
|
-
end
|
56
|
-
|
57
|
-
def make_env_directory
|
58
|
-
make_directory(env.secrets_directory)
|
59
|
-
end
|
60
|
-
|
61
|
-
def remove_env_file
|
62
|
-
[ :rm, "-f", env.secrets_file ]
|
63
|
-
end
|
64
|
-
|
65
|
-
private
|
66
|
-
def publish_args
|
67
|
-
argumentize "--publish", port if publish?
|
68
|
-
end
|
69
|
-
|
70
|
-
def label_args
|
71
|
-
argumentize "--label", labels
|
72
|
-
end
|
73
|
-
|
74
|
-
def env_args
|
75
|
-
env.args
|
76
|
-
end
|
77
|
-
|
78
|
-
def docker_options_args
|
79
|
-
optionize(options)
|
80
|
-
end
|
81
|
-
|
82
|
-
def cmd_option_args
|
83
|
-
optionize args, with: "="
|
84
|
-
end
|
85
|
-
end
|
@@ -1,59 +0,0 @@
|
|
1
|
-
# Healthcheck configuration
|
2
|
-
#
|
3
|
-
# On roles that are running Traefik, Kamal will supply a default healthcheck to `docker run`.
|
4
|
-
# For other roles, by default no healthcheck is supplied.
|
5
|
-
#
|
6
|
-
# If no healthcheck is supplied and the image does not define one, they we wait for the container
|
7
|
-
# to reach a running state and then pause for the readiness delay.
|
8
|
-
#
|
9
|
-
# The default healthcheck is `curl -f http://localhost:<port>/<path>`, so it assumes that `curl`
|
10
|
-
# is available within the container.
|
11
|
-
|
12
|
-
# Healthcheck options
|
13
|
-
#
|
14
|
-
# These go under the `healthcheck` key in the root or role configuration.
|
15
|
-
healthcheck:
|
16
|
-
|
17
|
-
# Command
|
18
|
-
#
|
19
|
-
# The command to run, defaults to `curl -f http://localhost:<port>/<path>` on roles running Traefik
|
20
|
-
cmd: "curl -f http://localhost"
|
21
|
-
|
22
|
-
# Interval
|
23
|
-
#
|
24
|
-
# The Docker healthcheck interval, defaults to `1s`
|
25
|
-
interval: 10s
|
26
|
-
|
27
|
-
# Max attempts
|
28
|
-
#
|
29
|
-
# The maximum number of times we poll the container to see if it is healthy, defaults to `7`
|
30
|
-
# Each check is separated by an increasing interval starting with 1 second.
|
31
|
-
max_attempts: 3
|
32
|
-
|
33
|
-
# Port
|
34
|
-
#
|
35
|
-
# The port to use in the healthcheck, defaults to `3000`
|
36
|
-
port: "80"
|
37
|
-
|
38
|
-
# Path
|
39
|
-
#
|
40
|
-
# The path to use in the healthcheck, defaults to `/up`
|
41
|
-
path: /health
|
42
|
-
|
43
|
-
# Cords for zero-downtime deployments
|
44
|
-
#
|
45
|
-
# The cord file is used for zero-downtime deployments. The healthcheck is augmented with a check
|
46
|
-
# for the existance of the file. This allows us to delete the file and force the container to
|
47
|
-
# become unhealthy, causing Traefik to stop routing traffic to it.
|
48
|
-
#
|
49
|
-
# Kamal mounts a volume at this location and creates the file before starting the container.
|
50
|
-
# You can set the value to `false` to disable the cord file, but this loses the zero-downtime
|
51
|
-
# guarantee.
|
52
|
-
#
|
53
|
-
# The default value is `/tmp/kamal-cord`
|
54
|
-
cord: /cord
|
55
|
-
|
56
|
-
# Log lines
|
57
|
-
#
|
58
|
-
# Number of lines to log from the container when the healthcheck fails, defaults to `50`
|
59
|
-
log_lines: 100
|
@@ -1,62 +0,0 @@
|
|
1
|
-
# Traefik
|
2
|
-
#
|
3
|
-
# Traefik is a reverse proxy, used by Kamal for zero-downtime deployments.
|
4
|
-
#
|
5
|
-
# We start an instance on the hosts in it's own container.
|
6
|
-
#
|
7
|
-
# During a deployment:
|
8
|
-
# 1. We start a new container which Traefik automatically detects due to the labels we have applied
|
9
|
-
# 2. Traefik starts routing traffic to the new container
|
10
|
-
# 3. We force the old container to fail it's healthcheck, causing Traefik to stop routing traffic to it
|
11
|
-
# 4. We stop the old container
|
12
|
-
|
13
|
-
# Traefik settings
|
14
|
-
#
|
15
|
-
# Traekik is configured in the root configuration under `traefik`.
|
16
|
-
traefik:
|
17
|
-
|
18
|
-
# Image
|
19
|
-
#
|
20
|
-
# The Traefik image to use, defaults to `traefik:v2.10`
|
21
|
-
image: traefik:v2.9
|
22
|
-
|
23
|
-
# Host port
|
24
|
-
#
|
25
|
-
# The host port to publish the Traefik container on, defaults to `80`
|
26
|
-
host_port: "8080"
|
27
|
-
|
28
|
-
# Disabling publishing
|
29
|
-
#
|
30
|
-
# To avoid publishing the Traefik container, set this to `false`
|
31
|
-
publish: false
|
32
|
-
|
33
|
-
# Labels
|
34
|
-
#
|
35
|
-
# Additional labels to apply to the Traefik container
|
36
|
-
labels:
|
37
|
-
traefik.http.routers.catchall.entryPoints: http
|
38
|
-
traefik.http.routers.catchall.rule: PathPrefix(`/`)
|
39
|
-
traefik.http.routers.catchall.service: unavailable
|
40
|
-
traefik.http.routers.catchall.priority: "1"
|
41
|
-
traefik.http.services.unavailable.loadbalancer.server.port: "0"
|
42
|
-
|
43
|
-
# Arguments
|
44
|
-
#
|
45
|
-
# Additional arguments to pass to the Traefik container
|
46
|
-
args:
|
47
|
-
entryPoints.http.address: ":80"
|
48
|
-
entryPoints.http.forwardedHeaders.insecure: true
|
49
|
-
accesslog: true
|
50
|
-
accesslog.format: json
|
51
|
-
|
52
|
-
# Options
|
53
|
-
#
|
54
|
-
# Additional options to pass to `docker run`
|
55
|
-
options:
|
56
|
-
cpus: 2
|
57
|
-
|
58
|
-
# Environment variables
|
59
|
-
#
|
60
|
-
# See kamal docs env
|
61
|
-
env:
|
62
|
-
...
|
@@ -1,63 +0,0 @@
|
|
1
|
-
class Kamal::Configuration::Healthcheck
|
2
|
-
include Kamal::Configuration::Validation
|
3
|
-
|
4
|
-
attr_reader :healthcheck_config
|
5
|
-
|
6
|
-
def initialize(healthcheck_config:, context: "healthcheck")
|
7
|
-
@healthcheck_config = healthcheck_config || {}
|
8
|
-
validate! @healthcheck_config, context: context
|
9
|
-
end
|
10
|
-
|
11
|
-
def merge(other)
|
12
|
-
self.class.new healthcheck_config: healthcheck_config.deep_merge(other.healthcheck_config)
|
13
|
-
end
|
14
|
-
|
15
|
-
def cmd
|
16
|
-
healthcheck_config.fetch("cmd", http_health_check)
|
17
|
-
end
|
18
|
-
|
19
|
-
def port
|
20
|
-
healthcheck_config.fetch("port", 3000)
|
21
|
-
end
|
22
|
-
|
23
|
-
def path
|
24
|
-
healthcheck_config.fetch("path", "/up")
|
25
|
-
end
|
26
|
-
|
27
|
-
def max_attempts
|
28
|
-
healthcheck_config.fetch("max_attempts", 7)
|
29
|
-
end
|
30
|
-
|
31
|
-
def interval
|
32
|
-
healthcheck_config.fetch("interval", "1s")
|
33
|
-
end
|
34
|
-
|
35
|
-
def cord
|
36
|
-
healthcheck_config.fetch("cord", "/tmp/kamal-cord")
|
37
|
-
end
|
38
|
-
|
39
|
-
def log_lines
|
40
|
-
healthcheck_config.fetch("log_lines", 50)
|
41
|
-
end
|
42
|
-
|
43
|
-
def set_port_or_path?
|
44
|
-
healthcheck_config["port"].present? || healthcheck_config["path"].present?
|
45
|
-
end
|
46
|
-
|
47
|
-
def to_h
|
48
|
-
{
|
49
|
-
"cmd" => cmd,
|
50
|
-
"interval" => interval,
|
51
|
-
"max_attempts" => max_attempts,
|
52
|
-
"port" => port,
|
53
|
-
"path" => path,
|
54
|
-
"cord" => cord,
|
55
|
-
"log_lines" => log_lines
|
56
|
-
}
|
57
|
-
end
|
58
|
-
|
59
|
-
private
|
60
|
-
def http_health_check
|
61
|
-
"curl -f #{URI.join("http://localhost:#{port}", path)} || exit 1" if path.present? || port.present?
|
62
|
-
end
|
63
|
-
end
|
@@ -1,60 +0,0 @@
|
|
1
|
-
class Kamal::Configuration::Traefik
|
2
|
-
DEFAULT_IMAGE = "traefik:v2.10"
|
3
|
-
CONTAINER_PORT = 80
|
4
|
-
DEFAULT_ARGS = {
|
5
|
-
"log.level" => "DEBUG"
|
6
|
-
}
|
7
|
-
DEFAULT_LABELS = {
|
8
|
-
# These ensure we serve a 502 rather than a 404 if no containers are available
|
9
|
-
"traefik.http.routers.catchall.entryPoints" => "http",
|
10
|
-
"traefik.http.routers.catchall.rule" => "PathPrefix(`/`)",
|
11
|
-
"traefik.http.routers.catchall.service" => "unavailable",
|
12
|
-
"traefik.http.routers.catchall.priority" => 1,
|
13
|
-
"traefik.http.services.unavailable.loadbalancer.server.port" => "0"
|
14
|
-
}
|
15
|
-
|
16
|
-
include Kamal::Configuration::Validation
|
17
|
-
|
18
|
-
attr_reader :config, :traefik_config
|
19
|
-
|
20
|
-
def initialize(config:)
|
21
|
-
@config = config
|
22
|
-
@traefik_config = config.raw_config.traefik || {}
|
23
|
-
validate! traefik_config
|
24
|
-
end
|
25
|
-
|
26
|
-
def publish?
|
27
|
-
traefik_config["publish"] != false
|
28
|
-
end
|
29
|
-
|
30
|
-
def labels
|
31
|
-
DEFAULT_LABELS.merge(traefik_config["labels"] || {})
|
32
|
-
end
|
33
|
-
|
34
|
-
def env
|
35
|
-
Kamal::Configuration::Env.new \
|
36
|
-
config: traefik_config.fetch("env", {}),
|
37
|
-
secrets_file: File.join(config.host_env_directory, "traefik", "traefik.env"),
|
38
|
-
context: "traefik/env"
|
39
|
-
end
|
40
|
-
|
41
|
-
def host_port
|
42
|
-
traefik_config.fetch("host_port", CONTAINER_PORT)
|
43
|
-
end
|
44
|
-
|
45
|
-
def options
|
46
|
-
traefik_config.fetch("options", {})
|
47
|
-
end
|
48
|
-
|
49
|
-
def port
|
50
|
-
"#{host_port}:#{CONTAINER_PORT}"
|
51
|
-
end
|
52
|
-
|
53
|
-
def args
|
54
|
-
DEFAULT_ARGS.merge(traefik_config.fetch("args", {}))
|
55
|
-
end
|
56
|
-
|
57
|
-
def image
|
58
|
-
traefik_config.fetch("image", DEFAULT_IMAGE)
|
59
|
-
end
|
60
|
-
end
|