Class: Kamal::Configuration::Proxy

Inherits:
Object
  • Object
show all
Includes:
Validation
Defined in:
lib/kamal/configuration/proxy.rb

Direct Known Subclasses

Loadbalancer

Defined Under Namespace

Classes: Boot, Run

Constant Summary collapse

DEFAULT_LOG_REQUEST_HEADERS =
[ "Cache-Control", "Last-Modified", "User-Agent" ]
CONTAINER_NAME =
"kamal-proxy"
LOADBALANCER_CONTAINER_NAME =
"kamal-loadbalancer"

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Validation

#validate!, #validation_yml

Constructor Details

#initialize(config:, proxy_config:, role_name: nil, secrets:, context: "proxy") ⇒ Proxy

Returns a new instance of Proxy.



11
12
13
14
15
16
17
18
19
# File 'lib/kamal/configuration/proxy.rb', line 11

def initialize(config:, proxy_config:, role_name: nil, secrets:, context: "proxy")
  @config = config
  @proxy_config = proxy_config
  @proxy_config = {} if @proxy_config.nil?
  @role_name = role_name
  @secrets = secrets
  validate! @proxy_config, with: Kamal::Configuration::Validator::Proxy, context: context
  @run = Kamal::Configuration::Proxy::Run.new(config, run_config: @proxy_config["run"], context: "#{context}/run") if @proxy_config && @proxy_config["run"].present?
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



10
11
12
# File 'lib/kamal/configuration/proxy.rb', line 10

def config
  @config
end

#proxy_configObject (readonly)

Returns the value of attribute proxy_config.



10
11
12
# File 'lib/kamal/configuration/proxy.rb', line 10

def proxy_config
  @proxy_config
end

#role_nameObject (readonly)

Returns the value of attribute role_name.



10
11
12
# File 'lib/kamal/configuration/proxy.rb', line 10

def role_name
  @role_name
end

#runObject (readonly)

Returns the value of attribute run.



10
11
12
# File 'lib/kamal/configuration/proxy.rb', line 10

def run
  @run
end

#secretsObject (readonly)

Returns the value of attribute secrets.



10
11
12
# File 'lib/kamal/configuration/proxy.rb', line 10

def secrets
  @secrets
end

Instance Method Details

#app_portObject



21
22
23
# File 'lib/kamal/configuration/proxy.rb', line 21

def app_port
  proxy_config.fetch("app_port", 80)
end

#certificate_pem_contentObject



59
60
61
62
63
# File 'lib/kamal/configuration/proxy.rb', line 59

def certificate_pem_content
  ssl = proxy_config["ssl"]
  return nil unless ssl.is_a?(Hash)
  secrets[ssl["certificate_pem"]]
end

#container_tls_certObject



79
80
81
# File 'lib/kamal/configuration/proxy.rb', line 79

def container_tls_cert
  tls_path(config.proxy_boot.tls_container_directory, "cert.pem")
end

#container_tls_keyObject



83
84
85
# File 'lib/kamal/configuration/proxy.rb', line 83

def container_tls_key
  tls_path(config.proxy_boot.tls_container_directory, "key.pem") if custom_ssl_certificate?
end

#custom_ssl_certificate?Boolean

Returns:

  • (Boolean)


53
54
55
56
57
# File 'lib/kamal/configuration/proxy.rb', line 53

def custom_ssl_certificate?
  ssl = proxy_config["ssl"]
  return false unless ssl.is_a?(Hash)
  ssl["certificate_pem"].present? && ssl["private_key_pem"].present?
end

#deploy_command_args(target:) ⇒ Object



125
126
127
# File 'lib/kamal/configuration/proxy.rb', line 125

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

#deploy_optionsObject



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/kamal/configuration/proxy.rb', line 91

def deploy_options
  opts = {
    host: hosts,
    tls: ssl? ? true : nil,
    "tls-certificate-path": container_tls_cert,
    "tls-private-key-path": container_tls_key,
    "deploy-timeout": seconds_duration(config.deploy_timeout),
    "drain-timeout": seconds_duration(config.drain_timeout),
    "health-check-interval": seconds_duration(proxy_config.dig("healthcheck", "interval")),
    "health-check-timeout": seconds_duration(proxy_config.dig("healthcheck", "timeout")),
    "health-check-path": proxy_config.dig("healthcheck", "path"),
    "target-timeout": seconds_duration(proxy_config["response_timeout"]),
    "buffer-requests": proxy_config.fetch("buffering", { "requests": true }).fetch("requests", true),
    "buffer-responses": proxy_config.fetch("buffering", { "responses": true }).fetch("responses", true),
    "buffer-memory": proxy_config.dig("buffering", "memory"),
    "max-request-body": proxy_config.dig("buffering", "max_request_body"),
    "max-response-body": proxy_config.dig("buffering", "max_response_body"),
    "path-prefix": path_prefixes,
    "strip-path-prefix": proxy_config.dig("strip_path_prefix"),
    "forward-headers": proxy_config.dig("forward_headers"),
    "tls-redirect": proxy_config.dig("ssl_redirect"),
    "log-request-header": proxy_config.dig("logging", "request_headers") || DEFAULT_LOG_REQUEST_HEADERS,
    "log-response-header": proxy_config.dig("logging", "response_headers"),
    "error-pages": error_pages
  }.compact

  if load_balancing?
    opts.delete(:host)
    opts.delete(:tls)
  end

  opts
end

#effective_loadbalancerObject



41
42
43
44
45
46
47
# File 'lib/kamal/configuration/proxy.rb', line 41

def effective_loadbalancer
  return false if loadbalancer == false
  return loadbalancer if loadbalancer.present?
  return config.primary_role.hosts.first if config.primary_role && Array(config.primary_role.hosts).size > 1

  nil
end

#host_tls_certObject



71
72
73
# File 'lib/kamal/configuration/proxy.rb', line 71

def host_tls_cert
  tls_path(config.proxy_boot.tls_directory, "cert.pem")
end

#host_tls_keyObject



75
76
77
# File 'lib/kamal/configuration/proxy.rb', line 75

def host_tls_key
  tls_path(config.proxy_boot.tls_directory, "key.pem")
end

#hostsObject



29
30
31
# File 'lib/kamal/configuration/proxy.rb', line 29

def hosts
  proxy_config["hosts"] || proxy_config["host"]&.split(",") || []
end

#load_balancing?Boolean

Returns:

  • (Boolean)


37
38
39
# File 'lib/kamal/configuration/proxy.rb', line 37

def load_balancing?
  effective_loadbalancer.present?
end

#loadbalancerObject



33
34
35
# File 'lib/kamal/configuration/proxy.rb', line 33

def loadbalancer
  proxy_config["loadbalancer"]
end

#loadbalancer_on_proxy_host?Boolean

Returns:

  • (Boolean)


49
50
51
# File 'lib/kamal/configuration/proxy.rb', line 49

def loadbalancer_on_proxy_host?
  load_balancing? && config.proxy_hosts.include?(effective_loadbalancer)
end

#merge(other) ⇒ Object



140
141
142
# File 'lib/kamal/configuration/proxy.rb', line 140

def merge(other)
  self.class.new config: config, proxy_config: other.proxy_config.deep_merge(proxy_config), role_name: role_name, secrets: secrets
end

#path_prefixesObject



87
88
89
# File 'lib/kamal/configuration/proxy.rb', line 87

def path_prefixes
  proxy_config["path_prefixes"] || proxy_config["path_prefix"]&.split(",") || []
end

#private_key_pem_contentObject



65
66
67
68
69
# File 'lib/kamal/configuration/proxy.rb', line 65

def private_key_pem_content
  ssl = proxy_config["ssl"]
  return nil unless ssl.is_a?(Hash)
  secrets[ssl["private_key_pem"]]
end

#ssl?Boolean

Returns:

  • (Boolean)


25
26
27
# File 'lib/kamal/configuration/proxy.rb', line 25

def ssl?
  proxy_config.fetch("ssl", false)
end

#stop_command_args(**options) ⇒ Object



136
137
138
# File 'lib/kamal/configuration/proxy.rb', line 136

def stop_command_args(**options)
  optionize stop_options(**options), with: "="
end

#stop_options(drain_timeout: nil, message: nil) ⇒ Object



129
130
131
132
133
134
# File 'lib/kamal/configuration/proxy.rb', line 129

def stop_options(drain_timeout: nil, message: nil)
  {
    "drain-timeout": seconds_duration(drain_timeout),
    message: message
  }.compact
end