From 93a11cddf6906e809ad6d006e55a2939fd5c4891 Mon Sep 17 00:00:00 2001 From: Hans Knecht Date: Tue, 24 Mar 2026 22:14:04 +0100 Subject: [PATCH] feat(ci): allow for supporting multi-arch images to be built and shipped --- .github/workflows/release.yaml | 16 ++++++---------- Makefile | 14 ++++++++++---- claude-code/Dockerfile | 9 ++++++++- cmd/kelos-controller/Dockerfile | 9 ++++++++- cmd/kelos-spawner/Dockerfile | 9 ++++++++- codex/Dockerfile | 9 ++++++++- cursor/Dockerfile | 9 ++++++++- gemini/Dockerfile | 9 ++++++++- opencode/Dockerfile | 9 ++++++++- 9 files changed, 72 insertions(+), 21 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index ffb90d06..ba024ef5 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -24,6 +24,9 @@ jobs: with: go-version-file: go.mod + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Login to GHCR uses: docker/login-action@v3 with: @@ -40,21 +43,14 @@ jobs: echo "version=main" >> "$GITHUB_OUTPUT" fi - - name: Build images + - name: Build and push multi-arch images env: VERSION: ${{ steps.version.outputs.version }} - run: make image VERSION="$VERSION" - - - name: Push images - env: - VERSION: ${{ steps.version.outputs.version }} - run: make push VERSION="$VERSION" + run: make push-multiarch VERSION="$VERSION" - name: Push latest tags for releases if: startsWith(github.ref, 'refs/tags/v') - run: | - make image VERSION=latest - make push VERSION=latest + run: make push-multiarch VERSION=latest - name: Build CLI binaries if: startsWith(github.ref, 'refs/tags/v') diff --git a/Makefile b/Makefile index 19a60ac1..73cc9b0c 100644 --- a/Makefile +++ b/Makefile @@ -81,10 +81,6 @@ run: ## Run a controller from your host. .PHONY: image image: ## Build docker images (use WHAT to build specific image). - @for dir in $(filter cmd/%,$(or $(WHAT),$(IMAGE_DIRS))); do \ - GOOS=linux GOARCH=amd64 $(MAKE) build WHAT=$$dir; \ - done - @GOOS=linux GOARCH=amd64 $(MAKE) build WHAT=cmd/kelos-capture @for dir in $(or $(WHAT),$(IMAGE_DIRS)); do \ docker build -t $(REGISTRY)/$$(basename $$dir):$(VERSION) -f $$dir/Dockerfile .; \ done @@ -95,6 +91,16 @@ push: ## Push docker images (use WHAT to push specific image). docker push $(REGISTRY)/$$(basename $$dir):$(VERSION); \ done +DOCKER_PLATFORMS ?= linux/amd64,linux/arm64 + +.PHONY: push-multiarch +push-multiarch: ## Build and push multi-arch docker images. + @for dir in $(or $(WHAT),$(IMAGE_DIRS)); do \ + docker buildx build --platform $(DOCKER_PLATFORMS) \ + -t $(REGISTRY)/$$(basename $$dir):$(VERSION) \ + -f $$dir/Dockerfile --push .; \ + done + RELEASE_PLATFORMS ?= linux/amd64 linux/arm64 darwin/amd64 darwin/arm64 .PHONY: release-binaries diff --git a/claude-code/Dockerfile b/claude-code/Dockerfile index 6e3352ef..b27e2e03 100644 --- a/claude-code/Dockerfile +++ b/claude-code/Dockerfile @@ -1,3 +1,10 @@ +FROM golang:1.25 AS builder +WORKDIR /workspace +COPY go.mod go.sum ./ +RUN go mod download +COPY . . +RUN CGO_ENABLED=0 go build -o bin/kelos-capture ./cmd/kelos-capture + FROM ubuntu:24.04 ARG GO_VERSION=1.25.0 @@ -33,7 +40,7 @@ RUN npm install -g @anthropic-ai/claude-code@${CLAUDE_CODE_VERSION} COPY claude-code/kelos_entrypoint.sh /kelos_entrypoint.sh RUN chmod +x /kelos_entrypoint.sh -COPY bin/kelos-capture /kelos/kelos-capture +COPY --from=builder /workspace/bin/kelos-capture /kelos/kelos-capture RUN useradd -u 61100 -m -s /bin/bash claude RUN mkdir -p /home/claude/.claude && chown -R claude:claude /home/claude diff --git a/cmd/kelos-controller/Dockerfile b/cmd/kelos-controller/Dockerfile index bbe8cb11..064ef76c 100644 --- a/cmd/kelos-controller/Dockerfile +++ b/cmd/kelos-controller/Dockerfile @@ -1,5 +1,12 @@ +FROM golang:1.25 AS builder +WORKDIR /workspace +COPY go.mod go.sum ./ +RUN go mod download +COPY . . +RUN CGO_ENABLED=0 go build -o bin/kelos-controller ./cmd/kelos-controller + FROM gcr.io/distroless/static:nonroot WORKDIR / -COPY bin/kelos-controller . +COPY --from=builder /workspace/bin/kelos-controller . USER 65532:65532 ENTRYPOINT ["/kelos-controller"] diff --git a/cmd/kelos-spawner/Dockerfile b/cmd/kelos-spawner/Dockerfile index a1851bc0..1797ea87 100644 --- a/cmd/kelos-spawner/Dockerfile +++ b/cmd/kelos-spawner/Dockerfile @@ -1,5 +1,12 @@ +FROM golang:1.25 AS builder +WORKDIR /workspace +COPY go.mod go.sum ./ +RUN go mod download +COPY . . +RUN CGO_ENABLED=0 go build -o bin/kelos-spawner ./cmd/kelos-spawner + FROM gcr.io/distroless/static:nonroot WORKDIR / -COPY bin/kelos-spawner . +COPY --from=builder /workspace/bin/kelos-spawner . USER 65532:65532 ENTRYPOINT ["/kelos-spawner"] diff --git a/codex/Dockerfile b/codex/Dockerfile index 397dd250..9a7ed9ca 100644 --- a/codex/Dockerfile +++ b/codex/Dockerfile @@ -1,3 +1,10 @@ +FROM golang:1.25 AS builder +WORKDIR /workspace +COPY go.mod go.sum ./ +RUN go mod download +COPY . . +RUN CGO_ENABLED=0 go build -o bin/kelos-capture ./cmd/kelos-capture + FROM ubuntu:24.04 ARG GO_VERSION=1.25.0 @@ -33,7 +40,7 @@ RUN npm install -g @openai/codex@${CODEX_VERSION} COPY codex/kelos_entrypoint.sh /kelos_entrypoint.sh RUN chmod +x /kelos_entrypoint.sh -COPY bin/kelos-capture /kelos/kelos-capture +COPY --from=builder /workspace/bin/kelos-capture /kelos/kelos-capture RUN useradd -u 61100 -m -s /bin/bash agent RUN mkdir -p /home/agent/.codex && chown -R agent:agent /home/agent diff --git a/cursor/Dockerfile b/cursor/Dockerfile index 4bd0f8ae..24b4f01e 100644 --- a/cursor/Dockerfile +++ b/cursor/Dockerfile @@ -1,3 +1,10 @@ +FROM golang:1.25 AS builder +WORKDIR /workspace +COPY go.mod go.sum ./ +RUN go mod download +COPY . . +RUN CGO_ENABLED=0 go build -o bin/kelos-capture ./cmd/kelos-capture + FROM ubuntu:24.04 ARG GO_VERSION=1.25.0 @@ -30,7 +37,7 @@ ENV PATH="/usr/local/go/bin:${PATH}" COPY cursor/kelos_entrypoint.sh /kelos_entrypoint.sh RUN chmod +x /kelos_entrypoint.sh -COPY bin/kelos-capture /kelos/kelos-capture +COPY --from=builder /workspace/bin/kelos-capture /kelos/kelos-capture RUN useradd -u 61100 -m -s /bin/bash agent RUN mkdir -p /home/agent/.cursor && chown -R agent:agent /home/agent diff --git a/gemini/Dockerfile b/gemini/Dockerfile index cb1a6b5d..c10f34bc 100644 --- a/gemini/Dockerfile +++ b/gemini/Dockerfile @@ -1,3 +1,10 @@ +FROM golang:1.25 AS builder +WORKDIR /workspace +COPY go.mod go.sum ./ +RUN go mod download +COPY . . +RUN CGO_ENABLED=0 go build -o bin/kelos-capture ./cmd/kelos-capture + FROM ubuntu:24.04 ARG GO_VERSION=1.25.0 @@ -33,7 +40,7 @@ RUN npm install -g @google/gemini-cli@${GEMINI_CLI_VERSION} COPY gemini/kelos_entrypoint.sh /kelos_entrypoint.sh RUN chmod +x /kelos_entrypoint.sh -COPY bin/kelos-capture /kelos/kelos-capture +COPY --from=builder /workspace/bin/kelos-capture /kelos/kelos-capture RUN useradd -u 61100 -m -s /bin/bash agent RUN mkdir -p /home/agent/.gemini && chown -R agent:agent /home/agent diff --git a/opencode/Dockerfile b/opencode/Dockerfile index f1cb13fb..f877d97a 100644 --- a/opencode/Dockerfile +++ b/opencode/Dockerfile @@ -1,3 +1,10 @@ +FROM golang:1.25 AS builder +WORKDIR /workspace +COPY go.mod go.sum ./ +RUN go mod download +COPY . . +RUN CGO_ENABLED=0 go build -o bin/kelos-capture ./cmd/kelos-capture + FROM ubuntu:24.04 ARG GO_VERSION=1.25.0 @@ -33,7 +40,7 @@ RUN npm install -g opencode-ai@${OPENCODE_VERSION} COPY opencode/kelos_entrypoint.sh /kelos_entrypoint.sh RUN chmod +x /kelos_entrypoint.sh -COPY bin/kelos-capture /kelos/kelos-capture +COPY --from=builder /workspace/bin/kelos-capture /kelos/kelos-capture RUN useradd -u 61100 -m -s /bin/bash agent RUN mkdir -p /home/agent/.opencode && chown -R agent:agent /home/agent