From 26933f3e66907a5c52124c85aa9ffbf49a29128e Mon Sep 17 00:00:00 2001 From: epistemophiliac Date: Tue, 16 Jun 2026 20:17:46 -0400 Subject: [PATCH] Push registry images via Skopeo on internal Forgejo network. Bypass Cloudflare/Traefik 413 limits by copying to forgejo:3000 over Docker network instead of docker push to git.aexoradao.com. --- docs/JENKINS.md | 14 ++++--------- scripts/ci/jenkins-push-image.sh | 30 ++++++++++++++++----------- scripts/ci/jenkins-registry-bypass.sh | 14 ------------- 3 files changed, 22 insertions(+), 36 deletions(-) delete mode 100755 scripts/ci/jenkins-registry-bypass.sh diff --git a/docs/JENKINS.md b/docs/JENKINS.md index 01540a3..45bfe7e 100644 --- a/docs/JENKINS.md +++ b/docs/JENKINS.md @@ -64,19 +64,13 @@ Set `DOCKER_GID` on the Jenkins Coolify service to the host docker group GID (`s ### Registry push `413 Payload Too Large` -Docker image layers are often **>100MB**. If `git.aexoradao.com` is behind **Cloudflare proxy** (orange cloud), uploads fail with `413`. +Large image layers fail with `413` when uploads go through **Cloudflare** (100MB limit) or **Traefik gzip** on Forgejo. -**Why Jenkins `extra_hosts` alone is not enough:** with `/var/run/docker.sock` mounted, **`docker push` runs on the host dockerd**, which uses the **host's** DNS/`/etc/hosts`, not the Jenkins container's. +**CI fix:** `jenkins-push-image.sh` uses **Skopeo** to push over the **internal Docker network** to `forgejo-vydgeq365afzmxe4s1d75fwv:3000`, bypassing Cloudflare and Traefik. Jenkins must be on network `vydgeq365afzmxe4s1d75fwv` (configured in Coolify Jenkins service). -**Fix applied in CI:** `jenkins-registry-bypass.sh` adds on the **Coolify host**: +Public pulls still use `git.aexoradao.com/epistemophiliac/erpnext:`. -```text -127.0.0.1 git.aexoradao.com -``` - -(via a one-shot `docker run --network host` container). Pushes then go to **local Traefik**, not Cloudflare. - -**Manual fallback:** Cloudflare DNS → **DNS only** (grey cloud) for `git.aexoradao.com`, or add the same line to the host `/etc/hosts` yourself. +**Manual fallback:** Cloudflare DNS → **DNS only** (grey cloud) for `git.aexoradao.com`. ### Registry push 401/403 diff --git a/scripts/ci/jenkins-push-image.sh b/scripts/ci/jenkins-push-image.sh index 966e32a..7a71674 100755 --- a/scripts/ci/jenkins-push-image.sh +++ b/scripts/ci/jenkins-push-image.sh @@ -6,6 +6,8 @@ source .ci-bin/ci-env.sh REGISTRY_IMAGE="${REGISTRY_IMAGE:-git.aexoradao.com/epistemophiliac/erpnext}" REGISTRY_HOST="${REGISTRY_HOST:-git.aexoradao.com}" +FORGEJO_HOST="${FORGEJO_HOST:-forgejo-vydgeq365afzmxe4s1d75fwv}" +FORGEJO_NETWORK="${FORGEJO_NETWORK:-vydgeq365afzmxe4s1d75fwv}" GIT_SHA="$(git rev-parse --short HEAD)" IMAGE_TAG="${IMAGE_TAG:-main-${GIT_SHA}}" @@ -14,17 +16,21 @@ if [ -z "${REGISTRY_USER:-}" ] || [ -z "${REGISTRY_PASSWORD:-}" ]; then exit 1 fi -bash scripts/ci/jenkins-registry-bypass.sh +push_with_skopeo() { + local ref="$1" + echo "Skopeo push ${ref} -> http://${FORGEJO_HOST}:3000 (internal, bypasses Cloudflare/Traefik)" + $DOCKER run --rm \ + --network "${FORGEJO_NETWORK}" \ + -v /var/run/docker.sock:/var/run/docker.sock \ + quay.io/skopeo/stable:v1.17.0 \ + copy "docker-daemon:${ref}" \ + "docker://${FORGEJO_HOST}:3000/epistemophiliac/erpnext:${ref##*:}" \ + --dest-creds "${REGISTRY_USER}:${REGISTRY_PASSWORD}" \ + --dest-tls-verify=false \ + --retry-times 3 +} -PUSH_DOCKER_CONFIG="$(mktemp -d)" -trap 'rm -rf "$PUSH_DOCKER_CONFIG"' EXIT -export DOCKER_CONFIG="$PUSH_DOCKER_CONFIG" +push_with_skopeo "${REGISTRY_IMAGE}:${IMAGE_TAG}" +push_with_skopeo "${REGISTRY_IMAGE}:main" -echo "$REGISTRY_PASSWORD" | $DOCKER login "$REGISTRY_HOST" -u "$REGISTRY_USER" --password-stdin - -echo "Pushing ${REGISTRY_IMAGE}:${IMAGE_TAG}" -$DOCKER push "${REGISTRY_IMAGE}:${IMAGE_TAG}" -$DOCKER push "${REGISTRY_IMAGE}:main" - -echo "Pushed ${REGISTRY_IMAGE}:${IMAGE_TAG}" -echo "Pushed ${REGISTRY_IMAGE}:main" +echo "Pushed via internal Forgejo (public pull: ${REGISTRY_IMAGE}:)" diff --git a/scripts/ci/jenkins-registry-bypass.sh b/scripts/ci/jenkins-registry-bypass.sh deleted file mode 100755 index 3867182..0000000 --- a/scripts/ci/jenkins-registry-bypass.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash -# Registry uploads use the HOST dockerd (docker.sock), not the Jenkins container network. -# Map git.aexoradao.com -> 127.0.0.1 on the HOST so pushes hit local Traefik, not Cloudflare. -set -euo pipefail - -REGISTRY_HOST="${REGISTRY_HOST:-git.aexoradao.com}" -REGISTRY_BYPASS_IP="${REGISTRY_BYPASS_IP:-127.0.0.1}" - -# shellcheck source=/dev/null -source .ci-bin/ci-env.sh - -echo "Ensuring host /etc/hosts maps ${REGISTRY_BYPASS_IP} -> ${REGISTRY_HOST}" -$DOCKER run --rm --network host alpine:3.20 sh -c \ - "grep -qE '[[:space:]]${REGISTRY_HOST}([[:space:]]|$)' /etc/hosts || echo '${REGISTRY_BYPASS_IP} ${REGISTRY_HOST}' >> /etc/hosts; grep '${REGISTRY_HOST}' /etc/hosts"