Add multi-arch build script (#21)

This commit is contained in:
andig 2019-04-27 19:14:16 +02:00 committed by Ludovic Fernandez
parent a40f688017
commit cb9c54f996
5 changed files with 113 additions and 4 deletions

View File

@ -6,3 +6,4 @@ dumpcerts.sh
acme.json
acme-backup.json
traefik-certs-dumper
build-docker.sh

View File

@ -4,7 +4,8 @@ go:
- 1.11.x
- 1.x
sudo: false
services:
- docker
env:
- GO111MODULE=on
@ -23,6 +24,13 @@ install:
- echo "TRAVIS_GO_VERSION=$TRAVIS_GO_VERSION"
- go mod download
before_deploy:
- >
if ! [ "$BEFORE_DEPLOY_RUN" ]; then
export BEFORE_DEPLOY_RUN=1;
echo "${DOCKER_PASSWORD}" | docker login -u "${DOCKER_USERNAME}" --password-stdin
fi
deploy:
- provider: script
skip_cleanup: true
@ -30,3 +38,9 @@ deploy:
on:
tags: true
condition: $TRAVIS_GO_VERSION =~ ^1\.x$
- provider: script
skip_cleanup: true
script: make publish-images
on:
tags: true
condition: $TRAVIS_GO_VERSION =~ ^1\.x$

View File

@ -1,5 +1,10 @@
FROM golang:1-alpine as builder
ARG RUNTIME_HASH
ARG GOARCH
ARG GOARM
ARG GOOS
RUN apk --update upgrade \
&& apk --no-cache --no-progress add git make gcc musl-dev
@ -10,9 +15,9 @@ COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN make build
RUN GOARCH=${GOARCH} GOARM=${GOARM} GOOS=${GOOS} make build
FROM alpine:3.9
FROM alpine:3.9${RUNTIME_HASH}
RUN apk --update upgrade \
&& apk --no-cache --no-progress add ca-certificates

View File

@ -16,7 +16,11 @@ clean:
build: clean
@echo Version: $(VERSION) $(BUILD_DATE)
go build -v -ldflags '-X "github.com/ldez/traefik-certs-dumper/cmd.version=${VERSION}" -X "github.com/ldez/traefik-certs-dumper/cmd.commit=${SHA}" -X "github.com/ldez/traefik-certs-dumper/cmd.date=${BUILD_DATE}"'
go build -v -ldflags '-X "github.com/ldez/traefik-certs-dumper/cmd.version=${VERSION}" -X "github.com/ldez/traefik-certs-dumper/cmd.commit=${SHA}" -X "github.com/ldez/traefik-certs-dumper/cmd.date=${BUILD_DATE}"' -o traefik-certs-dumper
checks:
golangci-lint run
publish-images:
VERSION=$(TAG_NAME) ./build-docker.sh
VERSION="latest" ./build-docker.sh

85
build-docker.sh Executable file
View File

@ -0,0 +1,85 @@
#!/usr/bin/env bash
set -o errexit
set -o pipefail
# safe guard
if [ -n "$TRAVIS_TAG" ] && [ -n "$VERSION" ]; then
echo "Deploying..."
else
echo "Skipping deploy"
exit 0
fi
# base docker image name
IMAGE_NAME="ldez/traefik-certs-dumper"
# only linux for now
OS=linux
# target platforms in docker manifest notation
declare -a PLATFORMS=( "amd64" "arm.v6" "arm.v7")
# images from Dockerfile
FROM_IMAGE=$(grep "{RUNTIME_HASH}" < Dockerfile | sed "s/FROM //" | sed 's/\$.*//')
# manifest cache file
MANIFEST_FILE=/tmp/tcd-manifest.${FROM_IMAGE}.json
# get platform image hash from docker manifest
function platformHash () {
local ARCHITECTURE VARIANT HASH
read -r ARCHITECTURE VARIANT <<< "$@"
if [ -z "$VARIANT" ]; then
HASH=$(jq -r ".manifests[] | select(.platform.architecture == \"$ARCHITECTURE\") | .digest" < "$MANIFEST_FILE")
else
HASH=$(jq -r ".manifests[] | select(.platform.architecture == \"$ARCHITECTURE\" and .platform.variant == \"$VARIANT\") | .digest" < "$MANIFEST_FILE")
fi
echo "$HASH"
}
# get manifest
if [ ! -f "$MANIFEST_FILE" ]; then
docker pull "$FROM_IMAGE"
DOCKER_CLI_EXPERIMENTAL=enabled docker manifest inspect "$FROM_IMAGE" > "$MANIFEST_FILE"
fi
# create and push images
for platform in "${PLATFORMS[@]}"; do
# split architecture.version
IFS='.' read -r ARCHITECTURE VARIANT <<< "$platform"
# add xargs to trim whitespace
RUNTIME_HASH=$(platformHash "$ARCHITECTURE" "$VARIANT")
# arm architectures flavors, strip "v" prefix
GOARM=${VARIANT:1}
# build for target runtime image and architecture
docker build --build-arg="RUNTIME_HASH=@${RUNTIME_HASH}" --build-arg="GOARCH=${ARCHITECTURE}" --build-arg="GOARM=${GOARM}" -t "$IMAGE_NAME:${VERSION}-$platform" .
# push images
docker push "$IMAGE_NAME:${VERSION}-$platform"
done
# create manifest
TAG_LIST=$(printf "$IMAGE_NAME:${VERSION}-%s " "${PLATFORMS[@]}")
# shellcheck disable=SC2086
DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create --amend "$IMAGE_NAME:${VERSION}" $TAG_LIST
for platform in "${PLATFORMS[@]}"; do
# split architecture.version
IFS='.' read -r ARCHITECTURE VARIANT <<< "$platform"
# docker and go architectures don't match
if [ "arm" == "$ARCHITECTURE" ] && [ -n "$VARIANT" ]; then
VARIANT="$ARCHITECTURE$VARIANT"
fi
DOCKER_CLI_EXPERIMENTAL=enabled docker manifest annotate "$IMAGE_NAME:${VERSION}" "$IMAGE_NAME:${VERSION}-$platform" --os "$OS" --arch "$ARCHITECTURE" --variant "$VARIANT"
done
# push manifest
DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push "$IMAGE_NAME:${VERSION}"