kamal 2.6.1 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/lib/kamal/cli/accessory.rb +15 -2
 - data/lib/kamal/cli/app/ssl_certificates.rb +28 -0
 - data/lib/kamal/cli/app.rb +1 -0
 - data/lib/kamal/cli/build.rb +33 -15
 - data/lib/kamal/cli/main.rb +7 -2
 - data/lib/kamal/cli/port_forwarding.rb +42 -0
 - data/lib/kamal/cli/registry.rb +16 -8
 - data/lib/kamal/cli/templates/deploy.yml +4 -3
 - data/lib/kamal/cli/templates/sample_hooks/pre-deploy.sample +13 -1
 - data/lib/kamal/cli/templates/secrets +1 -1
 - data/lib/kamal/commander.rb +1 -1
 - data/lib/kamal/commands/accessory.rb +8 -3
 - data/lib/kamal/commands/app/execution.rb +2 -2
 - data/lib/kamal/commands/app/proxy.rb +4 -0
 - data/lib/kamal/commands/app.rb +4 -2
 - data/lib/kamal/commands/base.rb +8 -0
 - data/lib/kamal/commands/builder/base.rb +11 -1
 - data/lib/kamal/commands/builder/local.rb +15 -2
 - data/lib/kamal/commands/builder/pack.rb +46 -0
 - data/lib/kamal/commands/builder/remote.rb +9 -1
 - data/lib/kamal/commands/builder.rb +14 -2
 - data/lib/kamal/commands/registry.rb +22 -0
 - data/lib/kamal/configuration/accessory.rb +2 -1
 - data/lib/kamal/configuration/builder.rb +12 -0
 - data/lib/kamal/configuration/docs/builder.yml +13 -0
 - data/lib/kamal/configuration/docs/proxy.yml +39 -0
 - data/lib/kamal/configuration/proxy/boot.rb +8 -0
 - data/lib/kamal/configuration/proxy.rb +52 -4
 - data/lib/kamal/configuration/registry.rb +8 -0
 - data/lib/kamal/configuration/role.rb +5 -3
 - data/lib/kamal/configuration/validator/accessory.rb +2 -0
 - data/lib/kamal/configuration/validator/builder.rb +2 -0
 - data/lib/kamal/configuration/validator/proxy.rb +10 -0
 - data/lib/kamal/configuration/validator/registry.rb +5 -3
 - data/lib/kamal/configuration/validator/role.rb +1 -0
 - data/lib/kamal/configuration/validator.rb +14 -0
 - data/lib/kamal/configuration.rb +12 -3
 - data/lib/kamal/secrets/adapters/bitwarden_secrets_manager.rb +10 -16
 - data/lib/kamal/secrets/adapters/one_password.rb +45 -11
 - data/lib/kamal/secrets/adapters/passbolt.rb +130 -0
 - data/lib/kamal/version.rb +1 -1
 - metadata +6 -2
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 80ba6d51041312c99d659a1bfaac13bfa0ed7d1e758bde65e5475c0e51d88238
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: f0cc94a905da2cfb5dcf4f5d9ead2194df1b0ed46fd3b8671a59bfc333b10fbf
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: e33ddb40f46e587364d9121bbd2f2d829beddeb956f4bf1d8399e5ac835285180914f51e1365bee96ec4b82a02c0e88df8ff513a68bf95e44a8dc7e0ce081509
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 8a0b1a90bbacd96d072cbbe5cec3371e5f7fe6d213cfa5dac3203f6d4ef02fadbddd1e3458909f3051adcd9218d69d6edb5b193f86fca6fac28b49b00bd2dd91
         
     | 
    
        data/lib/kamal/cli/accessory.rb
    CHANGED
    
    | 
         @@ -24,11 +24,11 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base 
     | 
|
| 
       24 
24 
     | 
    
         
             
                      directories(name)
         
     | 
| 
       25 
25 
     | 
    
         
             
                      upload(name)
         
     | 
| 
       26 
26 
     | 
    
         | 
| 
       27 
     | 
    
         
            -
                      on(hosts) do
         
     | 
| 
      
 27 
     | 
    
         
            +
                      on(hosts) do |host|
         
     | 
| 
       28 
28 
     | 
    
         
             
                        execute *KAMAL.auditor.record("Booted #{name} accessory"), verbosity: :debug
         
     | 
| 
       29 
29 
     | 
    
         
             
                        execute *accessory.ensure_env_directory
         
     | 
| 
       30 
30 
     | 
    
         
             
                        upload! accessory.secrets_io, accessory.secrets_path, mode: "0600"
         
     | 
| 
       31 
     | 
    
         
            -
                        execute *accessory.run
         
     | 
| 
      
 31 
     | 
    
         
            +
                        execute *accessory.run(host: host)
         
     | 
| 
       32 
32 
     | 
    
         | 
| 
       33 
33 
     | 
    
         
             
                        if accessory.running_proxy?
         
     | 
| 
       34 
34 
     | 
    
         
             
                          target = capture_with_info(*accessory.container_id_for(container_name: accessory.service_name, only_running: true)).strip
         
     | 
| 
         @@ -77,6 +77,7 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base 
     | 
|
| 
       77 
77 
     | 
    
         
             
                    KAMAL.accessory_names.each { |accessory_name| reboot(accessory_name) }
         
     | 
| 
       78 
78 
     | 
    
         
             
                  else
         
     | 
| 
       79 
79 
     | 
    
         
             
                    prepare(name)
         
     | 
| 
      
 80 
     | 
    
         
            +
                    pull_image(name)
         
     | 
| 
       80 
81 
     | 
    
         
             
                    stop(name)
         
     | 
| 
       81 
82 
     | 
    
         
             
                    remove_container(name)
         
     | 
| 
       82 
83 
     | 
    
         
             
                    boot(name, prepare: false)
         
     | 
| 
         @@ -203,6 +204,18 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base 
     | 
|
| 
       203 
204 
     | 
    
         
             
                end
         
     | 
| 
       204 
205 
     | 
    
         
             
              end
         
     | 
| 
       205 
206 
     | 
    
         | 
| 
      
 207 
     | 
    
         
            +
              desc "pull_image [NAME]", "Pull accessory image on host", hide: true
         
     | 
| 
      
 208 
     | 
    
         
            +
              def pull_image(name)
         
     | 
| 
      
 209 
     | 
    
         
            +
                with_lock do
         
     | 
| 
      
 210 
     | 
    
         
            +
                  with_accessory(name) do |accessory, hosts|
         
     | 
| 
      
 211 
     | 
    
         
            +
                    on(hosts) do
         
     | 
| 
      
 212 
     | 
    
         
            +
                      execute *KAMAL.auditor.record("Pull #{name} accessory image"), verbosity: :debug
         
     | 
| 
      
 213 
     | 
    
         
            +
                      execute *accessory.pull_image
         
     | 
| 
      
 214 
     | 
    
         
            +
                    end
         
     | 
| 
      
 215 
     | 
    
         
            +
                  end
         
     | 
| 
      
 216 
     | 
    
         
            +
                end
         
     | 
| 
      
 217 
     | 
    
         
            +
              end
         
     | 
| 
      
 218 
     | 
    
         
            +
             
     | 
| 
       206 
219 
     | 
    
         
             
              desc "remove [NAME]", "Remove accessory container, image and data directory from host (use NAME=all to remove all accessories)"
         
     | 
| 
       207 
220 
     | 
    
         
             
              option :confirmed, aliases: "-y", type: :boolean, default: false, desc: "Proceed without confirmation question"
         
     | 
| 
       208 
221 
     | 
    
         
             
              def remove(name)
         
     | 
| 
         @@ -0,0 +1,28 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Kamal::Cli::App::SslCertificates
         
     | 
| 
      
 2 
     | 
    
         
            +
              attr_reader :host, :role, :sshkit
         
     | 
| 
      
 3 
     | 
    
         
            +
              delegate :execute, :info, :upload!, to: :sshkit
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              def initialize(host, role, sshkit)
         
     | 
| 
      
 6 
     | 
    
         
            +
                @host = host
         
     | 
| 
      
 7 
     | 
    
         
            +
                @role = role
         
     | 
| 
      
 8 
     | 
    
         
            +
                @sshkit = sshkit
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              def run
         
     | 
| 
      
 12 
     | 
    
         
            +
                if role.running_proxy? && role.proxy.custom_ssl_certificate?
         
     | 
| 
      
 13 
     | 
    
         
            +
                  info "Writing SSL certificates for #{role.name} on #{host}"
         
     | 
| 
      
 14 
     | 
    
         
            +
                  execute *app.create_ssl_directory
         
     | 
| 
      
 15 
     | 
    
         
            +
                  if cert_content = role.proxy.certificate_pem_content
         
     | 
| 
      
 16 
     | 
    
         
            +
                    upload!(StringIO.new(cert_content), role.proxy.host_tls_cert, mode: "0644")
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
                  if key_content = role.proxy.private_key_pem_content
         
     | 
| 
      
 19 
     | 
    
         
            +
                    upload!(StringIO.new(key_content), role.proxy.host_tls_key, mode: "0644")
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
              private
         
     | 
| 
      
 25 
     | 
    
         
            +
                def app
         
     | 
| 
      
 26 
     | 
    
         
            +
                  @app ||= KAMAL.app(role: role, host: host)
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/kamal/cli/app.rb
    CHANGED
    
    
    
        data/lib/kamal/cli/build.rb
    CHANGED
    
    | 
         @@ -11,6 +11,7 @@ class Kamal::Cli::Build < Kamal::Cli::Base 
     | 
|
| 
       11 
11 
     | 
    
         | 
| 
       12 
12 
     | 
    
         
             
              desc "push", "Build and push app image to registry"
         
     | 
| 
       13 
13 
     | 
    
         
             
              option :output, type: :string, default: "registry", banner: "export_type", desc: "Exported type for the build result, and may be any exported type supported by 'buildx --output'."
         
     | 
| 
      
 14 
     | 
    
         
            +
              option :no_cache, type: :boolean, default: false, desc: "Build without using Docker's build cache"
         
     | 
| 
       14 
15 
     | 
    
         
             
              def push
         
     | 
| 
       15 
16 
     | 
    
         
             
                cli = self
         
     | 
| 
       16 
17 
     | 
    
         | 
| 
         @@ -19,7 +20,7 @@ class Kamal::Cli::Build < Kamal::Cli::Base 
     | 
|
| 
       19 
20 
     | 
    
         
             
                pre_connect_if_required
         
     | 
| 
       20 
21 
     | 
    
         | 
| 
       21 
22 
     | 
    
         
             
                ensure_docker_installed
         
     | 
| 
       22 
     | 
    
         
            -
                login_to_registry_locally
         
     | 
| 
      
 23 
     | 
    
         
            +
                login_to_registry_locally if KAMAL.builder.login_to_registry_locally?
         
     | 
| 
       23 
24 
     | 
    
         | 
| 
       24 
25 
     | 
    
         
             
                run_hook "pre-build"
         
     | 
| 
       25 
26 
     | 
    
         | 
| 
         @@ -56,10 +57,10 @@ class Kamal::Cli::Build < Kamal::Cli::Base 
     | 
|
| 
       56 
57 
     | 
    
         
             
                    end
         
     | 
| 
       57 
58 
     | 
    
         | 
| 
       58 
59 
     | 
    
         
             
                    # Get the command here to ensure the Dir.chdir doesn't interfere with it
         
     | 
| 
       59 
     | 
    
         
            -
                    push = KAMAL.builder.push(cli.options[:output])
         
     | 
| 
      
 60 
     | 
    
         
            +
                    push = KAMAL.builder.push(cli.options[:output], no_cache: cli.options[:no_cache])
         
     | 
| 
       60 
61 
     | 
    
         | 
| 
       61 
62 
     | 
    
         
             
                    KAMAL.with_verbosity(:debug) do
         
     | 
| 
       62 
     | 
    
         
            -
                      Dir.chdir(KAMAL.config.builder.build_directory) { execute *push }
         
     | 
| 
      
 63 
     | 
    
         
            +
                      Dir.chdir(KAMAL.config.builder.build_directory) { execute *push, env: KAMAL.builder.push_env }
         
     | 
| 
       63 
64 
     | 
    
         
             
                    end
         
     | 
| 
       64 
65 
     | 
    
         
             
                  end
         
     | 
| 
       65 
66 
     | 
    
         
             
                end
         
     | 
| 
         @@ -67,16 +68,18 @@ class Kamal::Cli::Build < Kamal::Cli::Base 
     | 
|
| 
       67 
68 
     | 
    
         | 
| 
       68 
69 
     | 
    
         
             
              desc "pull", "Pull app image from registry onto servers"
         
     | 
| 
       69 
70 
     | 
    
         
             
              def pull
         
     | 
| 
       70 
     | 
    
         
            -
                login_to_registry_remotely
         
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
       72 
     | 
    
         
            -
                 
     | 
| 
       73 
     | 
    
         
            -
                   
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
     | 
    
         
            -
             
     | 
| 
       76 
     | 
    
         
            -
             
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
       78 
     | 
    
         
            -
             
     | 
| 
       79 
     | 
    
         
            -
                   
     | 
| 
      
 71 
     | 
    
         
            +
                login_to_registry_remotely unless KAMAL.registry.local?
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                forward_local_registry_port do
         
     | 
| 
      
 74 
     | 
    
         
            +
                  if (first_hosts = mirror_hosts).any?
         
     | 
| 
      
 75 
     | 
    
         
            +
                    #  Pull on a single host per mirror first to seed them
         
     | 
| 
      
 76 
     | 
    
         
            +
                    say "Pulling image on #{first_hosts.join(", ")} to seed the #{"mirror".pluralize(first_hosts.count)}...", :magenta
         
     | 
| 
      
 77 
     | 
    
         
            +
                    pull_on_hosts(first_hosts)
         
     | 
| 
      
 78 
     | 
    
         
            +
                    say "Pulling image on remaining hosts...", :magenta
         
     | 
| 
      
 79 
     | 
    
         
            +
                    pull_on_hosts(KAMAL.app_hosts - first_hosts)
         
     | 
| 
      
 80 
     | 
    
         
            +
                  else
         
     | 
| 
      
 81 
     | 
    
         
            +
                    pull_on_hosts(KAMAL.app_hosts)
         
     | 
| 
      
 82 
     | 
    
         
            +
                  end
         
     | 
| 
       80 
83 
     | 
    
         
             
                end
         
     | 
| 
       81 
84 
     | 
    
         
             
              end
         
     | 
| 
       82 
85 
     | 
    
         | 
| 
         @@ -119,6 +122,7 @@ class Kamal::Cli::Build < Kamal::Cli::Base 
     | 
|
| 
       119 
122 
     | 
    
         | 
| 
       120 
123 
     | 
    
         
             
              desc "dev", "Build using the working directory, tag it as dirty, and push to local image store."
         
     | 
| 
       121 
124 
     | 
    
         
             
              option :output, type: :string, default: "docker", banner: "export_type", desc: "Exported type for the build result, and may be any exported type supported by 'buildx --output'."
         
     | 
| 
      
 125 
     | 
    
         
            +
              option :no_cache, type: :boolean, default: false, desc: "Build without using Docker's build cache"
         
     | 
| 
       122 
126 
     | 
    
         
             
              def dev
         
     | 
| 
       123 
127 
     | 
    
         
             
                cli = self
         
     | 
| 
       124 
128 
     | 
    
         | 
| 
         @@ -144,7 +148,7 @@ class Kamal::Cli::Build < Kamal::Cli::Base 
     | 
|
| 
       144 
148 
     | 
    
         | 
| 
       145 
149 
     | 
    
         
             
                with_env(KAMAL.config.builder.secrets) do
         
     | 
| 
       146 
150 
     | 
    
         
             
                  run_locally do
         
     | 
| 
       147 
     | 
    
         
            -
                    build = KAMAL.builder.push(cli.options[:output], tag_as_dirty: true)
         
     | 
| 
      
 151 
     | 
    
         
            +
                    build = KAMAL.builder.push(cli.options[:output], tag_as_dirty: true, no_cache: cli.options[:no_cache])
         
     | 
| 
       148 
152 
     | 
    
         
             
                    KAMAL.with_verbosity(:debug) do
         
     | 
| 
       149 
153 
     | 
    
         
             
                      execute(*build)
         
     | 
| 
       150 
154 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -192,7 +196,11 @@ class Kamal::Cli::Build < Kamal::Cli::Base 
     | 
|
| 
       192 
196 
     | 
    
         | 
| 
       193 
197 
     | 
    
         
             
                def login_to_registry_locally
         
     | 
| 
       194 
198 
     | 
    
         
             
                  run_locally do
         
     | 
| 
       195 
     | 
    
         
            -
                     
     | 
| 
      
 199 
     | 
    
         
            +
                    if KAMAL.registry.local?
         
     | 
| 
      
 200 
     | 
    
         
            +
                      execute *KAMAL.registry.setup
         
     | 
| 
      
 201 
     | 
    
         
            +
                    else
         
     | 
| 
      
 202 
     | 
    
         
            +
                      execute *KAMAL.registry.login
         
     | 
| 
      
 203 
     | 
    
         
            +
                    end
         
     | 
| 
       196 
204 
     | 
    
         
             
                  end
         
     | 
| 
       197 
205 
     | 
    
         
             
                end
         
     | 
| 
       198 
206 
     | 
    
         | 
| 
         @@ -201,4 +209,14 @@ class Kamal::Cli::Build < Kamal::Cli::Base 
     | 
|
| 
       201 
209 
     | 
    
         
             
                    execute *KAMAL.registry.login
         
     | 
| 
       202 
210 
     | 
    
         
             
                  end
         
     | 
| 
       203 
211 
     | 
    
         
             
                end
         
     | 
| 
      
 212 
     | 
    
         
            +
             
     | 
| 
      
 213 
     | 
    
         
            +
                def forward_local_registry_port(&block)
         
     | 
| 
      
 214 
     | 
    
         
            +
                  if KAMAL.config.registry.local?
         
     | 
| 
      
 215 
     | 
    
         
            +
                    Kamal::Cli::PortForwarding.
         
     | 
| 
      
 216 
     | 
    
         
            +
                      new(KAMAL.hosts, KAMAL.config.registry.local_port).
         
     | 
| 
      
 217 
     | 
    
         
            +
                      forward(&block)
         
     | 
| 
      
 218 
     | 
    
         
            +
                  else
         
     | 
| 
      
 219 
     | 
    
         
            +
                    yield
         
     | 
| 
      
 220 
     | 
    
         
            +
                  end
         
     | 
| 
      
 221 
     | 
    
         
            +
                end
         
     | 
| 
       204 
222 
     | 
    
         
             
            end
         
     | 
    
        data/lib/kamal/cli/main.rb
    CHANGED
    
    | 
         @@ -1,6 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            class Kamal::Cli::Main < Kamal::Cli::Base
         
     | 
| 
       2 
2 
     | 
    
         
             
              desc "setup", "Setup all accessories, push the env, and deploy app to servers"
         
     | 
| 
       3 
3 
     | 
    
         
             
              option :skip_push, aliases: "-P", type: :boolean, default: false, desc: "Skip image build and push"
         
     | 
| 
      
 4 
     | 
    
         
            +
              option :no_cache, type: :boolean, default: false, desc: "Build without using Docker's build cache"
         
     | 
| 
       4 
5 
     | 
    
         
             
              def setup
         
     | 
| 
       5 
6 
     | 
    
         
             
                print_runtime do
         
     | 
| 
       6 
7 
     | 
    
         
             
                  with_lock do
         
     | 
| 
         @@ -16,6 +17,7 @@ class Kamal::Cli::Main < Kamal::Cli::Base 
     | 
|
| 
       16 
17 
     | 
    
         | 
| 
       17 
18 
     | 
    
         
             
              desc "deploy", "Deploy app to servers"
         
     | 
| 
       18 
19 
     | 
    
         
             
              option :skip_push, aliases: "-P", type: :boolean, default: false, desc: "Skip image build and push"
         
     | 
| 
      
 20 
     | 
    
         
            +
              option :no_cache, type: :boolean, default: false, desc: "Build without using Docker's build cache"
         
     | 
| 
       19 
21 
     | 
    
         
             
              def deploy(boot_accessories: false)
         
     | 
| 
       20 
22 
     | 
    
         
             
                runtime = print_runtime do
         
     | 
| 
       21 
23 
     | 
    
         
             
                  invoke_options = deploy_options
         
     | 
| 
         @@ -51,6 +53,7 @@ class Kamal::Cli::Main < Kamal::Cli::Base 
     | 
|
| 
       51 
53 
     | 
    
         | 
| 
       52 
54 
     | 
    
         
             
              desc "redeploy", "Deploy app to servers without bootstrapping servers, starting kamal-proxy and pruning"
         
     | 
| 
       53 
55 
     | 
    
         
             
              option :skip_push, aliases: "-P", type: :boolean, default: false, desc: "Skip image build and push"
         
     | 
| 
      
 56 
     | 
    
         
            +
              option :no_cache, type: :boolean, default: false, desc: "Build without using Docker's build cache"
         
     | 
| 
       54 
57 
     | 
    
         
             
              def redeploy
         
     | 
| 
       55 
58 
     | 
    
         
             
                runtime = print_runtime do
         
     | 
| 
       56 
59 
     | 
    
         
             
                  invoke_options = deploy_options
         
     | 
| 
         @@ -182,7 +185,7 @@ class Kamal::Cli::Main < Kamal::Cli::Base 
     | 
|
| 
       182 
185 
     | 
    
         
             
                    invoke "kamal:cli:app:remove", [], options.without(:confirmed)
         
     | 
| 
       183 
186 
     | 
    
         
             
                    invoke "kamal:cli:proxy:remove", [], options.without(:confirmed)
         
     | 
| 
       184 
187 
     | 
    
         
             
                    invoke "kamal:cli:accessory:remove", [ "all" ], options
         
     | 
| 
       185 
     | 
    
         
            -
                    invoke "kamal:cli:registry: 
     | 
| 
      
 188 
     | 
    
         
            +
                    invoke "kamal:cli:registry:remove", [], options.without(:confirmed).merge(skip_local: true)
         
     | 
| 
       186 
189 
     | 
    
         
             
                  end
         
     | 
| 
       187 
190 
     | 
    
         
             
                end
         
     | 
| 
       188 
191 
     | 
    
         
             
              end
         
     | 
| 
         @@ -272,6 +275,8 @@ class Kamal::Cli::Main < Kamal::Cli::Base 
     | 
|
| 
       272 
275 
     | 
    
         
             
                end
         
     | 
| 
       273 
276 
     | 
    
         | 
| 
       274 
277 
     | 
    
         
             
                def deploy_options
         
     | 
| 
       275 
     | 
    
         
            -
                   
     | 
| 
      
 278 
     | 
    
         
            +
                  base_options = options.without("skip_push")
         
     | 
| 
      
 279 
     | 
    
         
            +
                  base_options = base_options.except("no_cache") unless base_options["no_cache"]
         
     | 
| 
      
 280 
     | 
    
         
            +
                  { "version" => KAMAL.config.version }.merge(base_options)
         
     | 
| 
       276 
281 
     | 
    
         
             
                end
         
     | 
| 
       277 
282 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,42 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Kamal::Cli::PortForwarding
         
     | 
| 
      
 2 
     | 
    
         
            +
              attr_reader :hosts, :port
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
              def initialize(hosts, port)
         
     | 
| 
      
 5 
     | 
    
         
            +
                @hosts = hosts
         
     | 
| 
      
 6 
     | 
    
         
            +
                @port = port
         
     | 
| 
      
 7 
     | 
    
         
            +
              end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              def forward
         
     | 
| 
      
 10 
     | 
    
         
            +
                @done = false
         
     | 
| 
      
 11 
     | 
    
         
            +
                forward_ports
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                yield
         
     | 
| 
      
 14 
     | 
    
         
            +
              ensure
         
     | 
| 
      
 15 
     | 
    
         
            +
                stop
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              private
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
              def stop
         
     | 
| 
      
 21 
     | 
    
         
            +
                @done = true
         
     | 
| 
      
 22 
     | 
    
         
            +
                @threads.to_a.each(&:join)
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
              def forward_ports
         
     | 
| 
      
 26 
     | 
    
         
            +
                @threads = hosts.map do |host|
         
     | 
| 
      
 27 
     | 
    
         
            +
                  Thread.new do
         
     | 
| 
      
 28 
     | 
    
         
            +
                    Net::SSH.start(host, KAMAL.config.ssh.user, **{ proxy: KAMAL.config.ssh.proxy }.compact) do |ssh|
         
     | 
| 
      
 29 
     | 
    
         
            +
                      ssh.forward.remote(port, "localhost", port, "localhost")
         
     | 
| 
      
 30 
     | 
    
         
            +
                      ssh.loop(0.1) do
         
     | 
| 
      
 31 
     | 
    
         
            +
                        if @done
         
     | 
| 
      
 32 
     | 
    
         
            +
                          ssh.forward.cancel_remote(port, "localhost")
         
     | 
| 
      
 33 
     | 
    
         
            +
                          break
         
     | 
| 
      
 34 
     | 
    
         
            +
                        else
         
     | 
| 
      
 35 
     | 
    
         
            +
                          true
         
     | 
| 
      
 36 
     | 
    
         
            +
                        end
         
     | 
| 
      
 37 
     | 
    
         
            +
                      end
         
     | 
| 
      
 38 
     | 
    
         
            +
                    end
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
                end
         
     | 
| 
      
 41 
     | 
    
         
            +
              end
         
     | 
| 
      
 42 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/kamal/cli/registry.rb
    CHANGED
    
    | 
         @@ -1,19 +1,27 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            class Kamal::Cli::Registry < Kamal::Cli::Base
         
     | 
| 
       2 
     | 
    
         
            -
              desc " 
     | 
| 
      
 2 
     | 
    
         
            +
              desc "setup", "Setup local registry or log in to remote registry locally and remotely"
         
     | 
| 
       3 
3 
     | 
    
         
             
              option :skip_local, aliases: "-L", type: :boolean, default: false, desc: "Skip local login"
         
     | 
| 
       4 
4 
     | 
    
         
             
              option :skip_remote, aliases: "-R", type: :boolean, default: false, desc: "Skip remote login"
         
     | 
| 
       5 
     | 
    
         
            -
              def  
     | 
| 
      
 5 
     | 
    
         
            +
              def setup
         
     | 
| 
       6 
6 
     | 
    
         
             
                ensure_docker_installed unless options[:skip_local]
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
                 
     | 
| 
       9 
     | 
    
         
            -
                 
     | 
| 
      
 8 
     | 
    
         
            +
                if KAMAL.registry.local?
         
     | 
| 
      
 9 
     | 
    
         
            +
                  run_locally    { execute *KAMAL.registry.setup } unless options[:skip_local]
         
     | 
| 
      
 10 
     | 
    
         
            +
                else
         
     | 
| 
      
 11 
     | 
    
         
            +
                  run_locally    { execute *KAMAL.registry.login } unless options[:skip_local]
         
     | 
| 
      
 12 
     | 
    
         
            +
                  on(KAMAL.hosts) { execute *KAMAL.registry.login } unless options[:skip_remote]
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
       10 
14 
     | 
    
         
             
              end
         
     | 
| 
       11 
15 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
              desc " 
     | 
| 
      
 16 
     | 
    
         
            +
              desc "remove", "Remove local registry or log out of remote registry locally and remotely"
         
     | 
| 
       13 
17 
     | 
    
         
             
              option :skip_local, aliases: "-L", type: :boolean, default: false, desc: "Skip local login"
         
     | 
| 
       14 
18 
     | 
    
         
             
              option :skip_remote, aliases: "-R", type: :boolean, default: false, desc: "Skip remote login"
         
     | 
| 
       15 
     | 
    
         
            -
              def  
     | 
| 
       16 
     | 
    
         
            -
                 
     | 
| 
       17 
     | 
    
         
            -
                 
     | 
| 
      
 19 
     | 
    
         
            +
              def remove
         
     | 
| 
      
 20 
     | 
    
         
            +
                if KAMAL.registry.local?
         
     | 
| 
      
 21 
     | 
    
         
            +
                  run_locally    { execute *KAMAL.registry.remove, raise_on_non_zero_exit: false } unless options[:skip_local]
         
     | 
| 
      
 22 
     | 
    
         
            +
                else
         
     | 
| 
      
 23 
     | 
    
         
            +
                  run_locally    { execute *KAMAL.registry.logout } unless options[:skip_local]
         
     | 
| 
      
 24 
     | 
    
         
            +
                  on(KAMAL.hosts) { execute *KAMAL.registry.logout } unless options[:skip_remote]
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
       18 
26 
     | 
    
         
             
              end
         
     | 
| 
       19 
27 
     | 
    
         
             
            end
         
     | 
| 
         @@ -25,13 +25,14 @@ proxy: 
     | 
|
| 
       25 
25 
     | 
    
         | 
| 
       26 
26 
     | 
    
         
             
            # Credentials for your image host.
         
     | 
| 
       27 
27 
     | 
    
         
             
            registry:
         
     | 
| 
      
 28 
     | 
    
         
            +
              server: localhost:5555
         
     | 
| 
       28 
29 
     | 
    
         
             
              # Specify the registry server, if you're not using Docker Hub
         
     | 
| 
       29 
30 
     | 
    
         
             
              # server: registry.digitalocean.com / ghcr.io / ...
         
     | 
| 
       30 
     | 
    
         
            -
              username: my-user
         
     | 
| 
      
 31 
     | 
    
         
            +
              # username: my-user
         
     | 
| 
       31 
32 
     | 
    
         | 
| 
       32 
33 
     | 
    
         
             
              # Always use an access token rather than real password (pulled from .kamal/secrets).
         
     | 
| 
       33 
     | 
    
         
            -
              password:
         
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
      
 34 
     | 
    
         
            +
              # password:
         
     | 
| 
      
 35 
     | 
    
         
            +
              #   - KAMAL_REGISTRY_PASSWORD
         
     | 
| 
       35 
36 
     | 
    
         | 
| 
       36 
37 
     | 
    
         
             
            # Configure builder setup.
         
     | 
| 
       37 
38 
     | 
    
         
             
            builder:
         
     | 
| 
         @@ -43,7 +43,7 @@ class GithubStatusChecks 
     | 
|
| 
       43 
43 
     | 
    
         
             
              attr_reader :remote_url, :git_sha, :github_client, :combined_status
         
     | 
| 
       44 
44 
     | 
    
         | 
| 
       45 
45 
     | 
    
         
             
              def initialize
         
     | 
| 
       46 
     | 
    
         
            -
                @remote_url =  
     | 
| 
      
 46 
     | 
    
         
            +
                @remote_url = github_repo_from_remote_url
         
     | 
| 
       47 
47 
     | 
    
         
             
                @git_sha = `git rev-parse HEAD`.strip
         
     | 
| 
       48 
48 
     | 
    
         
             
                @github_client = Octokit::Client.new(access_token: ENV["GITHUB_TOKEN"])
         
     | 
| 
       49 
49 
     | 
    
         
             
                refresh!
         
     | 
| 
         @@ -77,6 +77,18 @@ class GithubStatusChecks 
     | 
|
| 
       77 
77 
     | 
    
         
             
                  "Build not started..."
         
     | 
| 
       78 
78 
     | 
    
         
             
                end
         
     | 
| 
       79 
79 
     | 
    
         
             
              end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
              private
         
     | 
| 
      
 82 
     | 
    
         
            +
                def github_repo_from_remote_url
         
     | 
| 
      
 83 
     | 
    
         
            +
                  url = `git config --get remote.origin.url`.strip.delete_suffix(".git")
         
     | 
| 
      
 84 
     | 
    
         
            +
                  if url.start_with?("https://github.com/")
         
     | 
| 
      
 85 
     | 
    
         
            +
                    url.delete_prefix("https://github.com/")
         
     | 
| 
      
 86 
     | 
    
         
            +
                  elsif url.start_with?("git@github.com:")
         
     | 
| 
      
 87 
     | 
    
         
            +
                    url.delete_prefix("git@github.com:")
         
     | 
| 
      
 88 
     | 
    
         
            +
                  else
         
     | 
| 
      
 89 
     | 
    
         
            +
                    url
         
     | 
| 
      
 90 
     | 
    
         
            +
                  end
         
     | 
| 
      
 91 
     | 
    
         
            +
                end
         
     | 
| 
       80 
92 
     | 
    
         
             
            end
         
     | 
| 
       81 
93 
     | 
    
         | 
| 
       82 
94 
     | 
    
         | 
| 
         @@ -3,7 +3,7 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            # password manager, ENV, or a file. DO NOT ENTER RAW CREDENTIALS HERE! This file needs to be safe for git.
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
            # Option 1: Read secrets from the environment
         
     | 
| 
       6 
     | 
    
         
            -
            KAMAL_REGISTRY_PASSWORD=$KAMAL_REGISTRY_PASSWORD
         
     | 
| 
      
 6 
     | 
    
         
            +
            # KAMAL_REGISTRY_PASSWORD=$KAMAL_REGISTRY_PASSWORD
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
8 
     | 
    
         
             
            # Option 2: Read secrets via a command
         
     | 
| 
       9 
9 
     | 
    
         
             
            # RAILS_MASTER_KEY=$(cat config/master.key)
         
     | 
    
        data/lib/kamal/commander.rb
    CHANGED
    
    | 
         @@ -21,7 +21,7 @@ class Kamal::Commander 
     | 
|
| 
       21 
21 
     | 
    
         
             
              end
         
     | 
| 
       22 
22 
     | 
    
         | 
| 
       23 
23 
     | 
    
         
             
              def config
         
     | 
| 
       24 
     | 
    
         
            -
                @config ||= Kamal::Configuration.create_from(**@config_kwargs).tap do |config|
         
     | 
| 
      
 24 
     | 
    
         
            +
                @config ||= Kamal::Configuration.create_from(**@config_kwargs.to_h).tap do |config|
         
     | 
| 
       25 
25 
     | 
    
         
             
                  @config_kwargs = nil
         
     | 
| 
       26 
26 
     | 
    
         
             
                  configure_sshkit_with(config)
         
     | 
| 
       27 
27 
     | 
    
         
             
                end
         
     | 
| 
         @@ -12,7 +12,7 @@ class Kamal::Commands::Accessory < Kamal::Commands::Base 
     | 
|
| 
       12 
12 
     | 
    
         
             
                @accessory_config = config.accessory(name)
         
     | 
| 
       13 
13 
     | 
    
         
             
              end
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
       15 
     | 
    
         
            -
              def run
         
     | 
| 
      
 15 
     | 
    
         
            +
              def run(host: nil)
         
     | 
| 
       16 
16 
     | 
    
         
             
                docker :run,
         
     | 
| 
       17 
17 
     | 
    
         
             
                  "--name", service_name,
         
     | 
| 
       18 
18 
     | 
    
         
             
                  "--detach",
         
     | 
| 
         @@ -20,6 +20,7 @@ class Kamal::Commands::Accessory < Kamal::Commands::Base 
     | 
|
| 
       20 
20 
     | 
    
         
             
                  *network_args,
         
     | 
| 
       21 
21 
     | 
    
         
             
                  *config.logging_args,
         
     | 
| 
       22 
22 
     | 
    
         
             
                  *publish_args,
         
     | 
| 
      
 23 
     | 
    
         
            +
                  *([ "--env", "KAMAL_HOST=\"#{host}\"" ] if host),
         
     | 
| 
       23 
24 
     | 
    
         
             
                  *env_args,
         
     | 
| 
       24 
25 
     | 
    
         
             
                  *volume_args,
         
     | 
| 
       25 
26 
     | 
    
         
             
                  *label_args,
         
     | 
| 
         @@ -55,14 +56,14 @@ class Kamal::Commands::Accessory < Kamal::Commands::Base 
     | 
|
| 
       55 
56 
     | 
    
         | 
| 
       56 
57 
     | 
    
         
             
              def execute_in_existing_container(*command, interactive: false)
         
     | 
| 
       57 
58 
     | 
    
         
             
                docker :exec,
         
     | 
| 
       58 
     | 
    
         
            -
                  ( 
     | 
| 
      
 59 
     | 
    
         
            +
                  (docker_interactive_args if interactive),
         
     | 
| 
       59 
60 
     | 
    
         
             
                  service_name,
         
     | 
| 
       60 
61 
     | 
    
         
             
                  *command
         
     | 
| 
       61 
62 
     | 
    
         
             
              end
         
     | 
| 
       62 
63 
     | 
    
         | 
| 
       63 
64 
     | 
    
         
             
              def execute_in_new_container(*command, interactive: false)
         
     | 
| 
       64 
65 
     | 
    
         
             
                docker :run,
         
     | 
| 
       65 
     | 
    
         
            -
                  ( 
     | 
| 
      
 66 
     | 
    
         
            +
                  (docker_interactive_args if interactive),
         
     | 
| 
       66 
67 
     | 
    
         
             
                  "--rm",
         
     | 
| 
       67 
68 
     | 
    
         
             
                  *network_args,
         
     | 
| 
       68 
69 
     | 
    
         
             
                  *env_args,
         
     | 
| 
         @@ -89,6 +90,10 @@ class Kamal::Commands::Accessory < Kamal::Commands::Base 
     | 
|
| 
       89 
90 
     | 
    
         
             
                end
         
     | 
| 
       90 
91 
     | 
    
         
             
              end
         
     | 
| 
       91 
92 
     | 
    
         | 
| 
      
 93 
     | 
    
         
            +
              def pull_image
         
     | 
| 
      
 94 
     | 
    
         
            +
                docker :image, :pull, image
         
     | 
| 
      
 95 
     | 
    
         
            +
              end
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
       92 
97 
     | 
    
         
             
              def remove_service_directory
         
     | 
| 
       93 
98 
     | 
    
         
             
                [ :rm, "-rf", service_name ]
         
     | 
| 
       94 
99 
     | 
    
         
             
              end
         
     | 
| 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module Kamal::Commands::App::Execution
         
     | 
| 
       2 
2 
     | 
    
         
             
              def execute_in_existing_container(*command, interactive: false, env:)
         
     | 
| 
       3 
3 
     | 
    
         
             
                docker :exec,
         
     | 
| 
       4 
     | 
    
         
            -
                  ( 
     | 
| 
      
 4 
     | 
    
         
            +
                  (docker_interactive_args if interactive),
         
     | 
| 
       5 
5 
     | 
    
         
             
                  *argumentize("--env", env),
         
     | 
| 
       6 
6 
     | 
    
         
             
                  container_name,
         
     | 
| 
       7 
7 
     | 
    
         
             
                  *command
         
     | 
| 
         @@ -9,7 +9,7 @@ module Kamal::Commands::App::Execution 
     | 
|
| 
       9 
9 
     | 
    
         | 
| 
       10 
10 
     | 
    
         
             
              def execute_in_new_container(*command, interactive: false, detach: false, env:)
         
     | 
| 
       11 
11 
     | 
    
         
             
                docker :run,
         
     | 
| 
       12 
     | 
    
         
            -
                  ( 
     | 
| 
      
 12 
     | 
    
         
            +
                  (docker_interactive_args if interactive),
         
     | 
| 
       13 
13 
     | 
    
         
             
                  ("--detach" if detach),
         
     | 
| 
       14 
14 
     | 
    
         
             
                  ("--rm" unless detach),
         
     | 
| 
       15 
15 
     | 
    
         
             
                  "--network", "kamal",
         
     | 
| 
         @@ -21,6 +21,10 @@ module Kamal::Commands::App::Proxy 
     | 
|
| 
       21 
21 
     | 
    
         
             
                remove_directory config.proxy_boot.app_directory
         
     | 
| 
       22 
22 
     | 
    
         
             
              end
         
     | 
| 
       23 
23 
     | 
    
         | 
| 
      
 24 
     | 
    
         
            +
              def create_ssl_directory
         
     | 
| 
      
 25 
     | 
    
         
            +
                make_directory(File.join(config.proxy_boot.tls_directory, role.name))
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
       24 
28 
     | 
    
         
             
              private
         
     | 
| 
       25 
29 
     | 
    
         
             
                def proxy_exec(*command)
         
     | 
| 
       26 
30 
     | 
    
         
             
                  docker :exec, proxy_container_name, "kamal-proxy", *command
         
     | 
    
        data/lib/kamal/commands/app.rb
    CHANGED
    
    | 
         @@ -20,8 +20,10 @@ class Kamal::Commands::App < Kamal::Commands::Base 
     | 
|
| 
       20 
20 
     | 
    
         
             
                  "--name", container_name,
         
     | 
| 
       21 
21 
     | 
    
         
             
                  "--network", "kamal",
         
     | 
| 
       22 
22 
     | 
    
         
             
                  *([ "--hostname", hostname ] if hostname),
         
     | 
| 
       23 
     | 
    
         
            -
                  " 
     | 
| 
       24 
     | 
    
         
            -
                  " 
     | 
| 
      
 23 
     | 
    
         
            +
                  "--env", "KAMAL_CONTAINER_NAME=\"#{container_name}\"",
         
     | 
| 
      
 24 
     | 
    
         
            +
                  "--env", "KAMAL_VERSION=\"#{config.version}\"",
         
     | 
| 
      
 25 
     | 
    
         
            +
                  "--env", "KAMAL_HOST=\"#{host}\"",
         
     | 
| 
      
 26 
     | 
    
         
            +
                  "--env", "KAMAL_DESTINATION=\"#{config.destination}\"",
         
     | 
| 
       25 
27 
     | 
    
         
             
                  *role.env_args(host),
         
     | 
| 
       26 
28 
     | 
    
         
             
                  *role.logging_args,
         
     | 
| 
       27 
29 
     | 
    
         
             
                  *config.volume_args,
         
     | 
    
        data/lib/kamal/commands/base.rb
    CHANGED
    
    | 
         @@ -84,6 +84,10 @@ module Kamal::Commands 
     | 
|
| 
       84 
84 
     | 
    
         
             
                    args.compact.unshift :docker
         
     | 
| 
       85 
85 
     | 
    
         
             
                  end
         
     | 
| 
       86 
86 
     | 
    
         | 
| 
      
 87 
     | 
    
         
            +
                  def pack(*args)
         
     | 
| 
      
 88 
     | 
    
         
            +
                    args.compact.unshift :pack
         
     | 
| 
      
 89 
     | 
    
         
            +
                  end
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
       87 
91 
     | 
    
         
             
                  def git(*args, path: nil)
         
     | 
| 
       88 
92 
     | 
    
         
             
                    [ :git, *([ "-C", path ] if path), *args.compact ]
         
     | 
| 
       89 
93 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -122,5 +126,9 @@ module Kamal::Commands 
     | 
|
| 
       122 
126 
     | 
    
         
             
                  def ensure_local_buildx_installed
         
     | 
| 
       123 
127 
     | 
    
         
             
                    docker :buildx, "version"
         
     | 
| 
       124 
128 
     | 
    
         
             
                  end
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
                  def docker_interactive_args
         
     | 
| 
      
 131 
     | 
    
         
            +
                    STDIN.isatty ? "-it" : "-i"
         
     | 
| 
      
 132 
     | 
    
         
            +
                  end
         
     | 
| 
       125 
133 
     | 
    
         
             
              end
         
     | 
| 
       126 
134 
     | 
    
         
             
            end
         
     | 
| 
         @@ -6,6 +6,7 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base 
     | 
|
| 
       6 
6 
     | 
    
         
             
              delegate :argumentize, to: Kamal::Utils
         
     | 
| 
       7 
7 
     | 
    
         
             
              delegate \
         
     | 
| 
       8 
8 
     | 
    
         
             
                :args, :secrets, :dockerfile, :target, :arches, :local_arches, :remote_arches, :remote,
         
     | 
| 
      
 9 
     | 
    
         
            +
                :pack?, :pack_builder, :pack_buildpacks,
         
     | 
| 
       9 
10 
     | 
    
         
             
                :cache_from, :cache_to, :ssh, :provenance, :sbom, :driver, :docker_driver?,
         
     | 
| 
       10 
11 
     | 
    
         
             
                to: :builder_config
         
     | 
| 
       11 
12 
     | 
    
         | 
| 
         @@ -13,13 +14,14 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base 
     | 
|
| 
       13 
14 
     | 
    
         
             
                docker :image, :rm, "--force", config.absolute_image
         
     | 
| 
       14 
15 
     | 
    
         
             
              end
         
     | 
| 
       15 
16 
     | 
    
         | 
| 
       16 
     | 
    
         
            -
              def push(export_action = "registry", tag_as_dirty: false)
         
     | 
| 
      
 17 
     | 
    
         
            +
              def push(export_action = "registry", tag_as_dirty: false, no_cache: false)
         
     | 
| 
       17 
18 
     | 
    
         
             
                docker :buildx, :build,
         
     | 
| 
       18 
19 
     | 
    
         
             
                  "--output=type=#{export_action}",
         
     | 
| 
       19 
20 
     | 
    
         
             
                  *platform_options(arches),
         
     | 
| 
       20 
21 
     | 
    
         
             
                  *([ "--builder", builder_name ] unless docker_driver?),
         
     | 
| 
       21 
22 
     | 
    
         
             
                  *build_tag_options(tag_as_dirty: tag_as_dirty),
         
     | 
| 
       22 
23 
     | 
    
         
             
                  *build_options,
         
     | 
| 
      
 24 
     | 
    
         
            +
                  *([ "--no-cache" ] if no_cache),
         
     | 
| 
       23 
25 
     | 
    
         
             
                  build_context,
         
     | 
| 
       24 
26 
     | 
    
         
             
                  "2>&1"
         
     | 
| 
       25 
27 
     | 
    
         
             
              end
         
     | 
| 
         @@ -59,6 +61,14 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base 
     | 
|
| 
       59 
61 
     | 
    
         
             
                docker(:info, "--format '{{index .RegistryConfig.Mirrors 0}}'")
         
     | 
| 
       60 
62 
     | 
    
         
             
              end
         
     | 
| 
       61 
63 
     | 
    
         | 
| 
      
 64 
     | 
    
         
            +
              def login_to_registry_locally?
         
     | 
| 
      
 65 
     | 
    
         
            +
                true
         
     | 
| 
      
 66 
     | 
    
         
            +
              end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
              def push_env
         
     | 
| 
      
 69 
     | 
    
         
            +
                {}
         
     | 
| 
      
 70 
     | 
    
         
            +
              end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
       62 
72 
     | 
    
         
             
              private
         
     | 
| 
       63 
73 
     | 
    
         
             
                def build_tag_names(tag_as_dirty: false)
         
     | 
| 
       64 
74 
     | 
    
         
             
                  tag_names = [ config.absolute_image, config.latest_image ]
         
     | 
| 
         @@ -1,6 +1,15 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            class Kamal::Commands::Builder::Local < Kamal::Commands::Builder::Base
         
     | 
| 
       2 
2 
     | 
    
         
             
              def create
         
     | 
| 
       3 
     | 
    
         
            -
                 
     | 
| 
      
 3 
     | 
    
         
            +
                return if docker_driver?
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                options =
         
     | 
| 
      
 6 
     | 
    
         
            +
                  if KAMAL.registry.local?
         
     | 
| 
      
 7 
     | 
    
         
            +
                    "--driver=#{driver} --driver-opt network=host"
         
     | 
| 
      
 8 
     | 
    
         
            +
                  else
         
     | 
| 
      
 9 
     | 
    
         
            +
                    "--driver=#{driver}"
         
     | 
| 
      
 10 
     | 
    
         
            +
                  end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                docker :buildx, :create, "--name", builder_name, options
         
     | 
| 
       4 
13 
     | 
    
         
             
              end
         
     | 
| 
       5 
14 
     | 
    
         | 
| 
       6 
15 
     | 
    
         
             
              def remove
         
     | 
| 
         @@ -9,6 +18,10 @@ class Kamal::Commands::Builder::Local < Kamal::Commands::Builder::Base 
     | 
|
| 
       9 
18 
     | 
    
         | 
| 
       10 
19 
     | 
    
         
             
              private
         
     | 
| 
       11 
20 
     | 
    
         
             
                def builder_name
         
     | 
| 
       12 
     | 
    
         
            -
                   
     | 
| 
      
 21 
     | 
    
         
            +
                  if KAMAL.registry.local?
         
     | 
| 
      
 22 
     | 
    
         
            +
                    "kamal-local-registry-#{driver}"
         
     | 
| 
      
 23 
     | 
    
         
            +
                  else
         
     | 
| 
      
 24 
     | 
    
         
            +
                    "kamal-local-#{driver}"
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
       13 
26 
     | 
    
         
             
                end
         
     | 
| 
       14 
27 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,46 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Kamal::Commands::Builder::Pack < Kamal::Commands::Builder::Base
         
     | 
| 
      
 2 
     | 
    
         
            +
              def push(export_action = "registry", tag_as_dirty: false, no_cache: false)
         
     | 
| 
      
 3 
     | 
    
         
            +
                combine \
         
     | 
| 
      
 4 
     | 
    
         
            +
                  build(tag_as_dirty: tag_as_dirty, no_cache: no_cache),
         
     | 
| 
      
 5 
     | 
    
         
            +
                  export(export_action)
         
     | 
| 
      
 6 
     | 
    
         
            +
              end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              def remove;end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              def info
         
     | 
| 
      
 11 
     | 
    
         
            +
                pack :builder, :inspect, pack_builder
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
              alias_method :inspect_builder, :info
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              private
         
     | 
| 
      
 16 
     | 
    
         
            +
                def build(tag_as_dirty: false, no_cache: false)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  pack(:build,
         
     | 
| 
      
 18 
     | 
    
         
            +
                    config.repository,
         
     | 
| 
      
 19 
     | 
    
         
            +
                    "--platform", platform,
         
     | 
| 
      
 20 
     | 
    
         
            +
                    "--creation-time", "now",
         
     | 
| 
      
 21 
     | 
    
         
            +
                    "--builder", pack_builder,
         
     | 
| 
      
 22 
     | 
    
         
            +
                    buildpacks,
         
     | 
| 
      
 23 
     | 
    
         
            +
                    *build_tag_options(tag_as_dirty: tag_as_dirty),
         
     | 
| 
      
 24 
     | 
    
         
            +
                    *([ "--clear-cache" ] if no_cache),
         
     | 
| 
      
 25 
     | 
    
         
            +
                    "--env", "BP_IMAGE_LABELS=service=#{config.service}",
         
     | 
| 
      
 26 
     | 
    
         
            +
                    *argumentize("--env", args),
         
     | 
| 
      
 27 
     | 
    
         
            +
                    *argumentize("--env", secrets, sensitive: true),
         
     | 
| 
      
 28 
     | 
    
         
            +
                    "--path", build_context)
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                def export(export_action)
         
     | 
| 
      
 32 
     | 
    
         
            +
                  return unless export_action == "registry"
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                  combine \
         
     | 
| 
      
 35 
     | 
    
         
            +
                    docker(:push, config.absolute_image),
         
     | 
| 
      
 36 
     | 
    
         
            +
                    docker(:push, config.latest_image)
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                def platform
         
     | 
| 
      
 40 
     | 
    
         
            +
                  "linux/#{local_arches.first}"
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                def buildpacks
         
     | 
| 
      
 44 
     | 
    
         
            +
                  (pack_buildpacks << "paketo-buildpacks/image-labels").map { |buildpack| [ "--buildpack", buildpack ] }
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -19,11 +19,19 @@ class Kamal::Commands::Builder::Remote < Kamal::Commands::Builder::Base 
     | 
|
| 
       19 
19 
     | 
    
         | 
| 
       20 
20 
     | 
    
         
             
              def inspect_builder
         
     | 
| 
       21 
21 
     | 
    
         
             
                combine \
         
     | 
| 
       22 
     | 
    
         
            -
                  combine 
     | 
| 
      
 22 
     | 
    
         
            +
                  combine(inspect_buildx, inspect_remote_context),
         
     | 
| 
       23 
23 
     | 
    
         
             
                  [ "(echo no compatible builder && exit 1)" ],
         
     | 
| 
       24 
24 
     | 
    
         
             
                  by: "||"
         
     | 
| 
       25 
25 
     | 
    
         
             
              end
         
     | 
| 
       26 
26 
     | 
    
         | 
| 
      
 27 
     | 
    
         
            +
              def login_to_registry_locally?
         
     | 
| 
      
 28 
     | 
    
         
            +
                false
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
              def push_env
         
     | 
| 
      
 32 
     | 
    
         
            +
                { "BUILDKIT_NO_CLIENT_TOKEN" => "1" }
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
       27 
35 
     | 
    
         
             
              private
         
     | 
| 
       28 
36 
     | 
    
         
             
                def builder_name
         
     | 
| 
       29 
37 
     | 
    
         
             
                  "kamal-remote-#{remote.gsub(/[^a-z0-9_-]/, "-")}"
         
     | 
| 
         @@ -1,8 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require "active_support/core_ext/string/filters"
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            class Kamal::Commands::Builder < Kamal::Commands::Base
         
     | 
| 
       4 
     | 
    
         
            -
              delegate  
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
      
 4 
     | 
    
         
            +
              delegate \
         
     | 
| 
      
 5 
     | 
    
         
            +
                :create, :remove, :dev, :push, :clean, :pull, :info, :inspect_builder,
         
     | 
| 
      
 6 
     | 
    
         
            +
                :validate_image, :first_mirror, :login_to_registry_locally?, :push_env,
         
     | 
| 
      
 7 
     | 
    
         
            +
                to: :target
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              delegate \
         
     | 
| 
      
 10 
     | 
    
         
            +
                :local?, :remote?, :pack?, :cloud?,
         
     | 
| 
      
 11 
     | 
    
         
            +
                to: "config.builder"
         
     | 
| 
       6 
12 
     | 
    
         | 
| 
       7 
13 
     | 
    
         
             
              include Clone
         
     | 
| 
       8 
14 
     | 
    
         | 
| 
         @@ -17,6 +23,8 @@ class Kamal::Commands::Builder < Kamal::Commands::Base 
     | 
|
| 
       17 
23 
     | 
    
         
             
                  else
         
     | 
| 
       18 
24 
     | 
    
         
             
                    remote
         
     | 
| 
       19 
25 
     | 
    
         
             
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
                elsif pack?
         
     | 
| 
      
 27 
     | 
    
         
            +
                  pack
         
     | 
| 
       20 
28 
     | 
    
         
             
                elsif cloud?
         
     | 
| 
       21 
29 
     | 
    
         
             
                  cloud
         
     | 
| 
       22 
30 
     | 
    
         
             
                else
         
     | 
| 
         @@ -36,6 +44,10 @@ class Kamal::Commands::Builder < Kamal::Commands::Base 
     | 
|
| 
       36 
44 
     | 
    
         
             
                @hybrid ||= Kamal::Commands::Builder::Hybrid.new(config)
         
     | 
| 
       37 
45 
     | 
    
         
             
              end
         
     | 
| 
       38 
46 
     | 
    
         | 
| 
      
 47 
     | 
    
         
            +
              def pack
         
     | 
| 
      
 48 
     | 
    
         
            +
                @pack ||= Kamal::Commands::Builder::Pack.new(config)
         
     | 
| 
      
 49 
     | 
    
         
            +
              end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
       39 
51 
     | 
    
         
             
              def cloud
         
     | 
| 
       40 
52 
     | 
    
         
             
                @cloud ||= Kamal::Commands::Builder::Cloud.new(config)
         
     | 
| 
       41 
53 
     | 
    
         
             
              end
         
     |