From 311e4d13f699d9f404014694340cdae7384bc996 Mon Sep 17 00:00:00 2001 From: Lukasz Raczylo Date: Sat, 3 Jan 2026 21:55:01 +0000 Subject: [PATCH] fix: resolve CGO cross-compilation issues with multi-stage Docker builds Problem: - Enabling CGO_ENABLED=1 for SQLite support caused cross-compilation failures - ARM64 assembly errors when building from amd64 host - Cross-compilation with CGO requires architecture-specific toolchains Solution: - Converted all Dockerfiles to multi-stage builds - Binaries now compile inside Docker using native platform builders - Used --platform flag to build for target architecture natively - Removed binary builds from .goreleaser.yaml (skip: true) - Updated dockers_v2 to use buildx with multi-platform support Changes: - .goreleaser.yaml: Skip standalone builds, use Docker buildx - Dockerfile.server: Multi-stage build with CGO - Dockerfile.scanner: Multi-stage build with CGO - Dockerfile.migrate: Multi-stage build with CGO Benefits: - No cross-compilation needed (each platform builds natively) - Docker buildx handles multi-platform builds automatically - SQLite support working with CGO enabled - Cleaner separation between build and runtime environments --- .goreleaser.yaml | 86 +++++++++++++++------------------------------- Dockerfile.migrate | 42 +++++++++++++++++++--- Dockerfile.scanner | 42 +++++++++++++++++++--- Dockerfile.server | 42 +++++++++++++++++++--- 4 files changed, 142 insertions(+), 70 deletions(-) diff --git a/.goreleaser.yaml b/.goreleaser.yaml index a5da755..c542f7b 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -13,42 +13,13 @@ before: # - ./script/generate-version.sh # Build configuration +# Note: Binaries are built inside Docker containers (multi-stage builds) +# to avoid CGO cross-compilation issues. No standalone builds here. builds: - id: gohoarder - main: ./cmd/gohoarder - binary: gohoarder - env: - - CGO_ENABLED=1 - goos: - - linux - - darwin - - windows - goarch: - - amd64 - - arm64 - ldflags: - - -s -w - - -X github.com/lukaszraczylo/gohoarder/internal/version.Version={{.Version}} - - -X github.com/lukaszraczylo/gohoarder/internal/version.GitCommit={{.ShortCommit}} - - -X github.com/lukaszraczylo/gohoarder/internal/version.BuildTime={{.Date}} - + skip: true - id: migrate - main: ./cmd/migrate - binary: migrate - env: - - CGO_ENABLED=1 - goos: - - linux - - darwin - - windows - goarch: - - amd64 - - arm64 - ldflags: - - -s -w - - -X main.Version={{.Version}} - - -X main.GitCommit={{.ShortCommit}} - - -X main.BuildTime={{.Date}} + skip: true # Archives for releases archives: @@ -108,16 +79,17 @@ release: dockers_v2: # 1. Application Engine - Main GoHoarder server - id: gohoarder-server - ids: - - gohoarder + use: buildx images: - ghcr.io/lukaszraczylo/gohoarder-server + build_flag_templates: + - "--platform=linux/amd64,linux/arm64" + - "--build-arg=VERSION={{ .Version }}" + - "--build-arg=GIT_COMMIT={{ .ShortCommit }}" + - "--build-arg=BUILD_TIME={{ .Date }}" tags: - "{{ .Version }}" - latest - platforms: - - linux/amd64 - - linux/arm64 dockerfile: Dockerfile.server labels: org.opencontainers.image.title: GoHoarder Server @@ -132,16 +104,14 @@ dockers_v2: # 2. Website - Frontend Dashboard - id: gohoarder-frontend - ids: - - gohoarder + use: buildx images: - ghcr.io/lukaszraczylo/gohoarder-frontend + build_flag_templates: + - "--platform=linux/amd64,linux/arm64" tags: - "{{ .Version }}" - latest - platforms: - - linux/amd64 - - linux/arm64 dockerfile: Dockerfile.frontend labels: org.opencontainers.image.title: GoHoarder Frontend @@ -156,16 +126,17 @@ dockers_v2: # 3. Scanning Engine - Background scanner worker - id: gohoarder-scanner - ids: - - gohoarder + use: buildx images: - ghcr.io/lukaszraczylo/gohoarder-scanner + build_flag_templates: + - "--platform=linux/amd64,linux/arm64" + - "--build-arg=VERSION={{ .Version }}" + - "--build-arg=GIT_COMMIT={{ .ShortCommit }}" + - "--build-arg=BUILD_TIME={{ .Date }}" tags: - "{{ .Version }}" - latest - platforms: - - linux/amd64 - - linux/arm64 dockerfile: Dockerfile.scanner labels: org.opencontainers.image.title: GoHoarder Scanner @@ -180,16 +151,14 @@ dockers_v2: # 4. Gateway - Nginx reverse proxy for unified deployment - id: gohoarder-gateway - ids: - - gohoarder + use: buildx images: - ghcr.io/lukaszraczylo/gohoarder-gateway + build_flag_templates: + - "--platform=linux/amd64,linux/arm64" tags: - "{{ .Version }}" - latest - platforms: - - linux/amd64 - - linux/arm64 dockerfile: Dockerfile.gateway labels: org.opencontainers.image.title: GoHoarder Gateway @@ -202,16 +171,17 @@ dockers_v2: # 5. Migration Engine - Database migration tool - id: gohoarder-migrate - ids: - - migrate + use: buildx images: - ghcr.io/lukaszraczylo/gohoarder-migrate + build_flag_templates: + - "--platform=linux/amd64,linux/arm64" + - "--build-arg=VERSION={{ .Version }}" + - "--build-arg=GIT_COMMIT={{ .ShortCommit }}" + - "--build-arg=BUILD_TIME={{ .Date }}" tags: - "{{ .Version }}" - latest - platforms: - - linux/amd64 - - linux/arm64 dockerfile: Dockerfile.migrate labels: org.opencontainers.image.title: GoHoarder Migrate diff --git a/Dockerfile.migrate b/Dockerfile.migrate index ea9736d..824d491 100644 --- a/Dockerfile.migrate +++ b/Dockerfile.migrate @@ -1,7 +1,43 @@ # Migration Engine - Database Migration Tool +# Multi-stage build to compile with CGO support +ARG TARGETOS=linux +ARG TARGETARCH=amd64 + +# Build stage +FROM --platform=$TARGETOS/$TARGETARCH golang:1.23-alpine AS builder + +# Install build dependencies for CGO +RUN apk add --no-cache \ + gcc \ + g++ \ + musl-dev \ + sqlite-dev \ + git + +WORKDIR /build + +# Copy go mod files +COPY go.mod go.sum ./ +RUN go mod download + +# Copy source code +COPY . . + +# Build with CGO enabled ARG TARGETOS ARG TARGETARCH +ARG VERSION=dev +ARG GIT_COMMIT=unknown +ARG BUILD_TIME=unknown +RUN CGO_ENABLED=1 GOOS=$TARGETOS GOARCH=$TARGETARCH \ + go build -ldflags="-s -w \ + -X main.Version=${VERSION} \ + -X main.GitCommit=${GIT_COMMIT} \ + -X main.BuildTime=${BUILD_TIME}" \ + -o migrate ./cmd/migrate + +# Runtime stage FROM alpine:latest # Install runtime dependencies (including CGO/SQLite dependencies) @@ -18,10 +54,8 @@ RUN apk add --no-cache \ RUN addgroup -g 1000 gohoarder && \ adduser -D -u 1000 -G gohoarder gohoarder -# Copy binary (from platform-specific path) -ARG TARGETOS -ARG TARGETARCH -COPY ${TARGETOS}/${TARGETARCH}/migrate /usr/local/bin/migrate +# Copy binary from builder +COPY --from=builder /build/migrate /usr/local/bin/migrate RUN chmod +x /usr/local/bin/migrate WORKDIR /app diff --git a/Dockerfile.scanner b/Dockerfile.scanner index e88d30a..3430a0a 100644 --- a/Dockerfile.scanner +++ b/Dockerfile.scanner @@ -1,7 +1,43 @@ # Scanning Engine - Background Scanner Worker +# Multi-stage build to compile with CGO support +ARG TARGETOS=linux +ARG TARGETARCH=amd64 + +# Build stage +FROM --platform=$TARGETOS/$TARGETARCH golang:1.23-alpine AS builder + +# Install build dependencies for CGO +RUN apk add --no-cache \ + gcc \ + g++ \ + musl-dev \ + sqlite-dev \ + git + +WORKDIR /build + +# Copy go mod files +COPY go.mod go.sum ./ +RUN go mod download + +# Copy source code +COPY . . + +# Build with CGO enabled ARG TARGETOS ARG TARGETARCH +ARG VERSION=dev +ARG GIT_COMMIT=unknown +ARG BUILD_TIME=unknown +RUN CGO_ENABLED=1 GOOS=$TARGETOS GOARCH=$TARGETARCH \ + go build -ldflags="-s -w \ + -X github.com/lukaszraczylo/gohoarder/internal/version.Version=${VERSION} \ + -X github.com/lukaszraczylo/gohoarder/internal/version.GitCommit=${GIT_COMMIT} \ + -X github.com/lukaszraczylo/gohoarder/internal/version.BuildTime=${BUILD_TIME}" \ + -o gohoarder ./cmd/gohoarder + +# Runtime stage FROM alpine:latest # Install scanning tools and runtime dependencies (including CGO/SQLite dependencies) @@ -39,10 +75,8 @@ RUN mkdir -p /var/cache/gohoarder \ /var/lib/gohoarder \ /var/lib/trivy -# Copy binary (from platform-specific path) -ARG TARGETOS -ARG TARGETARCH -COPY ${TARGETOS}/${TARGETARCH}/gohoarder /usr/local/bin/gohoarder +# Copy binary from builder +COPY --from=builder /build/gohoarder /usr/local/bin/gohoarder RUN chmod +x /usr/local/bin/gohoarder # Copy example config diff --git a/Dockerfile.server b/Dockerfile.server index a089cce..f90c0b3 100644 --- a/Dockerfile.server +++ b/Dockerfile.server @@ -1,7 +1,43 @@ # Application Engine - GoHoarder Server +# Multi-stage build to compile with CGO support +ARG TARGETOS=linux +ARG TARGETARCH=amd64 + +# Build stage +FROM --platform=$TARGETOS/$TARGETARCH golang:1.23-alpine AS builder + +# Install build dependencies for CGO +RUN apk add --no-cache \ + gcc \ + g++ \ + musl-dev \ + sqlite-dev \ + git + +WORKDIR /build + +# Copy go mod files +COPY go.mod go.sum ./ +RUN go mod download + +# Copy source code +COPY . . + +# Build with CGO enabled ARG TARGETOS ARG TARGETARCH +ARG VERSION=dev +ARG GIT_COMMIT=unknown +ARG BUILD_TIME=unknown +RUN CGO_ENABLED=1 GOOS=$TARGETOS GOARCH=$TARGETARCH \ + go build -ldflags="-s -w \ + -X github.com/lukaszraczylo/gohoarder/internal/version.Version=${VERSION} \ + -X github.com/lukaszraczylo/gohoarder/internal/version.GitCommit=${GIT_COMMIT} \ + -X github.com/lukaszraczylo/gohoarder/internal/version.BuildTime=${BUILD_TIME}" \ + -o gohoarder ./cmd/gohoarder + +# Runtime stage FROM alpine:latest # Install runtime dependencies (including CGO/SQLite dependencies) @@ -26,10 +62,8 @@ RUN mkdir -p /var/cache/gohoarder \ chmod -R 750 /var/cache/gohoarder \ /var/lib/gohoarder -# Copy binary (from platform-specific path) -ARG TARGETOS -ARG TARGETARCH -COPY ${TARGETOS}/${TARGETARCH}/gohoarder /usr/local/bin/gohoarder +# Copy binary from builder +COPY --from=builder /build/gohoarder /usr/local/bin/gohoarder RUN chmod +x /usr/local/bin/gohoarder # Copy example config