Compare commits

..

16 Commits

Author SHA1 Message Date
Donal McBreen
d141c82efa Bump version for 1.9.3 2025-06-25 08:29:11 +01:00
Donal McBreen
cdb6c014ac Update Gemfile.lock 2025-06-25 08:04:44 +01:00
Donal McBreen
7ded6d3aef Use registry:3 image for the integration tests
v3 was recently released which broke the integration tests. Update them
to use the correct config file.

Set the major version to prevent this from happening when v4 is
released.
2025-06-25 08:04:44 +01:00
Donal McBreen
2ea60bea5e Merge pull request #1594 from basecamp/1-9-dotenv-precedence
Deploy env is authoritative (1-9-stable)
2025-06-25 07:55:12 +01:00
Jeremy Daer
3948a95e7a Fix local env vars overriding production env 2025-06-24 11:39:32 -07:00
Donal McBreen
21d7d6d79c Bump version for 1.9.2 2024-10-06 14:06:39 -04:00
Donal McBreen
f1b3c4a4fb Merge pull request #1063 from basecamp/safe-directory-fix-1.9
Safe directory fix 1.9
2024-10-06 18:55:56 +01:00
Ivan Velichko
fd9564f0c8 Relax the safe.directory requirement
Co-authored-by: Jeremy Daer <jeremydaer@gmail.com>
2024-10-06 13:44:23 -04:00
Ivan Velichko
d2338251a9 Fix git --add safe.directory command in Dockerfile
Upgrading kamal from `v1.8.3` to `v1.9.0` broke my [kamal playground](https://labs.iximiuz.com/playgrounds/kamal):

```
laborant@dev-machine:~/svc-a$ kamal setup
  INFO [34d0def6] Running /usr/bin/env mkdir -p .kamal on 172.16.0.3
  INFO [c34cf833] Running /usr/bin/env mkdir -p .kamal on 172.16.0.4
  INFO [34d0def6] Finished in 0.147 seconds with exit status 0 (successful).
  INFO [c34cf833] Finished in 0.204 seconds with exit status 0 (successful).
Acquiring the deploy lock...
Ensure Docker is installed...
  INFO [413ee426] Running docker -v on 172.16.0.4
  INFO [f1acacba] Running docker -v on 172.16.0.3
  INFO [413ee426] Finished in 0.036 seconds with exit status 0 (successful).
  INFO [f1acacba] Finished in 0.076 seconds with exit status 0 (successful).
Log into image registry...
  INFO [94cff492] Running docker login registry.iximiuz.com -u [REDACTED] -p [REDACTED] on localhost
  INFO [94cff492] Finished in 0.077 seconds with exit status 0 (successful).
  INFO [605c535f] Running docker login registry.iximiuz.com -u [REDACTED] -p [REDACTED] on 172.16.0.4
  INFO [6002b598] Running docker login registry.iximiuz.com -u [REDACTED] -p [REDACTED] on 172.16.0.3
  INFO [605c535f] Finished in 0.083 seconds with exit status 0 (successful).
  INFO [6002b598] Finished in 0.083 seconds with exit status 0 (successful).
Build and push app image...
  INFO [9d172b1e] Running docker --version && docker buildx version on localhost
  INFO [9d172b1e] Finished in 0.059 seconds with exit status 0 (successful).
  INFO Cloning repo into build directory `/tmp/kamal-clones/svc-a-2f65914456263/workdir/`...
  INFO [26fb1bd3] Running /usr/bin/env git -C /tmp/kamal-clones/svc-a-2f65914456263 clone /workdir --recurse-submodules on localhost
 ERROR Error preparing clone: Failed to clone repo: git exit status: 32768
git stdout: Nothing written
git stderr: Cloning into 'workdir'...
fatal: detected dubious ownership in repository at '/workdir/.git'
To add an exception for this directory, call:

        git config --global --add safe.directory /workdir/.git
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
, deleting and retrying...
  INFO Cloning repo into build directory `/tmp/kamal-clones/svc-a-2f65914456263/workdir/`...
  INFO [fd4aac0c] Running /usr/bin/env git -C /tmp/kamal-clones/svc-a-2f65914456263 clone /workdir --recurse-submodules on localhost
  Finished all in 0.3 seconds
Releasing the deploy lock...
  Finished all in 0.6 seconds
  ERROR (SSHKit::Command::Failed): git exit status: 32768
git stdout: Nothing written
git stderr: Cloning into 'workdir'...
fatal: detected dubious ownership in repository at '/workdir/.git'
To add an exception for this directory, call:

        git config --global --add safe.directory /workdir/.git
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

laborant@dev-machine:~/svc-a$ kamal version
2.0.0
```

I checked the [v1.8.3...v1.9.0](https://github.com/basecamp/kamal/compare/v1.8.3...v1.9.0) diff, and couldn't find anything even remotely related to the above error.

Then I checked the `git` versions in kamal `v1.8.3` and `v1.9.0` images:

```
docker run -it --rm --entrypoint sh ghcr.io/basecamp/kamal:v1.8.3 
/workdir # git --version
git version 2.38.5
```

vs.

```
docker run -it --rm --entrypoint sh ghcr.io/basecamp/kamal:v2.0.0 
/workdir # git --version
git version 2.39.5
```

Apparently, something changed in between `2.38.5` and `2.39.5` git releases (likely yet another CVE fix), and the `git config --global --add safe.directory /workdir` stopped working.

Here is the mitigation I currently use, but it's a bit awkward to do it:

```
docker build -t ghcr.io/basecamp/kamal:v2.0.0 - <<EOF
FROM ghcr.io/basecamp/kamal:v2.0.0

RUN git config --global --add safe.directory /workdir/.git
EOF
```

Hence, this PR.

To repro, you can start a [kamal playground](https://labs.iximiuz.com/playgrounds/kamal), then `docker pull ghcr.io/basecamp/kamal:v2.0.0` to override my patched image, and `cd svc-a && kamal setup`.
2024-10-06 13:44:12 -04:00
Donal McBreen
b00a4ec3e2 Merge pull request #1030 from basecamp/docker-not-latest
Do not tag 1.9.x Docker images as latest
2024-10-02 11:15:44 +01:00
Donal McBreen
4b09375ccd Exclude invalid Rails 8/Ruby 3.1 combination 2024-10-02 10:11:46 +01:00
Donal McBreen
3e0302230e Do not tag 1.9.x Docker images as latest
Only 2.x images should be set as latest.
2024-10-02 09:59:41 +01:00
Donal McBreen
bce2d35e9f Test 1-9-stable on push 2024-09-30 08:51:02 +01:00
Donal McBreen
46ea88a056 Bump version for 1.9.1 2024-09-30 08:49:47 +01:00
Donal McBreen
fa05270cac Merge pull request #997 from basecamp/traefik-2.11
Traefik 2.11 default to address CVE-2024-45410
2024-09-30 03:14:08 -04:00
Jeremy Daer
b058c45973 Traefik 2.11 default to address CVE-2024-45410
Fixes #968
2024-09-28 11:28:50 -04:00
17 changed files with 58 additions and 23 deletions

View File

@@ -3,7 +3,7 @@ on:
push:
branches:
- main
- 1-8-stable
- 1-9-stable
pull_request:
jobs:
rubocop:
@@ -31,6 +31,9 @@ jobs:
gemfile:
- Gemfile
- gemfiles/rails_edge.gemfile
exclude:
- ruby-version: "3.1"
gemfile: gemfiles/rails_edge.gemfile
name: ${{ format('Tests (Ruby {0})', matrix.ruby-version) }}
runs-on: ubuntu-latest
continue-on-error: true

View File

@@ -6,7 +6,7 @@ on:
tagInput:
description: 'Tag'
required: true
release:
types: [created]
tags:
@@ -51,5 +51,4 @@ jobs:
platforms: linux/amd64,linux/arm64
push: true
tags: |
ghcr.io/basecamp/kamal:latest
ghcr.io/basecamp/kamal:${{ steps.version-tag.outputs.value }}

View File

@@ -33,7 +33,7 @@ WORKDIR /workdir
# Tell git it's safe to access /workdir/.git even if
# the directory is owned by a different user
RUN git config --global --add safe.directory /workdir
RUN git config --global --add safe.directory '*'
# Set the entrypoint to run the installed binary in /workdir
# Example: docker run -it -v "$PWD:/workdir" kamal init

View File

@@ -1,7 +1,7 @@
PATH
remote: .
specs:
kamal (1.9.0)
kamal (1.9.3)
activesupport (>= 7.0)
base64 (~> 0.2)
bcrypt_pbkdf (~> 1.0)
@@ -78,11 +78,11 @@ GEM
net-sftp (4.0.0)
net-ssh (>= 5.0.0, < 8.0.0)
net-ssh (7.2.1)
nokogiri (1.16.0-arm64-darwin)
nokogiri (1.18.8-arm64-darwin)
racc (~> 1.4)
nokogiri (1.16.0-x86_64-darwin)
nokogiri (1.18.8-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.16.0-x86_64-linux)
nokogiri (1.18.8-x86_64-linux-gnu)
racc (~> 1.4)
parallel (1.24.0)
parser (3.3.0.5)

View File

@@ -37,9 +37,9 @@ module Kamal::Cli
def load_env
if destination = options[:destination]
Dotenv.load(".env.#{destination}", ".env")
Dotenv.overload(".env", ".env.#{destination}")
else
Dotenv.load(".env")
Dotenv.overload(".env")
end
end

View File

@@ -17,8 +17,8 @@ traefik:
# Image
#
# The Traefik image to use, defaults to `traefik:v2.10`
image: traefik:v2.9
# The Traefik image to use, defaults to `traefik:v2.11`
image: traefik:v2.11
# Host port
#

View File

@@ -1,5 +1,5 @@
class Kamal::Configuration::Traefik
DEFAULT_IMAGE = "traefik:v2.10"
DEFAULT_IMAGE = "traefik:v2.11"
CONTAINER_PORT = 80
DEFAULT_ARGS = {
"log.level" => "DEBUG"

View File

@@ -1,3 +1,3 @@
module Kamal
VERSION = "1.9.0"
VERSION = "1.9.3"
end

View File

@@ -490,6 +490,39 @@ class CliMainTest < CliTestCase
end
end
test "env files overwrite shell environment variables" do
ENV["TEST_VAR"] = "shell_value"
ENV["AWS_ACCESS_KEY_ID"] = "local_dev_key"
with_test_dotenv(".env": "TEST_VAR=dotenv_value\nAWS_ACCESS_KEY_ID=production_key") do
# Create a simple CLI command instance to trigger load_env
Kamal::Cli::Main.new.send(:load_env)
assert_equal "dotenv_value", ENV["TEST_VAR"]
assert_equal "production_key", ENV["AWS_ACCESS_KEY_ID"]
end
ensure
ENV.delete("TEST_VAR")
ENV.delete("AWS_ACCESS_KEY_ID")
end
test "destination env files overwrite base env files" do
ENV["TEST_VAR"] = "shell_value"
with_test_dotenv(".env": "TEST_VAR=base_value\nBASE_ONLY=base", ".env.world": "TEST_VAR=world_value\nWORLD_ONLY=world") do
# Create CLI command with destination to trigger load_env
Kamal::Cli::Main.new([], { destination: "world" }).send(:load_env)
assert_equal "world_value", ENV["TEST_VAR"]
assert_equal "base", ENV["BASE_ONLY"]
assert_equal "world", ENV["WORLD_ONLY"]
end
ensure
ENV.delete("TEST_VAR")
ENV.delete("BASE_ONLY")
ENV.delete("WORLD_ONLY")
end
test "remove with confirmation" do
run_command("remove", "-y", config_file: "deploy_with_accessories").tap do |output|
assert_match /docker container stop traefik/, output

View File

@@ -139,7 +139,7 @@ class CliTraefikTest < CliTestCase
assert_match "docker image prune --all --force --filter label=org.opencontainers.image.title=Traefik", output
assert_match "/usr/bin/env mkdir -p .kamal", output
assert_match "docker login -u [REDACTED] -p [REDACTED]", output
assert_match "docker container start traefik || docker run --name traefik --detach --restart unless-stopped --publish 80:80 --volume /var/run/docker.sock:/var/run/docker.sock --env-file .kamal/env/traefik/traefik.env --log-opt max-size=\"10m\" --label traefik.http.routers.catchall.entryPoints=\"http\" --label traefik.http.routers.catchall.rule=\"PathPrefix(\\`/\\`)\" --label traefik.http.routers.catchall.service=\"unavailable\" --label traefik.http.routers.catchall.priority=\"1\" --label traefik.http.services.unavailable.loadbalancer.server.port=\"0\" traefik:v2.10 --providers.docker --log.level=\"DEBUG\"", output
assert_match "docker container start traefik || docker run --name traefik --detach --restart unless-stopped --publish 80:80 --volume /var/run/docker.sock:/var/run/docker.sock --env-file .kamal/env/traefik/traefik.env --log-opt max-size=\"10m\" --label traefik.http.routers.catchall.entryPoints=\"http\" --label traefik.http.routers.catchall.rule=\"PathPrefix(\\`/\\`)\" --label traefik.http.routers.catchall.service=\"unavailable\" --label traefik.http.routers.catchall.priority=\"1\" --label traefik.http.services.unavailable.loadbalancer.server.port=\"0\" traefik:v2.11 --providers.docker --log.level=\"DEBUG\"", output
assert_match "/usr/bin/env mkdir -p .kamal", output
assert_match %r{docker rename app-web-latest app-web-latest_replaced_.*}, output
assert_match %r{docker run --detach --restart unless-stopped --name app-web-latest --hostname 1.1.1.1-.* -e KAMAL_CONTAINER_NAME="app-web-latest" -e KAMAL_VERSION="latest" --env-file .kamal/env/roles/app-web.env --health-cmd}, output

View File

@@ -33,7 +33,7 @@ traefik:
args:
accesslog: true
accesslog.format: json
image: registry:4443/traefik:v2.10
image: registry:4443/traefik:v2.11
accessories:
busybox:
service: custom-busybox

View File

@@ -27,7 +27,7 @@ traefik:
args:
accesslog: true
accesslog.format: json
image: registry:4443/traefik:v2.10
image: registry:4443/traefik:v2.11
accessories:
busybox:
service: custom-busybox

View File

@@ -19,7 +19,7 @@ push_image_to_registry_4443() {
install_kamal
push_image_to_registry_4443 nginx 1-alpine-slim
push_image_to_registry_4443 traefik v2.10
push_image_to_registry_4443 traefik v2.11
push_image_to_registry_4443 busybox 1.36.0
# .ssh is on a shared volume that persists between runs. Clean it up as the

View File

@@ -1,4 +1,4 @@
FROM registry
FROM registry:3
COPY boot.sh .

View File

@@ -1,3 +1,3 @@
#!/bin/sh
exec /entrypoint.sh /etc/docker/registry/config.yml
exec /entrypoint.sh /etc/distribution/config.yml

View File

@@ -32,7 +32,7 @@ class MainTest < IntegrationTest
assert_match /Traefik Host: vm2/, details
assert_match /App Host: vm1/, details
assert_match /App Host: vm2/, details
assert_match /traefik:v2.10/, details
assert_match /traefik:v2.11/, details
assert_match /registry:4443\/app:#{first_version}/, details
audit = kamal :audit, capture: true

View File

@@ -52,11 +52,11 @@ class TraefikTest < IntegrationTest
private
def assert_traefik_running
assert_match /traefik:v2.10 "\/entrypoint.sh/, traefik_details
assert_match /traefik:v2.11 "\/entrypoint.sh/, traefik_details
end
def assert_traefik_not_running
assert_no_match /traefik:v2.10 "\/entrypoint.sh/, traefik_details
assert_no_match /traefik:v2.11 "\/entrypoint.sh/, traefik_details
end
def traefik_details