mirror of
				https://github.com/dani-garcia/vaultwarden.git
				synced 2025-11-04 12:18:20 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			139 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			139 lines
		
	
	
		
			4.9 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.
 | 
						|
#
 | 
						|
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
 | 
						|
#
 | 
						|
docker buildx create --name builder --use --driver-opt network=host
 | 
						|
 | 
						|
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
 |