Compare commits
24 Commits
kamal-prox
...
v2.1.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e34031f70c | ||
|
|
23898a5197 | ||
|
|
1e9c9e9103 | ||
|
|
4b2c9cdc72 | ||
|
|
80191588c2 | ||
|
|
5ca806f4d3 | ||
|
|
1d04a6644f | ||
|
|
950624d667 | ||
|
|
81f3508507 | ||
|
|
9a16873f21 | ||
|
|
e5ca53db6e | ||
|
|
82a436fa02 | ||
|
|
7be2e7e0ba | ||
|
|
4f7ebd73a3 | ||
|
|
279bda2770 | ||
|
|
aa15fa532a | ||
|
|
276b469c2b | ||
|
|
c10b3fb07a | ||
|
|
0ff1450a74 | ||
|
|
f47fd13e5b | ||
|
|
1d8c40f5d2 | ||
|
|
73c78079bc | ||
|
|
cd12f95a97 | ||
|
|
190f4fba28 |
@@ -1,7 +1,7 @@
|
|||||||
PATH
|
PATH
|
||||||
remote: .
|
remote: .
|
||||||
specs:
|
specs:
|
||||||
kamal (2.0.0)
|
kamal (2.1.2)
|
||||||
activesupport (>= 7.0)
|
activesupport (>= 7.0)
|
||||||
base64 (~> 0.2)
|
base64 (~> 0.2)
|
||||||
bcrypt_pbkdf (~> 1.0)
|
bcrypt_pbkdf (~> 1.0)
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ class Kamal::Cli::App < Kamal::Cli::Base
|
|||||||
run_locally do
|
run_locally do
|
||||||
info "Following logs on #{KAMAL.primary_host}..."
|
info "Following logs on #{KAMAL.primary_host}..."
|
||||||
|
|
||||||
KAMAL.specific_roles ||= [ "web" ]
|
KAMAL.specific_roles ||= [ KAMAL.primary_role.name ]
|
||||||
role = KAMAL.roles_on(KAMAL.primary_host).first
|
role = KAMAL.roles_on(KAMAL.primary_host).first
|
||||||
|
|
||||||
app = KAMAL.app(role: role, host: host)
|
app = KAMAL.app(role: role, host: host)
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ class Kamal::Cli::Main < Kamal::Cli::Base
|
|||||||
puts "No documentation found for #{section}"
|
puts "No documentation found for #{section}"
|
||||||
end
|
end
|
||||||
|
|
||||||
desc "init", "Create config stub in config/deploy.yml and env stub in .env"
|
desc "init", "Create config stub in config/deploy.yml and secrets stub in .kamal"
|
||||||
option :bundle, type: :boolean, default: false, desc: "Add Kamal to the Gemfile and create a bin/kamal binstub"
|
option :bundle, type: :boolean, default: false, desc: "Add Kamal to the Gemfile and create a bin/kamal binstub"
|
||||||
def init
|
def init
|
||||||
require "fileutils"
|
require "fileutils"
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ servers:
|
|||||||
# cmd: bin/jobs
|
# cmd: bin/jobs
|
||||||
|
|
||||||
# Enable SSL auto certification via Let's Encrypt (and allow for multiple apps on one server).
|
# Enable SSL auto certification via Let's Encrypt (and allow for multiple apps on one server).
|
||||||
# Set ssl: false if using something like Cloudflare to terminate SSL (but keep host!).
|
# If using something like Cloudflare, it is recommended to set encryption mode
|
||||||
|
# in Cloudflare's SSL/TLS setting to "Full" to enable end-to-end encryption.
|
||||||
proxy:
|
proxy:
|
||||||
ssl: true
|
ssl: true
|
||||||
host: app.example.com
|
host: app.example.com
|
||||||
|
|||||||
@@ -1,13 +1,3 @@
|
|||||||
#!/usr/bin/env ruby
|
#!/bin/sh
|
||||||
|
|
||||||
# A sample docker-setup hook
|
echo "Docker set up on $KAMAL_HOSTS..."
|
||||||
#
|
|
||||||
# Sets up a Docker network on defined hosts which can then be used by the application’s containers
|
|
||||||
|
|
||||||
hosts = ENV["KAMAL_HOSTS"].split(",")
|
|
||||||
|
|
||||||
hosts.each do |ip|
|
|
||||||
destination = "root@#{ip}"
|
|
||||||
puts "Creating a Docker network \"kamal\" on #{destination}"
|
|
||||||
`ssh #{destination} docker network create kamal`
|
|
||||||
end
|
|
||||||
|
|||||||
@@ -43,7 +43,12 @@ class Kamal::Commander::Specifics
|
|||||||
end
|
end
|
||||||
|
|
||||||
def specified_hosts
|
def specified_hosts
|
||||||
(specific_hosts || config.all_hosts) \
|
specified_hosts = specific_hosts || config.all_hosts
|
||||||
.select { |host| (specific_roles || config.roles).flat_map(&:hosts).include?(host) }
|
|
||||||
|
if (specific_role_hosts = specific_roles&.flat_map(&:hosts)).present?
|
||||||
|
specified_hosts.select { |host| specific_role_hosts.include?(host) }
|
||||||
|
else
|
||||||
|
specified_hosts
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ class Kamal::Configuration
|
|||||||
|
|
||||||
class << self
|
class << self
|
||||||
def create_from(config_file:, destination: nil, version: nil)
|
def create_from(config_file:, destination: nil, version: nil)
|
||||||
|
ENV["KAMAL_DESTINATION"] = destination
|
||||||
|
|
||||||
raw_config = load_config_files(config_file, *destination_config_file(config_file, destination))
|
raw_config = load_config_files(config_file, *destination_config_file(config_file, destination))
|
||||||
|
|
||||||
new raw_config, destination: destination, version: version
|
new raw_config, destination: destination, version: version
|
||||||
|
|||||||
@@ -61,3 +61,10 @@ ssh:
|
|||||||
# An array of strings, with each element of the array being
|
# An array of strings, with each element of the array being
|
||||||
# a raw private key in PEM format.
|
# a raw private key in PEM format.
|
||||||
key_data: [ "-----BEGIN OPENSSH PRIVATE KEY-----" ]
|
key_data: [ "-----BEGIN OPENSSH PRIVATE KEY-----" ]
|
||||||
|
|
||||||
|
# Config
|
||||||
|
#
|
||||||
|
# Set to true to load the default OpenSSH config files (~/.ssh/config,
|
||||||
|
# /etc/ssh_config), to false ignore config files, or to a file path
|
||||||
|
# (or array of paths) to load specific configuration. Defaults to true.
|
||||||
|
config: true
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ class Kamal::Configuration::Proxy
|
|||||||
def deploy_options
|
def deploy_options
|
||||||
{
|
{
|
||||||
host: hosts,
|
host: hosts,
|
||||||
tls: proxy_config["ssl"],
|
tls: proxy_config["ssl"].presence,
|
||||||
"deploy-timeout": seconds_duration(config.deploy_timeout),
|
"deploy-timeout": seconds_duration(config.deploy_timeout),
|
||||||
"drain-timeout": seconds_duration(config.drain_timeout),
|
"drain-timeout": seconds_duration(config.drain_timeout),
|
||||||
"health-check-interval": seconds_duration(proxy_config.dig("healthcheck", "interval")),
|
"health-check-interval": seconds_duration(proxy_config.dig("healthcheck", "interval")),
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
module Kamal
|
module Kamal
|
||||||
VERSION = "2.0.0"
|
VERSION = "2.1.2"
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -150,6 +150,27 @@ class CommanderTest < ActiveSupport::TestCase
|
|||||||
assert_equal [ "1.1.1.2" ], @kamal.proxy_hosts
|
assert_equal [ "1.1.1.2" ], @kamal.proxy_hosts
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "accessory hosts without filtering" do
|
||||||
|
configure_with(:deploy_with_single_accessory)
|
||||||
|
assert_equal [ "1.1.1.5" ], @kamal.accessory_hosts
|
||||||
|
|
||||||
|
configure_with(:deploy_with_accessories_on_independent_server)
|
||||||
|
assert_equal [ "1.1.1.5", "1.1.1.1", "1.1.1.2" ], @kamal.accessory_hosts
|
||||||
|
end
|
||||||
|
|
||||||
|
test "accessory hosts with role filtering" do
|
||||||
|
configure_with(:deploy_with_single_accessory)
|
||||||
|
@kamal.specific_roles = [ "web" ]
|
||||||
|
assert_equal [], @kamal.accessory_hosts
|
||||||
|
|
||||||
|
configure_with(:deploy_with_accessories_on_independent_server)
|
||||||
|
@kamal.specific_roles = [ "web" ]
|
||||||
|
assert_equal [ "1.1.1.1", "1.1.1.2" ], @kamal.accessory_hosts
|
||||||
|
|
||||||
|
@kamal.specific_roles = [ "workers" ]
|
||||||
|
assert_equal [], @kamal.accessory_hosts
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def configure_with(variant)
|
def configure_with(variant)
|
||||||
@kamal = Kamal::Commander.new.tap do |kamal|
|
@kamal = Kamal::Commander.new.tap do |kamal|
|
||||||
|
|||||||
@@ -135,6 +135,14 @@ class CommandsAppTest < ActiveSupport::TestCase
|
|||||||
new_command.deploy(target: "172.1.0.2").join(" ")
|
new_command.deploy(target: "172.1.0.2").join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "deploy with SSL false" do
|
||||||
|
@config[:proxy] = { "ssl" => false }
|
||||||
|
|
||||||
|
assert_equal \
|
||||||
|
"docker exec kamal-proxy kamal-proxy deploy app-web --target=\"172.1.0.2:80\" --deploy-timeout=\"30s\" --drain-timeout=\"30s\" --buffer-requests --buffer-responses --log-request-header=\"Cache-Control\" --log-request-header=\"Last-Modified\" --log-request-header=\"User-Agent\"",
|
||||||
|
new_command.deploy(target: "172.1.0.2").join(" ")
|
||||||
|
end
|
||||||
|
|
||||||
test "remove" do
|
test "remove" do
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker exec kamal-proxy kamal-proxy remove app-web",
|
"docker exec kamal-proxy kamal-proxy remove app-web",
|
||||||
|
|||||||
@@ -222,6 +222,13 @@ class ConfigurationTest < ActiveSupport::TestCase
|
|||||||
assert_equal "my-user", config.registry.username
|
assert_equal "my-user", config.registry.username
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "destination is loaded into env" do
|
||||||
|
dest_config_file = Pathname.new(File.expand_path("fixtures/deploy_for_dest.yml", __dir__))
|
||||||
|
|
||||||
|
config = Kamal::Configuration.create_from config_file: dest_config_file, destination: "world"
|
||||||
|
assert_equal ENV["KAMAL_DESTINATION"], "world"
|
||||||
|
end
|
||||||
|
|
||||||
test "destination yml config merge" do
|
test "destination yml config merge" do
|
||||||
dest_config_file = Pathname.new(File.expand_path("fixtures/deploy_for_dest.yml", __dir__))
|
dest_config_file = Pathname.new(File.expand_path("fixtures/deploy_for_dest.yml", __dir__))
|
||||||
|
|
||||||
|
|||||||
38
test/fixtures/deploy_with_accessories_on_independent_server.yml
vendored
Normal file
38
test/fixtures/deploy_with_accessories_on_independent_server.yml
vendored
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
service: app
|
||||||
|
image: dhh/app
|
||||||
|
servers:
|
||||||
|
web:
|
||||||
|
- "1.1.1.1"
|
||||||
|
- "1.1.1.2"
|
||||||
|
workers:
|
||||||
|
- "1.1.1.3"
|
||||||
|
- "1.1.1.4"
|
||||||
|
registry:
|
||||||
|
username: user
|
||||||
|
password: pw
|
||||||
|
builder:
|
||||||
|
arch: amd64
|
||||||
|
|
||||||
|
accessories:
|
||||||
|
mysql:
|
||||||
|
image: mysql:5.7
|
||||||
|
host: 1.1.1.5
|
||||||
|
port: 3306
|
||||||
|
env:
|
||||||
|
clear:
|
||||||
|
MYSQL_ROOT_HOST: '%'
|
||||||
|
secret:
|
||||||
|
- MYSQL_ROOT_PASSWORD
|
||||||
|
files:
|
||||||
|
- test/fixtures/files/my.cnf:/etc/mysql/my.cnf
|
||||||
|
directories:
|
||||||
|
- data:/var/lib/mysql
|
||||||
|
redis:
|
||||||
|
image: redis:latest
|
||||||
|
roles:
|
||||||
|
- web
|
||||||
|
port: 6379
|
||||||
|
directories:
|
||||||
|
- data:/data
|
||||||
|
|
||||||
|
readiness_delay: 0
|
||||||
29
test/fixtures/deploy_with_single_accessory.yml
vendored
Normal file
29
test/fixtures/deploy_with_single_accessory.yml
vendored
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
service: app
|
||||||
|
image: dhh/app
|
||||||
|
servers:
|
||||||
|
web:
|
||||||
|
- "1.1.1.1"
|
||||||
|
- "1.1.1.2"
|
||||||
|
workers:
|
||||||
|
- "1.1.1.3"
|
||||||
|
- "1.1.1.4"
|
||||||
|
registry:
|
||||||
|
username: user
|
||||||
|
password: pw
|
||||||
|
builder:
|
||||||
|
arch: amd64
|
||||||
|
|
||||||
|
accessories:
|
||||||
|
mysql:
|
||||||
|
image: mysql:5.7
|
||||||
|
host: 1.1.1.5
|
||||||
|
port: 3306
|
||||||
|
env:
|
||||||
|
clear:
|
||||||
|
MYSQL_ROOT_HOST: '%'
|
||||||
|
secret:
|
||||||
|
- MYSQL_ROOT_PASSWORD
|
||||||
|
files:
|
||||||
|
- test/fixtures/files/my.cnf:/etc/mysql/my.cnf
|
||||||
|
directories:
|
||||||
|
- data:/var/lib/mysql
|
||||||
Reference in New Issue
Block a user