From 3c7ff8dcf0b02137afcbe3d08b1ade13c86d2b32 Mon Sep 17 00:00:00 2001 From: Alec Thomas Date: Thu, 29 Jan 2026 18:28:32 +1100 Subject: [PATCH] refactor: build binaries on the host to improve build/module cache reuse --- .dockerignore | 4 +--- Justfile | 3 ++- docker/Dockerfile | 38 +++++++------------------------------- docker/Justfile | 6 ++++++ 4 files changed, 16 insertions(+), 35 deletions(-) diff --git a/.dockerignore b/.dockerignore index 6ac986d..0568c3a 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,6 +1,4 @@ -# Build artifacts -dist/ -**/dist/ +# Build artifacts (dist/ is allowed for pre-built binaries) # Git .git/ diff --git a/Justfile b/Justfile index c3cc711..6e00bf9 100644 --- a/Justfile +++ b/Justfile @@ -39,7 +39,8 @@ fmt: build GOOS=(GOOS) GOARCH=(GOARCH): #!/usr/bin/env bash mkdir -p {{ RELEASE }} - go build -trimpath -o {{ RELEASE }}/cachewd-{{ GOOS }}-{{ GOARCH }} \ + CGO_ENABLED=0 GOOS={{ GOOS }} GOARCH={{ GOARCH }} \ + go build -trimpath -o {{ RELEASE }}/cachewd-{{ GOOS }}-{{ GOARCH }} \ -ldflags "-s -w -X main.version={{ VERSION }} -X main.gitCommit={{ GIT_COMMIT }}" \ ./cmd/cachewd test "{{ GOOS }}-{{ GOARCH }}" = "$(go env GOOS)-$(go env GOARCH)" && (cd {{ RELEASE }} && ln -sf cachewd-{{ GOOS }}-{{ GOARCH }} cachewd) diff --git a/docker/Dockerfile b/docker/Dockerfile index 7ef8329..b7bcb2b 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,51 +1,27 @@ -# Build stage -FROM golang:1.25.5-alpine AS builder +# Runtime image - binaries are pre-built on the host +FROM alpine:3.21 -ARG VERSION=dev -ARG GIT_COMMIT=unknown -ARG TARGETOS ARG TARGETARCH -WORKDIR /build - -# Install build dependencies -RUN apk add --no-cache git ca-certificates tzdata - -# Copy go mod files first for better caching -COPY go.mod go.sum ./ -RUN go mod download - -# Copy source code -COPY . . - -# Build the binary -RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \ - go build -trimpath -o cachewd \ - -ldflags "-s -w -X main.version=${VERSION} -X main.gitCommit=${GIT_COMMIT}" \ - ./cmd/cachewd - -# Runtime stage -FROM alpine:3.21 - SHELL ["/bin/sh", "-o", "pipefail", "-c"] # Install runtime dependencies for git operations and TLS RUN apk add --no-cache ca-certificates git tzdata && \ - addgroup -g 1000 cachew && \ - adduser -D -u 1000 -G cachew cachew + addgroup -g 1000 cachew && \ + adduser -D -u 1000 -G cachew cachew # Set working directory (config uses relative paths like ./state/cache) WORKDIR /app -# Copy binary from builder -COPY --from=builder /build/cachewd /usr/local/bin/cachewd +# Copy pre-built binary from host (built by Justfile) +COPY dist/cachewd-linux-${TARGETARCH} /usr/local/bin/cachewd # Copy default configuration file COPY cachew.hcl /app/cachew.hcl # Create state directory with proper permissions RUN mkdir -p /app/state/cache && \ - chown -R cachew:cachew /app + chown -R cachew:cachew /app # Switch to non-root user USER cachew diff --git a/docker/Justfile b/docker/Justfile index cdb3252..74a3751 100644 --- a/docker/Justfile +++ b/docker/Justfile @@ -7,9 +7,12 @@ TAG := `git rev-parse --short HEAD 2>/dev/null || echo "dev"` VERSION := `git describe --tags --always --dirty 2>/dev/null || echo "dev"` GIT_COMMIT := `git rev-parse HEAD 2>/dev/null || echo "unknown"` DOCKERFILE := ROOT + "/docker/Dockerfile" +RELEASE := ROOT + "/dist" # Build Docker image for local development build: + @echo "Building Linux binary for current architecture..." + @just -f {{ ROOT }}/Justfile build linux @echo "Building Docker image..." @docker build -f {{ DOCKERFILE }} \ --build-arg VERSION={{ VERSION }} \ @@ -20,6 +23,9 @@ build: # Build multi-arch Docker image (builds for amd64 + arm64, stays in cache) build-multi: + @echo "Building Linux binaries for amd64 and arm64..." + @just -f {{ ROOT }}/Justfile build linux amd64 + @just -f {{ ROOT }}/Justfile build linux arm64 @docker buildx create --use --driver docker-container --driver-opt image=moby/buildkit:v0.17.3 --name multi-arch-cachew 2>/dev/null || docker buildx use multi-arch-cachew @echo "Building multi-arch image..." @docker buildx build \