Skip to content

Commit

Permalink
support custom proxy image
Browse files Browse the repository at this point in the history
- Allow users to specify custom proxy image repository instead of using default basecamp/kamal-proxy
- Help users in regions where Docker Hub access is restricted (e.g. China) to pull proxy image from cloud vendor repositories
- Move proxy related configurations from configuration to proxy
  • Loading branch information
songjiz committed Dec 4, 2024
1 parent 495b3cd commit 77593f5
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 84 deletions.
20 changes: 11 additions & 9 deletions lib/kamal/cli/proxy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,34 @@ def boot

version = capture_with_info(*KAMAL.proxy.version).strip.presence

if version && Kamal::Utils.older_version?(version, Kamal::Configuration::PROXY_MINIMUM_VERSION)
raise "kamal-proxy version #{version} is too old, run `kamal proxy reboot` in order to update to at least #{Kamal::Configuration::PROXY_MINIMUM_VERSION}"
if version && Kamal::Utils.older_version?(version, Kamal::Configuration::Proxy::MINIMUM_VERSION)
raise "kamal-proxy version #{version} is too old, run `kamal proxy reboot` in order to update to at least #{Kamal::Configuration::Proxy::MINIMUM_VERSION}"
end
execute *KAMAL.proxy.start_or_run
end
end
end

desc "boot_config <set|get|reset>", "Manage kamal-proxy boot configuration"
option :image, type: :string, default: Kamal::Configuration::Proxy::DEFAULT_IMAGE, desc: "Name of the image"
option :publish, type: :boolean, default: true, desc: "Publish the proxy ports on the host"
option :http_port, type: :numeric, default: Kamal::Configuration::PROXY_HTTP_PORT, desc: "HTTP port to publish on the host"
option :https_port, type: :numeric, default: Kamal::Configuration::PROXY_HTTPS_PORT, desc: "HTTPS port to publish on the host"
option :log_max_size, type: :string, default: Kamal::Configuration::PROXY_LOG_MAX_SIZE, desc: "Max size of proxy logs"
option :http_port, type: :numeric, default: Kamal::Configuration::Proxy::HTTP_PORT, desc: "HTTP port to publish on the host"
option :https_port, type: :numeric, default: Kamal::Configuration::Proxy::HTTPS_PORT, desc: "HTTPS port to publish on the host"
option :log_max_size, type: :string, default: Kamal::Configuration::Proxy::LOG_MAX_SIZE, desc: "Max size of proxy logs"
option :docker_options, type: :array, default: [], desc: "Docker options to pass to the proxy container", banner: "option=value option2=value2"
def boot_config(subcommand)
case subcommand
when "set"
boot_options = [
*(KAMAL.config.proxy_publish_args(options[:http_port], options[:https_port]) if options[:publish]),
*(KAMAL.config.proxy_logging_args(options[:log_max_size])),
*options[:docker_options].map { |option| "--#{option}" }
*(KAMAL.config.proxy.publish_args(options[:http_port], options[:https_port]) if options[:publish]),
*(KAMAL.config.proxy.logging_args(options[:log_max_size])),
*options[:docker_options].map { |option| "--#{option}" },
options[:image]
]

on(KAMAL.proxy_hosts) do |host|
execute(*KAMAL.proxy.ensure_proxy_directory)
upload! StringIO.new(boot_options.join(" ")), KAMAL.config.proxy_options_file
upload! StringIO.new(boot_options.join(" ")), KAMAL.config.proxy.options_file
end
when "get"
on(KAMAL.proxy_hosts) do |host|
Expand Down
4 changes: 1 addition & 3 deletions lib/kamal/commands/app/proxy.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
module Kamal::Commands::App::Proxy
delegate :proxy_container_name, to: :config

def deploy(target:)
proxy_exec :deploy, role.container_prefix, *role.proxy.deploy_command_args(target: target)
end
Expand All @@ -11,6 +9,6 @@ def remove

private
def proxy_exec(*command)
docker :exec, proxy_container_name, "kamal-proxy", *command
docker :exec, config.proxy.container_name, "kamal-proxy", *command
end
end
13 changes: 6 additions & 7 deletions lib/kamal/commands/proxy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ def run
"--detach",
"--restart", "unless-stopped",
"--volume", "kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy",
"\$\(#{get_boot_options.join(" ")}\)",
config.proxy_image
"\$\(#{get_boot_options.join(" ")}\)"
end

def start
Expand Down Expand Up @@ -65,23 +64,23 @@ def cleanup_traefik
end

def ensure_proxy_directory
make_directory config.proxy_directory
make_directory config.proxy.directory
end

def remove_proxy_directory
remove_directory config.proxy_directory
remove_directory config.proxy.directory
end

def get_boot_options
combine [ :cat, config.proxy_options_file ], [ :echo, "\"#{config.proxy_options_default.join(" ")}\"" ], by: "||"
combine [ :cat, config.proxy.options_file ], [ :echo, "\"#{config.proxy.options_default.join(" ")}\"" ], by: "||"
end

def reset_boot_options
remove_file config.proxy_options_file
remove_file config.proxy.options_file
end

private
def container_name
config.proxy_container_name
config.proxy.container_name
end
end
42 changes: 0 additions & 42 deletions lib/kamal/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,6 @@ class Kamal::Configuration

include Validation

PROXY_MINIMUM_VERSION = "v0.8.4"
PROXY_HTTP_PORT = 80
PROXY_HTTPS_PORT = 443
PROXY_LOG_MAX_SIZE = "10m"

class << self
def create_from(config_file:, destination: nil, version: nil)
ENV["KAMAL_DESTINATION"] = destination
Expand Down Expand Up @@ -82,7 +77,6 @@ def initialize(raw_config, destination: nil, version: nil, validate: true)
ensure_unique_hosts_for_ssl_roles
end


def version=(version)
@declared_version = version
end
Expand All @@ -106,7 +100,6 @@ def minimum_version
raw_config.minimum_version
end


def roles
servers.roles
end
Expand All @@ -119,7 +112,6 @@ def accessory(name)
accessories.detect { |a| a.name == name.to_s }
end


def all_hosts
(roles + accessories).flat_map(&:hosts).uniq
end
Expand Down Expand Up @@ -180,7 +172,6 @@ def retain_containers
raw_config.retain_containers || 5
end


def volume_args
if raw_config.volumes.present?
argumentize "--volume", raw_config.volumes
Expand All @@ -193,7 +184,6 @@ def logging_args
logging.args
end


def readiness_delay
raw_config.readiness_delay || 7
end
Expand All @@ -206,7 +196,6 @@ def drain_timeout
raw_config.drain_timeout || 30
end


def run_directory
".kamal"
end
Expand All @@ -227,7 +216,6 @@ def assets_directory
File.join app_directory, "assets"
end


def hooks_path
raw_config.hooks_path || ".kamal/hooks"
end
Expand All @@ -236,7 +224,6 @@ def asset_path
raw_config.asset_path
end


def env_tags
@env_tags ||= if (tags = raw_config.env["tags"])
tags.collect { |name, config| Env::Tag.new(name, config: config, secrets: secrets) }
Expand All @@ -249,35 +236,6 @@ def env_tag(name)
env_tags.detect { |t| t.name == name.to_s }
end

def proxy_publish_args(http_port, https_port)
argumentize "--publish", [ "#{http_port}:#{PROXY_HTTP_PORT}", "#{https_port}:#{PROXY_HTTPS_PORT}" ]
end

def proxy_logging_args(max_size)
argumentize "--log-opt", "max-size=#{max_size}" if max_size.present?
end

def proxy_options_default
[ *proxy_publish_args(PROXY_HTTP_PORT, PROXY_HTTPS_PORT), *proxy_logging_args(PROXY_LOG_MAX_SIZE) ]
end

def proxy_image
"basecamp/kamal-proxy:#{PROXY_MINIMUM_VERSION}"
end

def proxy_container_name
"kamal-proxy"
end

def proxy_directory
File.join run_directory, "proxy"
end

def proxy_options_file
File.join proxy_directory, "options"
end


def to_h
{
roles: role_names,
Expand Down
1 change: 0 additions & 1 deletion lib/kamal/configuration/docs/proxy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
# It is disabled by default on all other roles but can be enabled by setting
# `proxy: true` or providing a proxy configuration.
proxy:

# Hosts
#
# The hosts that will be used to serve the app. The proxy will only route requests
Expand Down
31 changes: 30 additions & 1 deletion lib/kamal/configuration/proxy.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
class Kamal::Configuration::Proxy
include Kamal::Configuration::Validation

HTTP_PORT = 80
HTTPS_PORT = 443
LOG_MAX_SIZE = "10m"
MINIMUM_VERSION = "v0.8.4"
DEFAULT_LOG_REQUEST_HEADERS = [ "Cache-Control", "Last-Modified", "User-Agent" ]
CONTAINER_NAME = "kamal-proxy"
DEFAULT_CONTAINER_NAME = "kamal-proxy"
DEFAULT_IMAGE = "basecamp/kamal-proxy:#{MINIMUM_VERSION}"

delegate :argumentize, :optionize, to: Kamal::Utils

Expand All @@ -14,6 +19,10 @@ def initialize(config:, proxy_config:, context: "proxy")
validate! @proxy_config, with: Kamal::Configuration::Validator::Proxy, context: context
end

def container_name
DEFAULT_CONTAINER_NAME
end

def app_port
proxy_config.fetch("app_port", 80)
end
Expand Down Expand Up @@ -47,6 +56,26 @@ def deploy_options
}.compact
end

def directory
File.join config.run_directory, "proxy"
end

def options_file
File.join directory, "options"
end

def publish_args(http_port, https_port)
argumentize "--publish", [ "#{http_port}:#{HTTP_PORT}", "#{https_port}:#{HTTPS_PORT}" ]
end

def logging_args(max_size)
argumentize "--log-opt", "max-size=#{max_size}" if max_size.present?
end

def options_default
[ *publish_args(HTTP_PORT, HTTPS_PORT), *logging_args(LOG_MAX_SIZE), DEFAULT_IMAGE ]
end

def deploy_command_args(target:)
optionize ({ target: "#{target}:#{app_port}" }).merge(deploy_options), with: "="
end
Expand Down
Loading

0 comments on commit 77593f5

Please sign in to comment.