Multi-arch Docker push: amd64 + arm64 with manifest
All checks were successful
CI / test (push) Successful in 1m8s

- Dockerfile.static: takes pre-built binary, no compilation
- push-docker.sh: downloads x86_64 from CI release, builds arm64
  natively, creates multi-arch manifest and pushes both
- docker pull works on both Intel and Apple Silicon / RPi

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Siavash Sameni
2026-03-31 15:06:56 +04:00
parent f1f597d308
commit 1be3cb82dc
2 changed files with 98 additions and 19 deletions

18
Dockerfile.static Normal file
View File

@@ -0,0 +1,18 @@
# Minimal image from a pre-built static binary
# Usage: docker build -f Dockerfile.static --build-arg BINARY=dist/btest .
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
ARG BINARY=dist/btest
COPY ${BINARY} /usr/local/bin/btest
RUN chmod +x /usr/local/bin/btest
EXPOSE 2000/tcp
EXPOSE 2001-2100/udp
EXPOSE 2257-2356/udp
ENTRYPOINT ["btest"]
CMD ["-s"]

View File

@@ -1,6 +1,9 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Build and push Docker image to Gitea registry. # Build and push multi-arch Docker images to Gitea registry.
# Run on a machine with Docker (your Mac). #
# Prerequisites:
# - dist/btest-linux-x86_64.tar.gz (from CI release or scripts/build-linux.sh)
# - Native macOS binary (built automatically)
# #
# Usage: # Usage:
# ./scripts/push-docker.sh v0.1.0 # ./scripts/push-docker.sh v0.1.0
@@ -16,32 +19,90 @@ if [[ -f .env ]]; then
fi fi
TAG="${1:?Usage: $0 <tag> (e.g. v0.1.0)}" TAG="${1:?Usage: $0 <tag> (e.g. v0.1.0)}"
REGISTRY="${GITEA_URL:-https://git.manko.yoga}" REGISTRY_HOST="${GITEA_URL:-https://git.manko.yoga}"
REGISTRY_HOST="${REGISTRY#https://}" REGISTRY_HOST="${REGISTRY_HOST#https://}"
REGISTRY_HOST="${REGISTRY_HOST#http://}" REGISTRY_HOST="${REGISTRY_HOST#http://}"
IMAGE="${REGISTRY_HOST}/manawenuz/btest-rs" IMAGE="${REGISTRY_HOST}/manawenuz/btest-rs"
echo "=== Building Docker image for ${IMAGE}:${TAG} ===" # Login
# Build the image
docker build -t "${IMAGE}:${TAG}" -t "${IMAGE}:latest" .
echo ""
echo "=== Pushing to ${REGISTRY_HOST} ==="
# Login if needed (uses GITEA_USER + GITEA_TOKEN from .env)
if [[ -n "${GITEA_TOKEN:-}" ]]; then if [[ -n "${GITEA_TOKEN:-}" ]]; then
DOCKER_USER="${GITEA_USER:?Set GITEA_USER in .env (your Gitea username)}" DOCKER_USER="${GITEA_USER:?Set GITEA_USER in .env}"
echo "${GITEA_TOKEN}" | docker login "${REGISTRY_HOST}" -u "${DOCKER_USER}" --password-stdin echo "${GITEA_TOKEN}" | docker login "${REGISTRY_HOST}" -u "${DOCKER_USER}" --password-stdin
fi fi
docker push "${IMAGE}:${TAG}" mkdir -p dist/docker-amd64 dist/docker-arm64
docker push "${IMAGE}:latest"
# --- x86_64 binary ---
if [[ ! -f dist/docker-amd64/btest ]]; then
if [[ -f dist/btest-linux-x86_64.tar.gz ]]; then
echo "Extracting x86_64 binary from tarball..."
tar xzf dist/btest-linux-x86_64.tar.gz -C dist/docker-amd64/
else
echo "No x86_64 binary found. Downloading from release ${TAG}..."
GITEA_URL_FULL="https://${REGISTRY_HOST}"
RELEASE_URL=$(curl -sf \
-H "Authorization: token ${GITEA_TOKEN}" \
"${GITEA_URL_FULL}/api/v1/repos/manawenuz/btest-rs/releases/tags/${TAG}" \
| jq -r '.assets[] | select(.name=="btest-linux-x86_64.tar.gz") | .browser_download_url')
if [[ -n "$RELEASE_URL" ]]; then
curl -sL "$RELEASE_URL" | tar xz -C dist/docker-amd64/
else
echo "Error: Cannot find x86_64 binary. Run CI first or scripts/build-linux.sh"
exit 1
fi
fi
fi
# --- arm64 binary (native build on Apple Silicon) ---
if [[ ! -f dist/docker-arm64/btest ]]; then
echo "Building native arm64 binary..."
cargo build --release
cp target/release/btest dist/docker-arm64/btest
fi
echo "" echo ""
echo "Done! Images pushed:" echo "=== Building amd64 image ==="
echo " ${IMAGE}:${TAG}" docker build --platform linux/amd64 -f Dockerfile.static \
echo " ${IMAGE}:latest" --build-arg BINARY=dist/docker-amd64/btest \
-t "${IMAGE}:${TAG}-amd64" .
echo ""
echo "=== Building arm64 image ==="
docker build --platform linux/arm64 -f Dockerfile.static \
--build-arg BINARY=dist/docker-arm64/btest \
-t "${IMAGE}:${TAG}-arm64" .
echo ""
echo "=== Pushing ==="
docker push "${IMAGE}:${TAG}-amd64"
docker push "${IMAGE}:${TAG}-arm64"
# Create and push multi-arch manifest
echo ""
echo "=== Creating multi-arch manifest ==="
docker manifest create "${IMAGE}:${TAG}" \
"${IMAGE}:${TAG}-amd64" \
"${IMAGE}:${TAG}-arm64" 2>/dev/null || \
docker manifest create --amend "${IMAGE}:${TAG}" \
"${IMAGE}:${TAG}-amd64" \
"${IMAGE}:${TAG}-arm64"
docker manifest push "${IMAGE}:${TAG}"
# Tag as latest
docker manifest create "${IMAGE}:latest" \
"${IMAGE}:${TAG}-amd64" \
"${IMAGE}:${TAG}-arm64" 2>/dev/null || \
docker manifest create --amend "${IMAGE}:latest" \
"${IMAGE}:${TAG}-amd64" \
"${IMAGE}:${TAG}-arm64"
docker manifest push "${IMAGE}:latest"
echo ""
echo "Done! Multi-arch images pushed:"
echo " ${IMAGE}:${TAG} (amd64 + arm64)"
echo " ${IMAGE}:latest (amd64 + arm64)"
echo "" echo ""
echo "Run with:" echo "Run with:"
echo " docker run --rm -p 2000:2000 -p 2001-2100:2001-2100/udp ${IMAGE}:${TAG} -s -v" echo " docker run --rm -p 2000:2000 -p 2001-2100:2001-2100/udp ${IMAGE}:${TAG} -s -v"