Simplify the builders configuration
1. Add driver as an option, defaulting to `docker-container`. For a
"native" build you can set it to `docker`
2. Set arch as a array of architectures to build for, defaulting to
`[ "amd64", "arm64" ]` unless you are using the docker driver in
which case we default to not setting a platform
3. Remote is now just a connection string for the remote builder
4. If remote is set, we only use it for non-local arches, if we are
only building for the local arch, we'll ignore it.
Examples:
On arm64, build for arm64 locally, amd64 remotely or
On amd64, build for amd64 locally, arm64 remotely:
```yaml
builder:
remote: ssh://docker@docker-builder
```
On arm64, build amd64 on remote,
On amd64 build locally:
```yaml
builder:
arch:
- amd64
remote:
host: ssh://docker@docker-builder
```
Build amd64 on local:
```yaml
builder:
arch:
- amd64
```
Use docker driver, building for local arch:
```yaml
builder:
driver: docker
```
This commit is contained in:
committed by
Donal McBreen
parent
cffb6c3d7e
commit
56268d724d
@@ -66,7 +66,7 @@ class Kamal::Cli::Build < Kamal::Cli::Base
|
|||||||
|
|
||||||
desc "create", "Create a build setup"
|
desc "create", "Create a build setup"
|
||||||
def create
|
def create
|
||||||
if (remote_host = KAMAL.config.builder.remote_host)
|
if (remote_host = KAMAL.config.builder.remote)
|
||||||
connect_to_remote_host(remote_host)
|
connect_to_remote_host(remote_host)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ require "active_support/core_ext/string/filters"
|
|||||||
|
|
||||||
class Kamal::Commands::Builder < Kamal::Commands::Base
|
class Kamal::Commands::Builder < Kamal::Commands::Base
|
||||||
delegate :create, :remove, :push, :clean, :pull, :info, :buildx_inspect, :validate_image, :first_mirror, to: :target
|
delegate :create, :remove, :push, :clean, :pull, :info, :buildx_inspect, :validate_image, :first_mirror, to: :target
|
||||||
delegate :multiarch?, :local?, :remote?, to: "config.builder"
|
delegate :local?, :remote?, to: "config.builder"
|
||||||
|
|
||||||
include Clone
|
include Clone
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
|
|||||||
|
|
||||||
delegate :argumentize, to: Kamal::Utils
|
delegate :argumentize, to: Kamal::Utils
|
||||||
delegate \
|
delegate \
|
||||||
:args, :secrets, :dockerfile, :target, :local_arch, :remote_arch, :remote_host,
|
:args, :secrets, :dockerfile, :target, :arches, :local_arches, :remote_arches, :remote,
|
||||||
:cache_from, :cache_to, :multiarch?, :ssh, :driver, :docker_driver?,
|
:cache_from, :cache_to, :ssh, :driver, :docker_driver?,
|
||||||
to: :builder_config
|
to: :builder_config
|
||||||
|
|
||||||
def clean
|
def clean
|
||||||
@@ -16,7 +16,7 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
|
|||||||
def push
|
def push
|
||||||
docker :build,
|
docker :build,
|
||||||
"--push",
|
"--push",
|
||||||
*platform_options,
|
*platform_options(arches),
|
||||||
*([ "--builder", builder_name ] unless docker_driver?),
|
*([ "--builder", builder_name ] unless docker_driver?),
|
||||||
*build_options,
|
*build_options,
|
||||||
build_context
|
build_context
|
||||||
@@ -33,7 +33,7 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
def buildx_inspect
|
def buildx_inspect
|
||||||
docker :buildx, :inspect, builder_name
|
docker :buildx, :inspect, builder_name unless docker_driver?
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_options
|
def build_options
|
||||||
@@ -104,4 +104,8 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
|
|||||||
def context_host(builder_name)
|
def context_host(builder_name)
|
||||||
docker :context, :inspect, builder_name, "--format", ENDPOINT_DOCKER_HOST_INSPECT
|
docker :context, :inspect, builder_name, "--format", ENDPOINT_DOCKER_HOST_INSPECT
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def platform_options(arches)
|
||||||
|
argumentize "--platform", arches.map { |arch| "linux/#{arch}" }.join(",") if arches.any?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -8,18 +8,14 @@ class Kamal::Commands::Builder::Hybrid < Kamal::Commands::Builder::Remote
|
|||||||
|
|
||||||
private
|
private
|
||||||
def builder_name
|
def builder_name
|
||||||
"kamal-hybrid-#{driver}-#{local_arch}-#{remote_arch}-#{remote_host.gsub(/[^a-z0-9_-]/, "-")}"
|
"kamal-hybrid-#{driver}-#{remote.gsub(/[^a-z0-9_-]/, "-")}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_local_buildx
|
def create_local_buildx
|
||||||
docker :buildx, :create, "--name", builder_name, "--platform", "linux/#{local_arch}", "--driver=#{driver}"
|
docker :buildx, :create, *platform_options(local_arches), "--name", builder_name, "--driver=#{driver}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def append_remote_buildx
|
def append_remote_buildx
|
||||||
docker :buildx, :create, "--append", "--name", builder_name, builder_name, "--platform", "linux/#{remote_arch}"
|
docker :buildx, :create, *platform_options(remote_arches), "--append", "--name", builder_name, builder_name
|
||||||
end
|
|
||||||
|
|
||||||
def platform
|
|
||||||
"linux/#{local_arch},linux/#{remote_arch}"
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -11,14 +11,4 @@ class Kamal::Commands::Builder::Local < Kamal::Commands::Builder::Base
|
|||||||
def builder_name
|
def builder_name
|
||||||
"kamal-local-#{driver}"
|
"kamal-local-#{driver}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def platform_options
|
|
||||||
if multiarch?
|
|
||||||
if local_arch
|
|
||||||
[ "--platform", "linux/#{local_arch}" ]
|
|
||||||
else
|
|
||||||
[ "--platform", "linux/amd64,linux/arm64" ]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -17,22 +17,13 @@ class Kamal::Commands::Builder::Remote < Kamal::Commands::Builder::Base
|
|||||||
docker(:buildx, :ls)
|
docker(:buildx, :ls)
|
||||||
end
|
end
|
||||||
|
|
||||||
def push
|
|
||||||
docker :build,
|
|
||||||
"--push",
|
|
||||||
*platform_options,
|
|
||||||
"--builder", builder_name,
|
|
||||||
*build_options,
|
|
||||||
build_context
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
def builder_name
|
def builder_name
|
||||||
"kamal-remote-#{driver}-#{remote_arch}-#{remote_host.gsub(/[^a-z0-9_-]/, "-")}"
|
"kamal-remote-#{driver}-#{remote.gsub(/[^a-z0-9_-]/, "-")}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_remote_context
|
def create_remote_context
|
||||||
docker :context, :create, builder_name, "--description", "'#{builder_name} host'", "--docker", "'host=#{remote_host}'"
|
docker :context, :create, builder_name, "--description", "'#{builder_name} host'", "--docker", "'host=#{remote}'"
|
||||||
end
|
end
|
||||||
|
|
||||||
def remove_remote_context
|
def remove_remote_context
|
||||||
@@ -40,18 +31,10 @@ class Kamal::Commands::Builder::Remote < Kamal::Commands::Builder::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
def create_buildx
|
def create_buildx
|
||||||
docker :buildx, :create, "--name", builder_name, builder_name, "--platform", platform
|
docker :buildx, :create, "--name", builder_name, builder_name
|
||||||
end
|
end
|
||||||
|
|
||||||
def remove_buildx
|
def remove_buildx
|
||||||
docker :buildx, :rm, builder_name
|
docker :buildx, :rm, builder_name
|
||||||
end
|
end
|
||||||
|
|
||||||
def platform_options
|
|
||||||
[ "--platform", platform ]
|
|
||||||
end
|
|
||||||
|
|
||||||
def platform
|
|
||||||
"linux/#{remote_arch}"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -19,16 +19,38 @@ class Kamal::Configuration::Builder
|
|||||||
builder_config
|
builder_config
|
||||||
end
|
end
|
||||||
|
|
||||||
def multiarch?
|
def remote
|
||||||
builder_config["multiarch"] != false
|
builder_config["remote"]
|
||||||
end
|
end
|
||||||
|
|
||||||
def local?
|
def arches
|
||||||
!!builder_config["local"]
|
Array(builder_config.fetch("arch", default_arch))
|
||||||
|
end
|
||||||
|
|
||||||
|
def local_arches
|
||||||
|
@local_arches ||= if remote
|
||||||
|
uname_m = `uname -m`.strip
|
||||||
|
local_arch = uname_m == "x86_64" ? "amd64" : uname_m
|
||||||
|
arches & [ local_arch ]
|
||||||
|
else
|
||||||
|
arches
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def remote_arches
|
||||||
|
@remote_arches ||= if remote
|
||||||
|
arches - local_arches
|
||||||
|
else
|
||||||
|
[]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def remote?
|
def remote?
|
||||||
!!builder_config["remote"]
|
remote_arches.any?
|
||||||
|
end
|
||||||
|
|
||||||
|
def local?
|
||||||
|
arches.empty? || local_arches.any?
|
||||||
end
|
end
|
||||||
|
|
||||||
def cached?
|
def cached?
|
||||||
@@ -59,18 +81,6 @@ class Kamal::Configuration::Builder
|
|||||||
builder_config.fetch("driver", "docker-container")
|
builder_config.fetch("driver", "docker-container")
|
||||||
end
|
end
|
||||||
|
|
||||||
def local_arch
|
|
||||||
builder_config["local"]["arch"] if local?
|
|
||||||
end
|
|
||||||
|
|
||||||
def remote_arch
|
|
||||||
builder_config["remote"]["arch"] if remote?
|
|
||||||
end
|
|
||||||
|
|
||||||
def remote_host
|
|
||||||
builder_config["remote"]["host"] if remote?
|
|
||||||
end
|
|
||||||
|
|
||||||
def cache_from
|
def cache_from
|
||||||
if cached?
|
if cached?
|
||||||
case builder_config["cache"]["type"]
|
case builder_config["cache"]["type"]
|
||||||
@@ -120,27 +130,14 @@ class Kamal::Configuration::Builder
|
|||||||
|
|
||||||
private
|
private
|
||||||
def valid?
|
def valid?
|
||||||
if multiarch?
|
if docker_driver?
|
||||||
if local?
|
raise ArgumentError, "Invalid builder configuration: the `docker` driver does not not support remote builders" if remote
|
||||||
raise ArgumentError, "Invalid builder configuration: local configuration, arch required" unless local_arch
|
raise ArgumentError, "Invalid builder configuration: the `docker` driver does not not support caching" if cached?
|
||||||
end
|
raise ArgumentError, "Invalid builder configuration: the `docker` driver does not not support multiple arches" if arches.many?
|
||||||
|
|
||||||
if remote?
|
|
||||||
raise ArgumentError, "Invalid builder configuration: remote configuration, arch required" unless remote_arch
|
|
||||||
raise ArgumentError, "Invalid builder configuration: remote configuration, arch required" unless remote_host
|
|
||||||
end
|
|
||||||
|
|
||||||
if docker_driver?
|
|
||||||
raise ArgumentError, "Invalid builder configuration: the docker driver does not support multiarch builds"
|
|
||||||
end
|
|
||||||
else
|
|
||||||
raise ArgumentError, "Invalid builder configuration: multiarch must be enabled for local configuration" if local?
|
|
||||||
raise ArgumentError, "Invalid builder configuration: multiarch must be enabled for remote configuration" if remote?
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if @options["cache"] && @options["cache"]["type"]
|
if @options["cache"] && @options["cache"]["type"]
|
||||||
raise ArgumentError, "Invalid cache type: #{@options["cache"]["type"]}" unless [ "gha", "registry" ].include?(@options["cache"]["type"])
|
raise ArgumentError, "Invalid cache type: #{@options["cache"]["type"]}" unless [ "gha", "registry" ].include?(@options["cache"]["type"])
|
||||||
raise ArgumentError, "The docker driver does not support caching" if docker_driver?
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -179,4 +176,8 @@ class Kamal::Configuration::Builder
|
|||||||
def pwd_sha
|
def pwd_sha
|
||||||
Digest::SHA256.hexdigest(Dir.pwd)[0..12]
|
Digest::SHA256.hexdigest(Dir.pwd)[0..12]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def default_arch
|
||||||
|
docker_driver? ? [] : [ "amd64", "arm64" ]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
# The builder configuration controls how the application is built with `docker build`
|
# The builder configuration controls how the application is built with `docker build`
|
||||||
#
|
#
|
||||||
# If no configuration is specified, Kamal will:
|
# If no configuration is specified, Kamal will:
|
||||||
# 1. Create a buildx context called `kamal-<service>-multiarch`
|
# 1. Create a buildx context called `kamal-local-docker-container`, using the docker-container driver
|
||||||
# 2. Use `docker build` to build a multiarch image for linux/amd64,linux/arm64 with that context
|
# 2. Use `docker build` to build a multiarch image for linux/amd64,linux/arm64 with that context
|
||||||
#
|
#
|
||||||
# See https://kamal-deploy.org/docs/configuration/builder-examples/ for more information
|
# See https://kamal-deploy.org/docs/configuration/builder-examples/ for more information
|
||||||
@@ -12,41 +12,29 @@
|
|||||||
#
|
#
|
||||||
# Options go under the builder key in the root configuration.
|
# Options go under the builder key in the root configuration.
|
||||||
builder:
|
builder:
|
||||||
|
|
||||||
# Multiarch
|
|
||||||
#
|
|
||||||
# Enables multiarch builds, defaults to `true`
|
|
||||||
multiarch: false
|
|
||||||
|
|
||||||
# Driver
|
# Driver
|
||||||
#
|
#
|
||||||
# The build driver to use, defaults to `docker-container`
|
# The build driver to use, defaults to `docker-container`
|
||||||
driver: docker
|
driver: docker
|
||||||
|
|
||||||
# Local configuration
|
# Arch
|
||||||
#
|
#
|
||||||
# The build configuration for local builds, only used if multiarch is enabled (the default)
|
# The architectures to build for, defaults to `[ amd64, arm64 ]`
|
||||||
#
|
# Unless you are using the docker driver, when it defaults to the local architecture
|
||||||
# If there is no remote configuration, by default we build for amd64 and arm64.
|
# You can set an array or just a single value
|
||||||
# If you only want to build for one architecture, you can specify it here.
|
arch:
|
||||||
# The docker socket is optional and uses the default docker host socket when not specified
|
- amd64
|
||||||
local:
|
|
||||||
arch: amd64
|
|
||||||
host: /var/run/docker.sock
|
|
||||||
|
|
||||||
# Remote configuration
|
# Remote configuration
|
||||||
#
|
#
|
||||||
# The build configuration for remote builds, also only used if multiarch is enabled.
|
# If you have a remote builder, you can configure it here
|
||||||
# The arch is required and can be either amd64 or arm64.
|
remote: ssh://docker@docker-builder
|
||||||
remote:
|
|
||||||
arch: arm64
|
|
||||||
host: ssh://docker@docker-builder
|
|
||||||
|
|
||||||
# Builder cache
|
# Builder cache
|
||||||
#
|
#
|
||||||
# The type must be either 'gha' or 'registry'
|
# The type must be either 'gha' or 'registry'
|
||||||
#
|
#
|
||||||
# The image is only used for registry cache
|
# The image is only used for registry cache. Not compatible with the docker driver
|
||||||
cache:
|
cache:
|
||||||
type: registry
|
type: registry
|
||||||
options: mode=max
|
options: mode=max
|
||||||
|
|||||||
@@ -28,7 +28,11 @@ class Kamal::Configuration::Validator
|
|||||||
elsif key == "hosts"
|
elsif key == "hosts"
|
||||||
validate_servers! value
|
validate_servers! value
|
||||||
elsif example_value.is_a?(Array)
|
elsif example_value.is_a?(Array)
|
||||||
validate_array_of! value, example_value.first.class
|
if key == "arch"
|
||||||
|
validate_array_of_or_type! value, example_value.first.class
|
||||||
|
else
|
||||||
|
validate_array_of! value, example_value.first.class
|
||||||
|
end
|
||||||
elsif example_value.is_a?(Hash)
|
elsif example_value.is_a?(Hash)
|
||||||
case key.to_s
|
case key.to_s
|
||||||
when "options", "args"
|
when "options", "args"
|
||||||
@@ -71,6 +75,16 @@ class Kamal::Configuration::Validator
|
|||||||
value.is_a?(String) || value.is_a?(Symbol) || value.is_a?(Numeric) || value.is_a?(TrueClass) || value.is_a?(FalseClass)
|
value.is_a?(String) || value.is_a?(Symbol) || value.is_a?(Numeric) || value.is_a?(TrueClass) || value.is_a?(FalseClass)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def validate_array_of_or_type!(value, type)
|
||||||
|
if value.is_a?(Array)
|
||||||
|
validate_array_of! value, type
|
||||||
|
else
|
||||||
|
validate_type! value, type
|
||||||
|
end
|
||||||
|
rescue Kamal::ConfigurationError
|
||||||
|
type_error(Array, type)
|
||||||
|
end
|
||||||
|
|
||||||
def validate_array_of!(array, type)
|
def validate_array_of!(array, type)
|
||||||
validate_type! array, Array
|
validate_type! array, Array
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class CliBuildTest < CliTestCase
|
|||||||
assert_match /Cloning repo into build directory/, output
|
assert_match /Cloning repo into build directory/, output
|
||||||
assert_match /git -C #{Dir.tmpdir}\/kamal-clones\/app-#{pwd_sha} clone #{Dir.pwd}/, output
|
assert_match /git -C #{Dir.tmpdir}\/kamal-clones\/app-#{pwd_sha} clone #{Dir.pwd}/, output
|
||||||
assert_match /docker --version && docker buildx version/, output
|
assert_match /docker --version && docker buildx version/, output
|
||||||
assert_match /docker build --push --platform linux\/amd64,linux\/arm64 --builder kamal-local -t dhh\/app:999 -t dhh\/app:latest --label service="app" --file Dockerfile \. as .*@localhost/, output
|
assert_match /docker build --push --platform linux\/amd64,linux\/arm64 --builder kamal-local-docker-container -t dhh\/app:999 -t dhh\/app:latest --label service="app" --file Dockerfile \. as .*@localhost/, output
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -49,7 +49,7 @@ class CliBuildTest < CliTestCase
|
|||||||
SSHKit::Backend::Abstract.any_instance.expects(:execute).with(:git, "-C", build_directory, :submodule, :update, "--init")
|
SSHKit::Backend::Abstract.any_instance.expects(:execute).with(:git, "-C", build_directory, :submodule, :update, "--init")
|
||||||
|
|
||||||
SSHKit::Backend::Abstract.any_instance.expects(:execute)
|
SSHKit::Backend::Abstract.any_instance.expects(:execute)
|
||||||
.with(:docker, :build, "--push", "--platform", "linux/amd64,linux/arm64", "--builder", "kamal-local", "-t", "dhh/app:999", "-t", "dhh/app:latest", "--label", "service=\"app\"", "--file", "Dockerfile", ".")
|
.with(:docker, :build, "--push", "--platform", "linux/amd64,linux/arm64", "--builder", "kamal-local-docker-container", "-t", "dhh/app:999", "-t", "dhh/app:latest", "--label", "service=\"app\"", "--file", "Dockerfile", ".")
|
||||||
|
|
||||||
SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info)
|
SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info)
|
||||||
.with(:git, "-C", anything, :"rev-parse", :HEAD)
|
.with(:git, "-C", anything, :"rev-parse", :HEAD)
|
||||||
@@ -74,7 +74,7 @@ class CliBuildTest < CliTestCase
|
|||||||
assert_no_match /Cloning repo into build directory/, output
|
assert_no_match /Cloning repo into build directory/, output
|
||||||
assert_hook_ran "pre-build", output, **hook_variables
|
assert_hook_ran "pre-build", output, **hook_variables
|
||||||
assert_match /docker --version && docker buildx version/, output
|
assert_match /docker --version && docker buildx version/, output
|
||||||
assert_match /docker build --push --platform linux\/amd64,linux\/arm64 --builder kamal-local -t dhh\/app:999 -t dhh\/app:latest --label service="app" --file Dockerfile . as .*@localhost/, output
|
assert_match /docker build --push --platform linux\/amd64,linux\/arm64 --builder kamal-local-docker-container -t dhh\/app:999 -t dhh\/app:latest --label service="app" --file Dockerfile . as .*@localhost/, output
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -120,10 +120,10 @@ class CliBuildTest < CliTestCase
|
|||||||
.with(:docker, "--version", "&&", :docker, :buildx, "version")
|
.with(:docker, "--version", "&&", :docker, :buildx, "version")
|
||||||
|
|
||||||
SSHKit::Backend::Abstract.any_instance.expects(:execute)
|
SSHKit::Backend::Abstract.any_instance.expects(:execute)
|
||||||
.with(:docker, :buildx, :create, "--name", "kamal-local", "--driver=docker-container")
|
.with(:docker, :buildx, :create, "--name", "kamal-local-docker-container", "--driver=docker-container")
|
||||||
|
|
||||||
SSHKit::Backend::Abstract.any_instance.expects(:execute)
|
SSHKit::Backend::Abstract.any_instance.expects(:execute)
|
||||||
.with(:docker, :buildx, :inspect, "kamal-local")
|
.with(:docker, :buildx, :inspect, "kamal-local-docker-container")
|
||||||
.raises(SSHKit::Command::Failed.new("no builder"))
|
.raises(SSHKit::Command::Failed.new("no builder"))
|
||||||
|
|
||||||
SSHKit::Backend::Abstract.any_instance.expects(:execute).with { |*args| args.first.start_with?("git") }
|
SSHKit::Backend::Abstract.any_instance.expects(:execute).with { |*args| args.first.start_with?("git") }
|
||||||
@@ -137,7 +137,7 @@ class CliBuildTest < CliTestCase
|
|||||||
.returns("")
|
.returns("")
|
||||||
|
|
||||||
SSHKit::Backend::Abstract.any_instance.expects(:execute)
|
SSHKit::Backend::Abstract.any_instance.expects(:execute)
|
||||||
.with(:docker, :build, "--push", "--platform", "linux/amd64,linux/arm64", "--builder", "kamal-local", "-t", "dhh/app:999", "-t", "dhh/app:latest", "--label", "service=\"app\"", "--file", "Dockerfile", ".")
|
.with(:docker, :build, "--push", "--platform", "linux/amd64,linux/arm64", "--builder", "kamal-local-docker-container", "-t", "dhh/app:999", "-t", "dhh/app:latest", "--label", "service=\"app\"", "--file", "Dockerfile", ".")
|
||||||
|
|
||||||
run_command("push").tap do |output|
|
run_command("push").tap do |output|
|
||||||
assert_match /WARN Missing compatible builder, so creating a new one first/, output
|
assert_match /WARN Missing compatible builder, so creating a new one first/, output
|
||||||
@@ -203,23 +203,23 @@ class CliBuildTest < CliTestCase
|
|||||||
|
|
||||||
test "create" do
|
test "create" do
|
||||||
run_command("create").tap do |output|
|
run_command("create").tap do |output|
|
||||||
assert_match /docker buildx create --name kamal-local --driver=docker-container/, output
|
assert_match /docker buildx create --name kamal-local-docker-container --driver=docker-container/, output
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
test "create remote" do
|
test "create remote" do
|
||||||
run_command("create", fixture: :with_remote_builder).tap do |output|
|
run_command("create", fixture: :with_remote_builder).tap do |output|
|
||||||
assert_match "Running /usr/bin/env true on 1.1.1.5", output
|
assert_match "Running /usr/bin/env true on 1.1.1.5", output
|
||||||
assert_match "docker context create kamal-remote-amd64-ssh---app-1-1-1-5 --description 'kamal-remote-amd64-ssh---app-1-1-1-5 host' --docker 'host=ssh://app@1.1.1.5'", output
|
assert_match "docker context create kamal-remote-docker-container-ssh---app-1-1-1-5 --description 'kamal-remote-docker-container-ssh---app-1-1-1-5 host' --docker 'host=ssh://app@1.1.1.5'", output
|
||||||
assert_match "docker buildx create --name kamal-remote-amd64-ssh---app-1-1-1-5 kamal-remote-amd64-ssh---app-1-1-1-5 --platform linux/amd64", output
|
assert_match "docker buildx create --name kamal-remote-docker-container-ssh---app-1-1-1-5 kamal-remote-docker-container-ssh---app-1-1-1-5", output
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
test "create remote with custom ports" do
|
test "create remote with custom ports" do
|
||||||
run_command("create", fixture: :with_remote_builder_and_custom_ports).tap do |output|
|
run_command("create", fixture: :with_remote_builder_and_custom_ports).tap do |output|
|
||||||
assert_match "Running /usr/bin/env true on 1.1.1.5", output
|
assert_match "Running /usr/bin/env true on 1.1.1.5", output
|
||||||
assert_match "docker context create kamal-remote-amd64-ssh---app-1-1-1-5-2122 --description 'kamal-remote-amd64-ssh---app-1-1-1-5-2122 host' --docker 'host=ssh://app@1.1.1.5:2122'", output
|
assert_match "docker context create kamal-remote-docker-container-ssh---app-1-1-1-5-2122 --description 'kamal-remote-docker-container-ssh---app-1-1-1-5-2122 host' --docker 'host=ssh://app@1.1.1.5:2122'", output
|
||||||
assert_match "docker buildx create --name kamal-remote-amd64-ssh---app-1-1-1-5-2122 kamal-remote-amd64-ssh---app-1-1-1-5-2122 --platform linux/amd64", output
|
assert_match "docker buildx create --name kamal-remote-docker-container-ssh---app-1-1-1-5-2122 kamal-remote-docker-container-ssh---app-1-1-1-5-2122", output
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class CliTestCase < ActiveSupport::TestCase
|
|||||||
SSHKit::Backend::Abstract.any_instance.stubs(:execute)
|
SSHKit::Backend::Abstract.any_instance.stubs(:execute)
|
||||||
.with { |arg1, arg2| arg1 == :rm && arg2 == ".kamal/locks/app/details" }
|
.with { |arg1, arg2| arg1 == :rm && arg2 == ".kamal/locks/app/details" }
|
||||||
SSHKit::Backend::Abstract.any_instance.stubs(:execute)
|
SSHKit::Backend::Abstract.any_instance.stubs(:execute)
|
||||||
.with(:docker, :buildx, :inspect, "kamal-local")
|
.with(:docker, :buildx, :inspect, "kamal-local-docker-container")
|
||||||
end
|
end
|
||||||
|
|
||||||
def assert_hook_ran(hook, output, version:, service_version:, hosts:, command:, subcommand: nil, runtime: false)
|
def assert_hook_ran(hook, output, version:, service_version:, hosts:, command:, subcommand: nil, runtime: false)
|
||||||
|
|||||||
@@ -5,51 +5,51 @@ class CommandsBuilderTest < ActiveSupport::TestCase
|
|||||||
@config = { service: "app", image: "dhh/app", registry: { "username" => "dhh", "password" => "secret" }, servers: [ "1.1.1.1" ] }
|
@config = { service: "app", image: "dhh/app", registry: { "username" => "dhh", "password" => "secret" }, servers: [ "1.1.1.1" ] }
|
||||||
end
|
end
|
||||||
|
|
||||||
test "target multiarch by default" do
|
test "target linux/amd64,linux/arm64 locally by default" do
|
||||||
builder = new_builder_command(builder: { "cache" => { "type" => "gha" } })
|
builder = new_builder_command(builder: { "cache" => { "type" => "gha" } })
|
||||||
assert_equal "local", builder.name
|
assert_equal "local", builder.name
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker build --push --platform linux/amd64,linux/arm64 --builder kamal-local -t dhh/app:123 -t dhh/app:latest --cache-to type=gha --cache-from type=gha --label service=\"app\" --file Dockerfile .",
|
"docker build --push --platform linux/amd64,linux/arm64 --builder kamal-local-docker-container -t dhh/app:123 -t dhh/app:latest --cache-to type=gha --cache-from type=gha --label service=\"app\" --file Dockerfile .",
|
||||||
builder.push.join(" ")
|
builder.push.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "target native when multiarch is off" do
|
test "target specified arch locally by default" do
|
||||||
builder = new_builder_command(builder: { "multiarch" => false })
|
builder = new_builder_command(builder: { "arch" => [ "amd64" ] })
|
||||||
assert_equal "local", builder.name
|
assert_equal "local", builder.name
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker build --push --builder kamal-local -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --file Dockerfile .",
|
"docker build --push --platform linux/amd64 --builder kamal-local-docker-container -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --file Dockerfile .",
|
||||||
builder.push.join(" ")
|
builder.push.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "target native cached when multiarch is off and cache is set" do
|
test "build with caching" do
|
||||||
builder = new_builder_command(builder: { "multiarch" => false, "cache" => { "type" => "gha" } })
|
builder = new_builder_command(builder: { "cache" => { "type" => "gha" } })
|
||||||
assert_equal "local", builder.name
|
assert_equal "local", builder.name
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker build --push --builder kamal-local -t dhh/app:123 -t dhh/app:latest --cache-to type=gha --cache-from type=gha --label service=\"app\" --file Dockerfile .",
|
"docker build --push --platform linux/amd64,linux/arm64 --builder kamal-local-docker-container -t dhh/app:123 -t dhh/app:latest --cache-to type=gha --cache-from type=gha --label service=\"app\" --file Dockerfile .",
|
||||||
builder.push.join(" ")
|
builder.push.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "target multiarch remote when local and remote is set" do
|
test "hybrid build if remote is set" do
|
||||||
builder = new_builder_command(builder: { "local" => { "arch" => "arm64" }, "remote" => { "arch" => "amd64", "host" => "ssh://app@127.0.0.1" }, "cache" => { "type" => "gha" } })
|
builder = new_builder_command(builder: { "remote" => "ssh://app@127.0.0.1", "cache" => { "type" => "gha" } })
|
||||||
assert_equal "hybrid", builder.name
|
assert_equal "hybrid", builder.name
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker build --push --platform linux/arm64,linux/amd64 --builder kamal-hybrid-arm64-amd64-ssh---app-127-0-0-1 -t dhh/app:123 -t dhh/app:latest --cache-to type=gha --cache-from type=gha --label service=\"app\" --file Dockerfile .",
|
"docker build --push --platform linux/amd64,linux/arm64 --builder kamal-hybrid-docker-container-ssh---app-127-0-0-1 -t dhh/app:123 -t dhh/app:latest --cache-to type=gha --cache-from type=gha --label service=\"app\" --file Dockerfile .",
|
||||||
builder.push.join(" ")
|
builder.push.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "target multiarch local when arch is set" do
|
test "target remote when remote set and arch is non local" do
|
||||||
builder = new_builder_command(builder: { "local" => { "arch" => "amd64" } })
|
builder = new_builder_command(builder: { "arch" => [ "#{remote_arch}" ], "remote" => "ssh://app@host", "cache" => { "type" => "gha" } })
|
||||||
assert_equal "local", builder.name
|
|
||||||
assert_equal \
|
|
||||||
"docker build --push --platform linux/amd64 --builder kamal-local -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --file Dockerfile .",
|
|
||||||
builder.push.join(" ")
|
|
||||||
end
|
|
||||||
|
|
||||||
test "target native remote when only remote is set" do
|
|
||||||
builder = new_builder_command(builder: { "remote" => { "arch" => "amd64", "host" => "ssh://app@host" }, "cache" => { "type" => "gha" } })
|
|
||||||
assert_equal "remote", builder.name
|
assert_equal "remote", builder.name
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker build --push --platform linux/amd64 --builder kamal-remote-amd64-ssh---app-host -t dhh/app:123 -t dhh/app:latest --cache-to type=gha --cache-from type=gha --label service=\"app\" --file Dockerfile .",
|
"docker build --push --platform linux/#{remote_arch} --builder kamal-remote-docker-container-ssh---app-host -t dhh/app:123 -t dhh/app:latest --cache-to type=gha --cache-from type=gha --label service=\"app\" --file Dockerfile .",
|
||||||
|
builder.push.join(" ")
|
||||||
|
end
|
||||||
|
|
||||||
|
test "target local when remote set and arch is local" do
|
||||||
|
builder = new_builder_command(builder: { "arch" => [ "#{local_arch}" ], "remote" => "ssh://app@host", "cache" => { "type" => "gha" } })
|
||||||
|
assert_equal "local", builder.name
|
||||||
|
assert_equal \
|
||||||
|
"docker build --push --platform linux/#{local_arch} --builder kamal-local-docker-container -t dhh/app:123 -t dhh/app:latest --cache-to type=gha --cache-from type=gha --label service=\"app\" --file Dockerfile .",
|
||||||
builder.push.join(" ")
|
builder.push.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -93,28 +93,21 @@ class CommandsBuilderTest < ActiveSupport::TestCase
|
|||||||
test "build context" do
|
test "build context" do
|
||||||
builder = new_builder_command(builder: { "context" => ".." })
|
builder = new_builder_command(builder: { "context" => ".." })
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker build --push --platform linux/amd64,linux/arm64 --builder kamal-local -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --file Dockerfile ..",
|
"docker build --push --platform linux/amd64,linux/arm64 --builder kamal-local-docker-container -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --file Dockerfile ..",
|
||||||
builder.push.join(" ")
|
builder.push.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "native push with build args" do
|
test "push with build args" do
|
||||||
builder = new_builder_command(builder: { "multiarch" => false, "args" => { "a" => 1, "b" => 2 } })
|
|
||||||
assert_equal \
|
|
||||||
"docker build --push --builder kamal-local -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --build-arg a=\"1\" --build-arg b=\"2\" --file Dockerfile .",
|
|
||||||
builder.push.join(" ")
|
|
||||||
end
|
|
||||||
|
|
||||||
test "multiarch push with build args" do
|
|
||||||
builder = new_builder_command(builder: { "args" => { "a" => 1, "b" => 2 } })
|
builder = new_builder_command(builder: { "args" => { "a" => 1, "b" => 2 } })
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker build --push --platform linux/amd64,linux/arm64 --builder kamal-local -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --build-arg a=\"1\" --build-arg b=\"2\" --file Dockerfile .",
|
"docker build --push --platform linux/amd64,linux/arm64 --builder kamal-local-docker-container -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --build-arg a=\"1\" --build-arg b=\"2\" --file Dockerfile .",
|
||||||
builder.push.join(" ")
|
builder.push.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "native push with build secrets" do
|
test "push with build secrets" do
|
||||||
builder = new_builder_command(builder: { "multiarch" => false, "secrets" => [ "a", "b" ] })
|
builder = new_builder_command(builder: { "secrets" => [ "a", "b" ] })
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker build --push --builder kamal-local -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --secret id=\"a\" --secret id=\"b\" --file Dockerfile .",
|
"docker build --push --platform linux/amd64,linux/arm64 --builder kamal-local-docker-container -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --secret id=\"a\" --secret id=\"b\" --file Dockerfile .",
|
||||||
builder.push.join(" ")
|
builder.push.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -130,31 +123,10 @@ class CommandsBuilderTest < ActiveSupport::TestCase
|
|||||||
assert_equal "docker inspect -f '{{ .Config.Labels.service }}' dhh/app:123 | grep -x app || (echo \"Image dhh/app:123 is missing the 'service' label\" && exit 1)", new_builder_command.validate_image.join(" ")
|
assert_equal "docker inspect -f '{{ .Config.Labels.service }}' dhh/app:123 | grep -x app || (echo \"Image dhh/app:123 is missing the 'service' label\" && exit 1)", new_builder_command.validate_image.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "multiarch context build" do
|
test "context build" do
|
||||||
builder = new_builder_command(builder: { "context" => "./foo" })
|
builder = new_builder_command(builder: { "context" => "./foo" })
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker build --push --platform linux/amd64,linux/arm64 --builder kamal-local -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --file Dockerfile ./foo",
|
"docker build --push --platform linux/amd64,linux/arm64 --builder kamal-local-docker-container -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --file Dockerfile ./foo",
|
||||||
builder.push.join(" ")
|
|
||||||
end
|
|
||||||
|
|
||||||
test "native context build" do
|
|
||||||
builder = new_builder_command(builder: { "multiarch" => false, "context" => "./foo" })
|
|
||||||
assert_equal \
|
|
||||||
"docker build --push --builder kamal-local -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --file Dockerfile ./foo",
|
|
||||||
builder.push.join(" ")
|
|
||||||
end
|
|
||||||
|
|
||||||
test "cached context build" do
|
|
||||||
builder = new_builder_command(builder: { "multiarch" => false, "context" => "./foo", "cache" => { "type" => "gha" } })
|
|
||||||
assert_equal \
|
|
||||||
"docker build --push --builder kamal-local -t dhh/app:123 -t dhh/app:latest --cache-to type=gha --cache-from type=gha --label service=\"app\" --file Dockerfile ./foo",
|
|
||||||
builder.push.join(" ")
|
|
||||||
end
|
|
||||||
|
|
||||||
test "remote context build" do
|
|
||||||
builder = new_builder_command(builder: { "remote" => { "arch" => "amd64", "host" => "ssh://app@host" }, "context" => "./foo" })
|
|
||||||
assert_equal \
|
|
||||||
"docker build --push --platform linux/amd64 --builder kamal-remote-amd64-ssh---app-host -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --file Dockerfile ./foo",
|
|
||||||
builder.push.join(" ")
|
builder.push.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -171,4 +143,12 @@ class CommandsBuilderTest < ActiveSupport::TestCase
|
|||||||
def build_directory
|
def build_directory
|
||||||
"#{Dir.tmpdir}/kamal-clones/app/kamal/"
|
"#{Dir.tmpdir}/kamal-clones/app/kamal/"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def local_arch
|
||||||
|
`uname -m`.strip == "x86_64" ? "amd64" : "arm64"
|
||||||
|
end
|
||||||
|
|
||||||
|
def remote_arch
|
||||||
|
`uname -m`.strip == "x86_64" ? "arm64" : "amd64"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -14,45 +14,29 @@ class ConfigurationBuilderTest < ActiveSupport::TestCase
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
test "multiarch?" do
|
|
||||||
assert_equal true, config.builder.multiarch?
|
|
||||||
end
|
|
||||||
|
|
||||||
test "setting multiarch to false" do
|
|
||||||
@deploy_with_builder_option[:builder] = { "multiarch" => false }
|
|
||||||
|
|
||||||
assert_equal false, config_with_builder_option.builder.multiarch?
|
|
||||||
end
|
|
||||||
|
|
||||||
test "local?" do
|
test "local?" do
|
||||||
assert_equal false, config.builder.local?
|
assert_equal true, config.builder.local?
|
||||||
end
|
end
|
||||||
|
|
||||||
test "remote?" do
|
test "remote?" do
|
||||||
assert_equal false, config.builder.remote?
|
assert_equal false, config.builder.remote?
|
||||||
end
|
end
|
||||||
|
|
||||||
test "remote_arch" do
|
test "remote" do
|
||||||
assert_nil config.builder.remote_arch
|
assert_nil config.builder.remote
|
||||||
end
|
|
||||||
|
|
||||||
test "remote_host" do
|
|
||||||
assert_nil config.builder.remote_host
|
|
||||||
end
|
end
|
||||||
|
|
||||||
test "setting both local and remote configs" do
|
test "setting both local and remote configs" do
|
||||||
@deploy_with_builder_option[:builder] = {
|
@deploy_with_builder_option[:builder] = {
|
||||||
"local" => { "arch" => "arm64" },
|
"arch" => [ "amd64", "arm64" ],
|
||||||
"remote" => { "arch" => "amd64", "host" => "ssh://root@192.168.0.1" }
|
"remote" => "ssh://root@192.168.0.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_equal true, config_with_builder_option.builder.local?
|
assert_equal true, config_with_builder_option.builder.local?
|
||||||
assert_equal true, config_with_builder_option.builder.remote?
|
assert_equal true, config_with_builder_option.builder.remote?
|
||||||
|
|
||||||
assert_equal "amd64", config_with_builder_option.builder.remote_arch
|
assert_equal [ "amd64", "arm64" ], config_with_builder_option.builder.arches
|
||||||
assert_equal "ssh://root@192.168.0.1", config_with_builder_option.builder.remote_host
|
assert_equal "ssh://root@192.168.0.1", config_with_builder_option.builder.remote
|
||||||
|
|
||||||
assert_equal "arm64", config_with_builder_option.builder.local_arch
|
|
||||||
end
|
end
|
||||||
|
|
||||||
test "cached?" do
|
test "cached?" do
|
||||||
|
|||||||
@@ -90,10 +90,8 @@ class ConfigurationValidationTest < ActiveSupport::TestCase
|
|||||||
|
|
||||||
test "builder" do
|
test "builder" do
|
||||||
assert_error "builder: unknown key: foo", builder: { "foo" => "bar" }
|
assert_error "builder: unknown key: foo", builder: { "foo" => "bar" }
|
||||||
assert_error "builder/remote: should be a hash", builder: { "remote" => true }
|
assert_error "builder/remote: should be a string", builder: { "remote" => { "foo" => "bar" } }
|
||||||
assert_error "builder/remote: unknown key: foo", builder: { "remote" => { "foo" => "bar" } }
|
assert_error "builder/arch: should be an array or a string", builder: { "arch" => {} }
|
||||||
assert_error "builder/local: unknown key: foo", builder: { "local" => { "foo" => "bar" } }
|
|
||||||
assert_error "builder/remote/arch: should be a string", builder: { "remote" => { "arch" => [] } }
|
|
||||||
assert_error "builder/args: should be a hash", builder: { "args" => [ "foo" ] }
|
assert_error "builder/args: should be a hash", builder: { "args" => [ "foo" ] }
|
||||||
assert_error "builder/cache/options: should be a string", builder: { "cache" => { "options" => [] } }
|
assert_error "builder/cache/options: should be a string", builder: { "cache" => { "options" => [] } }
|
||||||
end
|
end
|
||||||
|
|||||||
5
test/fixtures/deploy_with_remote_builder.yml
vendored
5
test/fixtures/deploy_with_remote_builder.yml
vendored
@@ -36,6 +36,5 @@ accessories:
|
|||||||
readiness_delay: 0
|
readiness_delay: 0
|
||||||
|
|
||||||
builder:
|
builder:
|
||||||
remote:
|
arch: <%= `uname -m`.strip == "x86_64" ? "arm64" : "amd64" %>
|
||||||
arch: amd64
|
remote: ssh://app@1.1.1.5
|
||||||
host: ssh://app@1.1.1.5
|
|
||||||
|
|||||||
@@ -40,6 +40,5 @@ ssh:
|
|||||||
port: 22
|
port: 22
|
||||||
|
|
||||||
builder:
|
builder:
|
||||||
remote:
|
arch: <%= `uname -m`.strip == "x86_64" ? "arm64" : "amd64" %>
|
||||||
arch: amd64
|
remote: ssh://app@1.1.1.5:2122
|
||||||
host: ssh://app@1.1.1.5:2122
|
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ registry:
|
|||||||
username: root
|
username: root
|
||||||
password: root
|
password: root
|
||||||
builder:
|
builder:
|
||||||
multiarch: false
|
|
||||||
driver: docker
|
driver: docker
|
||||||
args:
|
args:
|
||||||
COMMIT_SHA: <%= `git rev-parse HEAD` %>
|
COMMIT_SHA: <%= `git rev-parse HEAD` %>
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ registry:
|
|||||||
username: root
|
username: root
|
||||||
password: root
|
password: root
|
||||||
builder:
|
builder:
|
||||||
multiarch: false
|
|
||||||
driver: docker
|
driver: docker
|
||||||
args:
|
args:
|
||||||
COMMIT_SHA: <%= `git rev-parse HEAD` %>
|
COMMIT_SHA: <%= `git rev-parse HEAD` %>
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ class MainTest < IntegrationTest
|
|||||||
assert_equal "app-#{version}", config[:service_with_version]
|
assert_equal "app-#{version}", config[:service_with_version]
|
||||||
assert_equal [], config[:volume_args]
|
assert_equal [], config[:volume_args]
|
||||||
assert_equal({ user: "root", port: 22, keepalive: true, keepalive_interval: 30, log_level: :fatal }, config[:ssh_options])
|
assert_equal({ user: "root", port: 22, keepalive: true, keepalive_interval: 30, log_level: :fatal }, config[:ssh_options])
|
||||||
assert_equal({ "multiarch" => false, "args" => { "COMMIT_SHA" => version } }, config[:builder])
|
assert_equal({ "driver" => "docker", "args" => { "COMMIT_SHA" => version } }, config[:builder])
|
||||||
assert_equal [ "--log-opt", "max-size=\"10m\"" ], config[:logging]
|
assert_equal [ "--log-opt", "max-size=\"10m\"" ], config[:logging]
|
||||||
assert_equal({ "cmd"=>"wget -qO- http://localhost > /dev/null || exit 1", "interval"=>"1s", "max_attempts"=>3, "port"=>3000, "path"=>"/up", "cord"=>"/tmp/kamal-cord", "log_lines"=>50 }, config[:healthcheck])
|
assert_equal({ "cmd"=>"wget -qO- http://localhost > /dev/null || exit 1", "interval"=>"1s", "max_attempts"=>3, "port"=>3000, "path"=>"/up", "cord"=>"/tmp/kamal-cord", "log_lines"=>50 }, config[:healthcheck])
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user