mirror of
https://github.com/dani-garcia/vaultwarden.git
synced 2024-12-27 15:45:57 -05:00
20535065d7
Since docker hub stopped Autobuild, we need to switch to something else. This will trigger building of images on Github Actions and pushes them to Docker Hub. You only need to add 3 secrets before you merge this PR to have it working directly. - DOCKERHUB_USERNAME : The username of the account you are going to push the builds to - DOCKERHUB_TOKEN : The token needed to login and push builds - DOCKERHUB_REPO : The repo name in the following form `index.docker.io/<user>/<repo>` So for vaultwarden that would be `index.docker.io/vaultwarden/server` Also some small modifications to the other workflows.
147 lines
5.3 KiB
Bash
Executable File
147 lines
5.3 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
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..."
|
|
|
|
# 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
|
|
#
|
|
docker start registry > /dev/null 2>&1 || docker run -d --name registry --network host registry:2 # defaults to port 5000
|
|
|
|
# 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
|
|
platforms="$(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 "${platforms}" \
|
|
"${tag_args[@]}" \
|
|
--push \
|
|
- < ./docker/Dockerfile.buildx
|
|
|
|
# Add an extra arch-specific tag for `arm32v6`; Docker can't seem to properly
|
|
# auto-select that image on ARMv6 platforms like Raspberry Pi 1 and Zero
|
|
# (https://github.com/moby/moby/issues/41017).
|
|
#
|
|
# Note that we use `arm32v6` instead of `armv6` to be consistent with the
|
|
# existing vaultwarden tags, which adhere to the naming conventions of the
|
|
# Docker per-architecture repos (e.g., https://hub.docker.com/u/arm32v6).
|
|
# Unfortunately, these per-arch repo names aren't always consistent with the
|
|
# corresponding platform (OS/arch/variant) IDs, particularly in the case of
|
|
# 32-bit ARM arches (e.g., `linux/arm/v6` is used, not `linux/arm32/v6`).
|
|
#
|
|
# TODO: It looks like this issue should be fixed starting in Docker 20.10.0,
|
|
# so this step can be removed once fixed versions are in wider distribution.
|
|
#
|
|
# Tags:
|
|
#
|
|
# testing => testing-arm32v6
|
|
# testing-alpine => <ignored>
|
|
# x.y.z => x.y.z-arm32v6, latest-arm32v6
|
|
# x.y.z-alpine => <ignored>
|
|
#
|
|
if [[ "${DOCKER_TAG}" != *alpine ]]; then
|
|
image="${DOCKER_REPO}":"${DOCKER_TAG}"
|
|
|
|
# Fetch the multi-arch manifest list and find the digest of the armv6 image.
|
|
filter='.manifests|.[]|select(.platform.architecture=="arm" and .platform.variant=="v6")|.digest'
|
|
digest="$(docker manifest inspect "${image}" | jq -r "${filter}")"
|
|
|
|
# Pull the armv6 image by digest, retag it, and repush it.
|
|
docker pull "${DOCKER_REPO}"@"${digest}"
|
|
docker tag "${DOCKER_REPO}"@"${digest}" "${image}"-arm32v6
|
|
docker push "${image}"-arm32v6
|
|
|
|
if [[ "${DOCKER_TAG}" =~ ^[0-9]+\.[0-9]+\.[0-9]+ ]]; then
|
|
docker tag "${image}"-arm32v6 "${DOCKER_REPO}:latest"-arm32v6
|
|
docker push "${DOCKER_REPO}:latest"-arm32v6
|
|
fi
|
|
fi
|