| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- #!/usr/bin/env bash
- # shellcheck source=arches.sh
- source ./hooks/arches.sh
- export DOCKER_CLI_EXPERIMENTAL=enabled
- # Join a list of args with a single char.
- # Ref: https://stackoverflow.com/a/17841619
- join() { local IFS="$1"; shift; echo "$*"; }
- set -ex
- echo ">>> Starting local Docker registry when needed..."
- # Docker Buildx's `docker-container` driver is needed for multi-platform
- # builds, but it can't access existing images on the Docker host (like the
- # cross-compiled ones we just built). Those images first need to be pushed to
- # a registry -- Docker Hub could be used, but since it's not trivial to clean
- # up those intermediate images on Docker Hub, it's easier to just run a local
- # Docker registry, which gets cleaned up automatically once the build job ends.
- #
- # https://docs.docker.com/registry/deploying/
- # https://hub.docker.com/_/registry
- #
- # Use host networking so the buildx container can access the registry via
- # localhost.
- #
- # First check if there already is a registry container running, else skip it.
- # This will only happen either locally or running it via Github Actions
- #
- if ! timeout 5 bash -c 'cat < /dev/null > /dev/tcp/localhost/5000'; then
- # defaults to port 5000
- docker run -d --name registry --network host registry:2
- fi
- # Docker Hub sets a `DOCKER_REPO` env var with the format `index.docker.io/user/repo`.
- # Strip the registry portion to construct a local repo path for use in `Dockerfile.buildx`.
- LOCAL_REGISTRY="localhost:5000"
- REPO="${DOCKER_REPO#*/}"
- LOCAL_REPO="${LOCAL_REGISTRY}/${REPO}"
- echo ">>> Pushing images to local registry..."
- for arch in "${arches[@]}"; do
- docker_image="${DOCKER_REPO}:${DOCKER_TAG}-${arch}"
- local_image="${LOCAL_REPO}:${DOCKER_TAG}-${arch}"
- docker tag "${docker_image}" "${local_image}"
- docker push "${local_image}"
- done
- echo ">>> Setting up Docker Buildx..."
- # Same as earlier, use host networking so the buildx container can access the
- # registry via localhost.
- #
- # Ref: https://github.com/docker/buildx/issues/94#issuecomment-534367714
- #
- # Check if there already is a builder running, else skip this and use the existing.
- # This will only happen either locally or running it via Github Actions
- #
- if ! docker buildx inspect builder > /dev/null 2>&1 ; then
- docker buildx create --name builder --use --driver-opt network=host
- fi
- echo ">>> Running Docker Buildx..."
- tags=("${DOCKER_REPO}:${DOCKER_TAG}")
- # If the Docker tag starts with a version number, assume the latest release
- # is being pushed. Add an extra tag (`latest` or `alpine`, as appropriate)
- # to make it easier for users to track the latest release.
- if [[ "${DOCKER_TAG}" =~ ^[0-9]+\.[0-9]+\.[0-9]+ ]]; then
- if [[ "${DOCKER_TAG}" == *alpine ]]; then
- tags+=("${DOCKER_REPO}:alpine")
- else
- tags+=("${DOCKER_REPO}:latest")
- fi
- fi
- tag_args=()
- for tag in "${tags[@]}"; do
- tag_args+=(--tag "${tag}")
- done
- # Docker Buildx takes a list of target platforms (OS/arch/variant), so map
- # the arch list to a platform list (assuming the OS is always `linux`).
- declare -A arch_to_platform=(
- [amd64]="linux/amd64"
- [armv6]="linux/arm/v6"
- [armv7]="linux/arm/v7"
- [arm64]="linux/arm64"
- )
- platforms=()
- for arch in "${arches[@]}"; do
- platforms+=("${arch_to_platform[$arch]}")
- done
- platform="$(join "," "${platforms[@]}")"
- # Run the build, pushing the resulting images and multi-arch manifest list to
- # Docker Hub. The Dockerfile is read from stdin to avoid sending any build
- # context, which isn't needed here since the actual cross-compiled images
- # have already been built.
- docker buildx build \
- --network host \
- --build-arg LOCAL_REPO="${LOCAL_REPO}" \
- --build-arg DOCKER_TAG="${DOCKER_TAG}" \
- --platform "${platform}" \
- "${tag_args[@]}" \
- --push \
- - < ./docker/Dockerfile.buildx
|