Skip to content

Commit

Permalink
Produce multi-platform Docker images
Browse files Browse the repository at this point in the history
Signed-off-by: Dave Henderson <dhenderson@gmail.com>
  • Loading branch information
Dave Henderson committed Apr 21, 2020
1 parent 5833b4f commit 44887b9
Show file tree
Hide file tree
Showing 3 changed files with 207 additions and 37 deletions.
101 changes: 98 additions & 3 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,104 @@ on: [push]
jobs:
docker-build:
runs-on: ubuntu-latest
services:
registry:
image: registry:2
ports:
- '5000:5000'
env:
DOCKER_BUILDKIT: 1
DOCKER_CLI_EXPERIMENTAL: enabled
steps:
- name: enable experimental mode
run: |
mkdir ~/.docker
echo '{"experimental": "enabled"}' > ~/.docker/config.json
- name: Install BuildX
run: |
mkdir -p ~/.docker/cli-plugins
curl -SL -o ~/.docker/cli-plugins/docker-buildx https://github.com/docker/buildx/releases/download/v0.3.1/buildx-v0.3.1.linux-amd64
chmod 755 ~/.docker/cli-plugins/docker-buildx
- name: Create BuildX Builder
run: |
docker buildx create \
--name builder \
--platform linux/amd64,linux/arm64,linux/arm/v6,linux/arm/v7,linux/ppc64le,linux/s390x,linux/386 \
--use \
--driver docker-container --driver-opt image=moby/buildkit:buildx-stable-1,network=host
docker buildx ls
docker ps
docker images
- run: docker info && docker version
- uses: actions/checkout@v1
- name: Make Docker images
run: make docker-images
- name: determine if this is a tag
run: |
if (git describe --abbrev=0 --exact-match &>/dev/null); then
echo "::set-env name=is_tag::true"
echo "::set-env name=git_tag::$(git describe --abbrev=0 --exact-match)"
# splits the major version from $tag - assumes it's a 3-part semver
echo "::set-env name=major_version::${tag%%\.*}"
fi
if: github.repository == 'hairyhenderson/gomplate'
- name: login
run: |
# NOTE: DOCKERHUB_TOKEN and DOCKERHUB_USERNAME must be present in https://github.com/hairyhenderson/gomplate/settings
echo ${{ secrets.DOCKERHUB_TOKEN }} | docker login --username ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin
- name: Make/Push temporary Docker images
run: make docker-multi COMMIT=${{ github.sha }} DOCKER_REPO=localhost:5000/gomplate
env:
DOCKER_BUILDKIT: '1'
COMMIT: ${{ github.sha }}
- name: Pull the temporary images
run: |
docker pull localhost:5000/gomplate:latest-${{ github.sha }}
docker pull localhost:5000/gomplate:slim-${{ github.sha }}
docker pull localhost:5000/gomplate:alpine-${{ github.sha }}
- name: Re-tag and push (master)
run: |
docker tag localhost:5000/gomplate:latest-${{ github.sha }} hairyhenderson/gomplate:latest
docker tag localhost:5000/gomplate:slim-${{ github.sha }} hairyhenderson/gomplate:slim
docker tag localhost:5000/gomplate:alpine-${{ github.sha }} hairyhenderson/gomplate:alpine
docker rmi localhost:5000/gomplate:latest-${{ github.sha }}
docker rmi localhost:5000/gomplate:slim-${{ github.sha }}
docker rmi localhost:5000/gomplate:alpine-${{ github.sha }}
docker images
# docker push hairyhenderson/gomplate
if: github.repository == 'hairyhenderson/gomplate' && github.ref == 'refs/heads/master'
- name: Re-tag and push (tagged release)
run: |
docker tag localhost:5000/gomplate:latest-${{ github.sha }} hairyhenderson/gomplate:latest
docker tag localhost:5000/gomplate:slim-${{ github.sha }} hairyhenderson/gomplate:slim
docker tag localhost:5000/gomplate:alpine-${{ github.sha }} hairyhenderson/gomplate:alpine
docker tag localhost:5000/gomplate:latest-${{ github.sha }} hairyhenderson/gomplate:${git_tag}
docker tag localhost:5000/gomplate:latest-${{ github.sha }} hairyhenderson/gomplate:stable
docker tag localhost:5000/gomplate:latest-${{ github.sha }} hairyhenderson/gomplate:${major_version}
docker tag localhost:5000/gomplate:slim-${{ github.sha }} hairyhenderson/gomplate:${git_tag}-slim
docker tag localhost:5000/gomplate:slim-${{ github.sha }} hairyhenderson/gomplate:${major_version}-slim
docker tag localhost:5000/gomplate:slim-${{ github.sha }} hairyhenderson/gomplate:stable-slim
docker tag localhost:5000/gomplate:alpine-${{ github.sha }} hairyhenderson/gomplate:${git_tag}-alpine
docker tag localhost:5000/gomplate:alpine-${{ github.sha }} hairyhenderson/gomplate:${major_version}-alpine
docker tag localhost:5000/gomplate:alpine-${{ github.sha }} hairyhenderson/gomplate:stable-alpine
docker rmi localhost:5000/gomplate:latest-${{ github.sha }}
docker rmi localhost:5000/gomplate:slim-${{ github.sha }}
docker rmi localhost:5000/gomplate:alpine-${{ github.sha }}
docker images
# docker push hairyhenderson/gomplate
if: github.repository == 'hairyhenderson/gomplate' && contains(github.ref, 'v*')
- name: Re-tag and push (non-master dry run)
run: |
docker tag localhost:5000/gomplate:latest-${{ github.sha }} hairyhenderson/gomplate:latest
docker tag localhost:5000/gomplate:slim-${{ github.sha }} hairyhenderson/gomplate:slim
docker tag localhost:5000/gomplate:alpine-${{ github.sha }} hairyhenderson/gomplate:alpine
docker rmi localhost:5000/gomplate:latest-${{ github.sha }}
docker rmi localhost:5000/gomplate:slim-${{ github.sha }}
docker rmi localhost:5000/gomplate:alpine-${{ github.sha }}
docker images
# docker push hairyhenderson/gomplate
if: github.repository != 'hairyhenderson/gomplate' || github.ref != 'refs/heads/master'
96 changes: 69 additions & 27 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,65 +1,107 @@
FROM hairyhenderson/upx:3.94 AS upx
# syntax=docker/dockerfile:1.1.5-experimental
FROM --platform=linux/amd64 hairyhenderson/upx:3.94 AS upx

FROM golang:1.14.2-alpine3.11 AS build
FROM --platform=linux/amd64 golang:1.14.2-alpine3.11 AS build

RUN apk add --no-cache \
make \
libgcc libstdc++ ucl \
git
ARG TARGETOS
ARG TARGETARCH
ARG TARGETVARIANT
ENV GOOS=$TARGETOS GOARCH=$TARGETARCH

COPY --from=upx /usr/bin/upx /usr/bin/upx
RUN apk add --no-cache make git

RUN mkdir -p /go/src/github.com/hairyhenderson/gomplate
WORKDIR /go/src/github.com/hairyhenderson/gomplate
COPY go.mod /go/src/github.com/hairyhenderson/gomplate
COPY go.sum /go/src/github.com/hairyhenderson/gomplate

RUN --mount=type=cache,id=go-build-${TARGETOS}-${TARGETARCH}${TARGETVARIANT},target=/root/.cache/go-build \
--mount=type=cache,id=go-pkg-${TARGETOS}-${TARGETARCH}${TARGETVARIANT},target=/go/pkg \
go mod download -x

COPY . /go/src/github.com/hairyhenderson/gomplate

RUN make build compress
RUN --mount=type=cache,id=go-build-${TARGETOS}-${TARGETARCH}${TARGETVARIANT},target=/root/.cache/go-build \
--mount=type=cache,id=go-pkg-${TARGETOS}-${TARGETARCH}${TARGETVARIANT},target=/go/pkg \
make build
RUN mv bin/gomplate* /bin/

FROM scratch AS artifacts
FROM --platform=linux/amd64 alpine:3.11.5 AS compress

COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY --from=build /go/src/github.com/hairyhenderson/gomplate/bin/* /bin/
ARG TARGETOS
ARG TARGETARCH
ARG TARGETVARIANT

CMD [ "/bin/gomplate_linux-amd64" ]
RUN apk add --no-cache \
make \
libgcc libstdc++ ucl

FROM scratch AS gomplate
ENV GOOS=$TARGETOS GOARCH=$TARGETARCH
WORKDIR /go/src/github.com/hairyhenderson/gomplate
COPY Makefile .
RUN mkdir bin

COPY --from=upx /usr/bin/upx /usr/bin/upx
COPY --from=build bin/* bin/

RUN make compress
RUN mv bin/gomplate* /bin/

FROM scratch AS gomplate-linux

ARG VCS_REF
ARG OS=linux
ARG ARCH=amd64
ARG TARGETOS
ARG TARGETARCH
ARG TARGETVARIANT

LABEL org.opencontainers.image.revision=$VCS_REF \
org.opencontainers.image.source="https://github.com/hairyhenderson/gomplate"

COPY --from=artifacts /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY --from=artifacts /bin/gomplate_${OS}-${ARCH} /gomplate
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY --from=build /bin/gomplate_${TARGETOS}-${TARGETARCH}${TARGETVARIANT} /gomplate

ENTRYPOINT [ "/gomplate" ]

FROM alpine:3.11.5 AS gomplate-alpine

ARG VCS_REF
ARG OS=linux
ARG ARCH=amd64
ARG TARGETOS
ARG TARGETARCH
ARG TARGETVARIANT

LABEL org.opencontainers.image.revision=$VCS_REF \
org.opencontainers.image.source="https://github.com/hairyhenderson/gomplate"

RUN apk add --no-cache ca-certificates
COPY --from=artifacts /bin/gomplate_${OS}-${ARCH}-slim /bin/gomplate
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY --from=compress /bin/gomplate_${TARGETOS}-${TARGETARCH}${TARGETVARIANT}-slim /gomplate

ENTRYPOINT [ "/bin/gomplate" ]

FROM scratch AS gomplate-slim
FROM scratch AS gomplate-slim-linux

ARG VCS_REF
ARG OS=linux
ARG ARCH=amd64
ARG TARGETOS
ARG TARGETARCH
ARG TARGETVARIANT

LABEL org.opencontainers.image.revision=$VCS_REF \
org.opencontainers.image.source="https://github.com/hairyhenderson/gomplate"

COPY --from=artifacts /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY --from=artifacts /bin/gomplate_${OS}-${ARCH}-slim /gomplate
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY --from=compress /bin/gomplate_${TARGETOS}-${TARGETARCH}${TARGETVARIANT}-slim /gomplate

ENTRYPOINT [ "/gomplate" ]

FROM --platform=windows/amd64 mcr.microsoft.com/windows/nanoserver:1809 AS gomplate-windows
ARG TARGETOS
ARG TARGETARCH
ARG TARGETVARIANT
COPY --from=build /bin/gomplate_${TARGETOS}-${TARGETARCH}${TARGETVARIANT}.exe /gomplate.exe

FROM --platform=windows/amd64 mcr.microsoft.com/windows/nanoserver:1809 AS gomplate-slim-windows
ARG TARGETOS
ARG TARGETARCH
ARG TARGETVARIANT
COPY --from=compress /bin/gomplate_${TARGETOS}-${TARGETARCH}${TARGETVARIANT}-slim.exe /gomplate.exe

FROM gomplate-$TARGETOS AS gomplate
FROM gomplate-slim-$TARGETOS AS gomplate-slim
47 changes: 40 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
extension = $(patsubst windows,.exe,$(filter windows,$(1)))
GO := go
PKG_NAME := gomplate
DOCKER_REPO ?= hairyhenderson/$(PKG_NAME)
PREFIX := .
DOCKER_LINUX_PLATFORMS ?= linux/amd64,linux/arm64,linux/arm/v6,linux/arm/v7
DOCKER_PLATFORMS ?= $(DOCKER_LINUX_PLATFORMS),windows/amd64

ifeq ("$(CI)","true")
LINT_PROCS ?= 1
Expand All @@ -19,8 +22,18 @@ VERSION_FLAG := -X `go list ./version`.Version=$(VERSION)
GOOS ?= $(shell go version | sed 's/^.*\ \([a-z0-9]*\)\/\([a-z0-9]*\)/\1/')
GOARCH ?= $(shell go version | sed 's/^.*\ \([a-z0-9]*\)\/\([a-z0-9]*\)/\2/')

platforms := freebsd-amd64 linux-amd64 linux-386 linux-arm linux-arm64 darwin-amd64 solaris-amd64 windows-amd64.exe windows-386.exe
compressed-platforms := linux-amd64-slim linux-arm-slim linux-arm64-slim darwin-amd64-slim windows-amd64-slim.exe
ifeq ("$(TARGETVARIANT)","")
ifneq ("$(GOARM)","")
TARGETVARIANT := v$(GOARM)
endif
else
ifeq ("$(GOARM)","")
GOARM ?= $(subst v,,$(TARGETVARIANT))
endif
endif

platforms := freebsd-amd64 linux-amd64 linux-386 linux-armv6 linux-armv7 linux-arm64 darwin-amd64 solaris-amd64 windows-amd64.exe windows-386.exe
compressed-platforms := linux-amd64-slim linux-armv6-slim linux-armv7-slim linux-arm64-slim darwin-amd64-slim windows-amd64-slim.exe

clean:
rm -Rf $(PREFIX)/bin/*
Expand All @@ -47,7 +60,7 @@ $(PREFIX)/bin/checksums.txt: \
$(PREFIX)/%.signed: $(PREFIX)/%
@keybase sign < $< > $@

compress: $(PREFIX)/bin/$(PKG_NAME)_$(GOOS)-$(GOARCH)-slim$(call extension,$(GOOS))
compress: $(PREFIX)/bin/$(PKG_NAME)_$(GOOS)-$(GOARCH)$(TARGETVARIANT)-slim$(call extension,$(GOOS))
cp $< $(PREFIX)/bin/$(PKG_NAME)-slim$(call extension,$(GOOS))

%.iid: Dockerfile
Expand All @@ -57,6 +70,26 @@ compress: $(PREFIX)/bin/$(PKG_NAME)_$(GOOS)-$(GOARCH)-slim$(call extension,$(GOO
--iidfile $@ \
.

docker-multi: Dockerfile
docker buildx build \
--build-arg VCS_REF=$(COMMIT) \
--platform $(DOCKER_PLATFORMS) \
--tag $(DOCKER_REPO):latest-$(COMMIT) \
--target gomplate \
--push .
docker buildx build \
--build-arg VCS_REF=$(COMMIT) \
--platform $(DOCKER_PLATFORMS) \
--tag $(DOCKER_REPO):slim-$(COMMIT) \
--target gomplate-slim \
--push .
docker buildx build \
--build-arg VCS_REF=$(COMMIT) \
--platform $(DOCKER_LINUX_PLATFORMS) \
--tag $(DOCKER_REPO):alpine-$(COMMIT) \
--target gomplate-alpine \
--push .

%.cid: %.iid
@docker create $(shell cat $<) > $@

Expand All @@ -65,17 +98,17 @@ build-release: artifacts.cid

docker-images: gomplate.iid gomplate-slim.iid

$(PREFIX)/bin/$(PKG_NAME)_%: $(shell find $(PREFIX) -type f -name "*.go")
GOOS=$(shell echo $* | cut -f1 -d-) GOARCH=$(shell echo $* | cut -f2 -d- | cut -f1 -d.) CGO_ENABLED=0 \
$(PREFIX)/bin/$(PKG_NAME)_%$(TARGETVARIANT)$(call extension,$(GOOS)): $(shell find $(PREFIX) -type f -name "*.go")
GOOS=$(shell echo $* | cut -f1 -d-) GOARCH=$(shell echo $* | cut -f2 -d- ) GOARM=$(GOARM) CGO_ENABLED=0 \
$(GO) build \
-ldflags "-w -s $(COMMIT_FLAG) $(VERSION_FLAG)" \
-o $@ \
./cmd/gomplate

$(PREFIX)/bin/$(PKG_NAME)$(call extension,$(GOOS)): $(PREFIX)/bin/$(PKG_NAME)_$(GOOS)-$(GOARCH)$(call extension,$(GOOS))
$(PREFIX)/bin/$(PKG_NAME)$(call extension,$(GOOS)): $(PREFIX)/bin/$(PKG_NAME)_$(GOOS)-$(GOARCH)$(TARGETVARIANT)$(call extension,$(GOOS))
cp $< $@

build: $(PREFIX)/bin/$(PKG_NAME)$(call extension,$(GOOS))
build: $(PREFIX)/bin/$(PKG_NAME)_$(GOOS)-$(GOARCH)$(TARGETVARIANT)$(call extension,$(GOOS)) $(PREFIX)/bin/$(PKG_NAME)$(call extension,$(GOOS))

ifeq ($(OS),Windows_NT)
test:
Expand Down

0 comments on commit 44887b9

Please sign in to comment.