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
@@ -19,16 +19,38 @@ class Kamal::Configuration::Builder
|
||||
builder_config
|
||||
end
|
||||
|
||||
def multiarch?
|
||||
builder_config["multiarch"] != false
|
||||
def remote
|
||||
builder_config["remote"]
|
||||
end
|
||||
|
||||
def local?
|
||||
!!builder_config["local"]
|
||||
def arches
|
||||
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
|
||||
|
||||
def remote?
|
||||
!!builder_config["remote"]
|
||||
remote_arches.any?
|
||||
end
|
||||
|
||||
def local?
|
||||
arches.empty? || local_arches.any?
|
||||
end
|
||||
|
||||
def cached?
|
||||
@@ -59,18 +81,6 @@ class Kamal::Configuration::Builder
|
||||
builder_config.fetch("driver", "docker-container")
|
||||
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
|
||||
if cached?
|
||||
case builder_config["cache"]["type"]
|
||||
@@ -120,27 +130,14 @@ class Kamal::Configuration::Builder
|
||||
|
||||
private
|
||||
def valid?
|
||||
if multiarch?
|
||||
if local?
|
||||
raise ArgumentError, "Invalid builder configuration: local configuration, arch required" unless local_arch
|
||||
end
|
||||
|
||||
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?
|
||||
if docker_driver?
|
||||
raise ArgumentError, "Invalid builder configuration: the `docker` driver does not not support remote builders" if remote
|
||||
raise ArgumentError, "Invalid builder configuration: the `docker` driver does not not support caching" if cached?
|
||||
raise ArgumentError, "Invalid builder configuration: the `docker` driver does not not support multiple arches" if arches.many?
|
||||
end
|
||||
|
||||
if @options["cache"] && @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
|
||||
|
||||
@@ -179,4 +176,8 @@ class Kamal::Configuration::Builder
|
||||
def pwd_sha
|
||||
Digest::SHA256.hexdigest(Dir.pwd)[0..12]
|
||||
end
|
||||
|
||||
def default_arch
|
||||
docker_driver? ? [] : [ "amd64", "arm64" ]
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# The builder configuration controls how the application is built with `docker build`
|
||||
#
|
||||
# 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
|
||||
#
|
||||
# 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.
|
||||
builder:
|
||||
|
||||
# Multiarch
|
||||
#
|
||||
# Enables multiarch builds, defaults to `true`
|
||||
multiarch: false
|
||||
|
||||
# Driver
|
||||
#
|
||||
# The build driver to use, defaults to `docker-container`
|
||||
driver: docker
|
||||
|
||||
# Local configuration
|
||||
# Arch
|
||||
#
|
||||
# The build configuration for local builds, only used if multiarch is enabled (the default)
|
||||
#
|
||||
# If there is no remote configuration, by default we build for amd64 and arm64.
|
||||
# If you only want to build for one architecture, you can specify it here.
|
||||
# The docker socket is optional and uses the default docker host socket when not specified
|
||||
local:
|
||||
arch: amd64
|
||||
host: /var/run/docker.sock
|
||||
# The architectures to build for, defaults to `[ amd64, arm64 ]`
|
||||
# Unless you are using the docker driver, when it defaults to the local architecture
|
||||
# You can set an array or just a single value
|
||||
arch:
|
||||
- amd64
|
||||
|
||||
# Remote configuration
|
||||
#
|
||||
# The build configuration for remote builds, also only used if multiarch is enabled.
|
||||
# The arch is required and can be either amd64 or arm64.
|
||||
remote:
|
||||
arch: arm64
|
||||
host: ssh://docker@docker-builder
|
||||
# If you have a remote builder, you can configure it here
|
||||
remote: ssh://docker@docker-builder
|
||||
|
||||
# Builder cache
|
||||
#
|
||||
# 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:
|
||||
type: registry
|
||||
options: mode=max
|
||||
|
||||
@@ -28,7 +28,11 @@ class Kamal::Configuration::Validator
|
||||
elsif key == "hosts"
|
||||
validate_servers! value
|
||||
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)
|
||||
case key.to_s
|
||||
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)
|
||||
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)
|
||||
validate_type! array, Array
|
||||
|
||||
|
||||
Reference in New Issue
Block a user