Skip to content

Commit

Permalink
Statically build using musl toolchain and target alpine
Browse files Browse the repository at this point in the history
Signed-off-by: Paulo Gomes <[email protected]>
  • Loading branch information
Paulo Gomes committed Jan 26, 2022
1 parent 90cf4b2 commit e3b0dfc
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 57 deletions.
96 changes: 40 additions & 56 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,89 +1,73 @@
ARG BASE_VARIANT=bullseye
ARG BASE_VARIANT=alpine
ARG GO_VERSION=1.17
ARG XX_VERSION=1.1.0

ARG LIBGIT2_IMG=ghcr.io/fluxcd/golang-with-libgit2
ARG LIBGIT2_TAG=libgit2-1.1.1-3
ARG LIBGIT2_TAG=libgit2-1.1.1-4

FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
FROM ${LIBGIT2_IMG}:${LIBGIT2_TAG} as libgit2
FROM --platform=linux/amd64 ${LIBGIT2_IMG}:${LIBGIT2_TAG} as build-amd64
FROM --platform=linux/arm64 ${LIBGIT2_IMG}:${LIBGIT2_TAG} as build-arm64
FROM --platform=linux/arm/v7 ${LIBGIT2_IMG}:${LIBGIT2_TAG} as build-armv7

FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-${BASE_VARIANT} as gostable

FROM gostable AS go-linux

FROM go-${TARGETOS} AS build-base-bullseye

# Copy the build utilities
COPY --from=xx / /
COPY --from=libgit2 /Makefile /libgit2/

# Install the libgit2 build dependencies
RUN make -C /libgit2 cmake

ARG TARGETPLATFORM
RUN make -C /libgit2 dependencies

FROM build-base-${BASE_VARIANT} as libgit2-bullseye

# Compile and install libgit2
ARG TARGETPLATFORM
RUN FLAGS=$(xx-clang --print-cmake-defines) make -C /libgit2 libgit2

FROM libgit2-${BASE_VARIANT} as build
FROM --platform=$BUILDPLATFORM build-$TARGETARCH$TARGETVARIANT AS build

# Configure workspace
WORKDIR /workspace

# This has its own go.mod, which needs to be present so go mod
# download works.
# Copy api submodule
COPY api/ api/

# Copy modules manifests
COPY go.mod go.mod
COPY go.sum go.sum

# cache deps before building and copying source so that we don't need to re-download as much
# and so that source changes don't invalidate our downloaded layer
# Cache modules
RUN go mod download

# Copy the go source
COPY main.go main.go
COPY pkg/ pkg/
COPY controllers/ controllers/
RUN apk add clang lld pkgconfig ca-certificates

# Build the binary
ENV CGO_ENABLED=1
ARG TARGETPLATFORM
RUN xx-go build -o image-automation-controller -trimpath \

RUN xx-apk add --no-cache \
musl-dev gcc lld binutils-gold

# Performance related changes:
# - Use read-only bind instead of copying go source files.
# - Cache go packages.
RUN --mount=target=. \
--mount=type=cache,target=/root/.cache/go-build \
--mount=type=cache,target=/go/pkg \
export LIBRARY_PATH="/usr/local/$(xx-info triple)/lib:/usr/local/$(xx-info triple)/lib64:${LIBRARY_PATH}" && \
export PKG_CONFIG_PATH="/usr/local/$(xx-info triple)/lib/pkgconfig:/usr/local/$(xx-info triple)/lib64/pkgconfig" && \
export FLAGS="$(pkg-config --static --libs --cflags libssh2 openssl libgit2)" && \
CGO_LDFLAGS="${FLAGS} -static" \
xx-go build \
-ldflags "-s -w" \
-tags 'netgo,osusergo,static_build' \
-o /image-automation-controller -trimpath \
main.go

FROM build as prepare-bullseye
# Ensure that the binary was cross-compiled correctly to the target platform.
RUN xx-verify --static /image-automation-controller

# Move libgit2 lib to generic and predictable location
ARG TARGETPLATFORM
RUN mkdir -p /libgit2/lib/ \
&& cp -d /usr/lib/$(xx-info triple)/libgit2.so* /libgit2/lib/

FROM prepare-${BASE_VARIANT} as prepare
FROM alpine

# The target image must aligned with apt sources used for libgit2.
FROM debian:bookworm-slim as controller
# Link repo to the GitHub Container Registry image
LABEL org.opencontainers.image.source="https://github.com/fluxcd/image-automation-controller"

# Copy libgit2
COPY --from=prepare /libgit2/lib/ /usr/local/lib/
RUN ldconfig
ARG TARGETPLATFORM
RUN apk --no-cache add ca-certificates \
&& update-ca-certificates

# Upgrade packages and install runtime dependencies
RUN apt update \
&& apt install -y zlib1g libssl1.1 libssh2-1 ca-certificates \
&& apt clean \
&& apt autoremove --purge -y \
&& rm -rf /var/lib/apt/lists/*
# Create minimal nsswitch.conf file to prioritize the usage of /etc/hosts over DNS queries.
# https://github.com/gliderlabs/docker-alpine/issues/367#issuecomment-354316460
RUN [ ! -e /etc/nsswitch.conf ] && echo 'hosts: files dns' > /etc/nsswitch.conf

# Copy over binary from build
COPY --from=prepare /workspace/image-automation-controller /usr/local/bin/
COPY --from=build /image-automation-controller /usr/local/bin/
COPY ATTRIBUTIONS.md /

USER 65534:65534

ENTRYPOINT [ "image-automation-controller" ]
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ CRD_OPTIONS ?= crd:crdVersions=v1

# Base image used to build the Go binary
LIBGIT2_IMG ?= ghcr.io/fluxcd/golang-with-libgit2
LIBGIT2_TAG ?= libgit2-1.1.1-3
LIBGIT2_TAG ?= libgit2-1.1.1-4

# Allows for defining additional Docker buildx arguments,
# e.g. '--push'.
Expand Down

0 comments on commit e3b0dfc

Please sign in to comment.