mirror of
https://github.com/BigBodyCobain/Shadowbroker.git
synced 2026-09-27 11:11:50 +02:00
feat: add Docker Hub as primary registry for anonymous pulls
GHCR requires authentication even for public packages on some systems. CI now pushes to both GHCR and Docker Hub. docker-compose.yml and Helm chart point to Docker Hub where anonymous pulls always work. Build directives kept as fallback for source-based builds. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
66df14a93c
commit
a3e7a2bc6b
@@ -8,7 +8,9 @@ on:
|
|||||||
branches: ["main"]
|
branches: ["main"]
|
||||||
|
|
||||||
env:
|
env:
|
||||||
REGISTRY: ghcr.io
|
GHCR_REGISTRY: ghcr.io
|
||||||
|
DOCKERHUB_BACKEND: bigbodycobain/shadowbroker-backend
|
||||||
|
DOCKERHUB_FRONTEND: bigbodycobain/shadowbroker-frontend
|
||||||
# github.repository as <account>/<repo>
|
# github.repository as <account>/<repo>
|
||||||
IMAGE_NAME: ${{ github.repository }}
|
IMAGE_NAME: ${{ github.repository }}
|
||||||
|
|
||||||
@@ -44,19 +46,26 @@ jobs:
|
|||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3.0.0
|
uses: docker/setup-buildx-action@v3.0.0
|
||||||
|
|
||||||
- name: Log into registry ${{ env.REGISTRY }}
|
- name: Log into GHCR
|
||||||
if: github.event_name != 'pull_request'
|
if: github.event_name != 'pull_request'
|
||||||
uses: docker/login-action@v3.0.0
|
uses: docker/login-action@v3.0.0
|
||||||
with:
|
with:
|
||||||
registry: ${{ env.REGISTRY }}
|
registry: ${{ env.GHCR_REGISTRY }}
|
||||||
username: ${{ github.actor }}
|
username: ${{ github.actor }}
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Log into Docker Hub
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
uses: docker/login-action@v3.0.0
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Extract Docker metadata
|
- name: Extract Docker metadata
|
||||||
id: meta
|
id: meta
|
||||||
uses: docker/metadata-action@v5.0.0
|
uses: docker/metadata-action@v5.0.0
|
||||||
with:
|
with:
|
||||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-frontend
|
images: ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}-frontend
|
||||||
|
|
||||||
- name: Build and push Docker image by digest
|
- name: Build and push Docker image by digest
|
||||||
id: build
|
id: build
|
||||||
@@ -68,7 +77,7 @@ jobs:
|
|||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
cache-from: type=gha,scope=frontend-${{ matrix.platform }}
|
cache-from: type=gha,scope=frontend-${{ matrix.platform }}
|
||||||
cache-to: type=gha,mode=max,scope=frontend-${{ matrix.platform }}
|
cache-to: type=gha,mode=max,scope=frontend-${{ matrix.platform }}
|
||||||
outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-frontend,push-by-digest=true,name-canonical=true,push=${{ github.event_name != 'pull_request' }}
|
outputs: type=image,name=${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}-frontend,push-by-digest=true,name-canonical=true,push=${{ github.event_name != 'pull_request' }}
|
||||||
|
|
||||||
- name: Export digest
|
- name: Export digest
|
||||||
if: github.event_name != 'pull_request'
|
if: github.event_name != 'pull_request'
|
||||||
@@ -108,29 +117,56 @@ jobs:
|
|||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3.0.0
|
uses: docker/setup-buildx-action@v3.0.0
|
||||||
|
|
||||||
- name: Log into registry ${{ env.REGISTRY }}
|
- name: Log into GHCR
|
||||||
uses: docker/login-action@v3.0.0
|
uses: docker/login-action@v3.0.0
|
||||||
with:
|
with:
|
||||||
registry: ${{ env.REGISTRY }}
|
registry: ${{ env.GHCR_REGISTRY }}
|
||||||
username: ${{ github.actor }}
|
username: ${{ github.actor }}
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Extract Docker metadata
|
- name: Log into Docker Hub
|
||||||
id: meta
|
uses: docker/login-action@v3.0.0
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Extract Docker metadata (GHCR)
|
||||||
|
id: meta-ghcr
|
||||||
uses: docker/metadata-action@v5.0.0
|
uses: docker/metadata-action@v5.0.0
|
||||||
with:
|
with:
|
||||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-frontend
|
images: ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}-frontend
|
||||||
tags: |
|
tags: |
|
||||||
type=semver,pattern={{version}}
|
type=semver,pattern={{version}}
|
||||||
type=semver,pattern={{major}}.{{minor}}
|
type=semver,pattern={{major}}.{{minor}}
|
||||||
type=raw,value=latest,enable={{is_default_branch}}
|
type=raw,value=latest,enable={{is_default_branch}}
|
||||||
|
|
||||||
- name: Create and push manifest
|
- name: Extract Docker metadata (Docker Hub)
|
||||||
|
id: meta-hub
|
||||||
|
uses: docker/metadata-action@v5.0.0
|
||||||
|
with:
|
||||||
|
images: ${{ env.DOCKERHUB_FRONTEND }}
|
||||||
|
tags: |
|
||||||
|
type=semver,pattern={{version}}
|
||||||
|
type=semver,pattern={{major}}.{{minor}}
|
||||||
|
type=raw,value=latest,enable={{is_default_branch}}
|
||||||
|
|
||||||
|
- name: Create and push GHCR manifest
|
||||||
working-directory: /tmp/digests/frontend
|
working-directory: /tmp/digests/frontend
|
||||||
run: |
|
run: |
|
||||||
docker buildx imagetools create \
|
docker buildx imagetools create \
|
||||||
$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
|
$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
|
||||||
$(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-frontend@sha256:%s ' *)
|
$(printf '${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}-frontend@sha256:%s ' *)
|
||||||
|
env:
|
||||||
|
DOCKER_METADATA_OUTPUT_JSON: ${{ steps.meta-ghcr.outputs.json }}
|
||||||
|
|
||||||
|
- name: Push to Docker Hub
|
||||||
|
working-directory: /tmp/digests/frontend
|
||||||
|
run: |
|
||||||
|
docker buildx imagetools create \
|
||||||
|
$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
|
||||||
|
$(printf '${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}-frontend@sha256:%s ' *)
|
||||||
|
env:
|
||||||
|
DOCKER_METADATA_OUTPUT_JSON: ${{ steps.meta-hub.outputs.json }}
|
||||||
|
|
||||||
build-backend:
|
build-backend:
|
||||||
needs: ci-gate
|
needs: ci-gate
|
||||||
@@ -159,19 +195,26 @@ jobs:
|
|||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3.0.0
|
uses: docker/setup-buildx-action@v3.0.0
|
||||||
|
|
||||||
- name: Log into registry ${{ env.REGISTRY }}
|
- name: Log into GHCR
|
||||||
if: github.event_name != 'pull_request'
|
if: github.event_name != 'pull_request'
|
||||||
uses: docker/login-action@v3.0.0
|
uses: docker/login-action@v3.0.0
|
||||||
with:
|
with:
|
||||||
registry: ${{ env.REGISTRY }}
|
registry: ${{ env.GHCR_REGISTRY }}
|
||||||
username: ${{ github.actor }}
|
username: ${{ github.actor }}
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Log into Docker Hub
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
uses: docker/login-action@v3.0.0
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Extract Docker metadata
|
- name: Extract Docker metadata
|
||||||
id: meta
|
id: meta
|
||||||
uses: docker/metadata-action@v5.0.0
|
uses: docker/metadata-action@v5.0.0
|
||||||
with:
|
with:
|
||||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-backend
|
images: ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}-backend
|
||||||
|
|
||||||
- name: Build and push Docker image by digest
|
- name: Build and push Docker image by digest
|
||||||
id: build
|
id: build
|
||||||
@@ -184,7 +227,7 @@ jobs:
|
|||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
cache-from: type=gha,scope=backend-${{ matrix.platform }}
|
cache-from: type=gha,scope=backend-${{ matrix.platform }}
|
||||||
cache-to: type=gha,mode=max,scope=backend-${{ matrix.platform }}
|
cache-to: type=gha,mode=max,scope=backend-${{ matrix.platform }}
|
||||||
outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-backend,push-by-digest=true,name-canonical=true,push=${{ github.event_name != 'pull_request' }}
|
outputs: type=image,name=${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}-backend,push-by-digest=true,name-canonical=true,push=${{ github.event_name != 'pull_request' }}
|
||||||
|
|
||||||
- name: Export digest
|
- name: Export digest
|
||||||
if: github.event_name != 'pull_request'
|
if: github.event_name != 'pull_request'
|
||||||
@@ -224,26 +267,53 @@ jobs:
|
|||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3.0.0
|
uses: docker/setup-buildx-action@v3.0.0
|
||||||
|
|
||||||
- name: Log into registry ${{ env.REGISTRY }}
|
- name: Log into GHCR
|
||||||
uses: docker/login-action@v3.0.0
|
uses: docker/login-action@v3.0.0
|
||||||
with:
|
with:
|
||||||
registry: ${{ env.REGISTRY }}
|
registry: ${{ env.GHCR_REGISTRY }}
|
||||||
username: ${{ github.actor }}
|
username: ${{ github.actor }}
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Extract Docker metadata
|
- name: Log into Docker Hub
|
||||||
id: meta
|
uses: docker/login-action@v3.0.0
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Extract Docker metadata (GHCR)
|
||||||
|
id: meta-ghcr
|
||||||
uses: docker/metadata-action@v5.0.0
|
uses: docker/metadata-action@v5.0.0
|
||||||
with:
|
with:
|
||||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-backend
|
images: ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}-backend
|
||||||
tags: |
|
tags: |
|
||||||
type=semver,pattern={{version}}
|
type=semver,pattern={{version}}
|
||||||
type=semver,pattern={{major}}.{{minor}}
|
type=semver,pattern={{major}}.{{minor}}
|
||||||
type=raw,value=latest,enable={{is_default_branch}}
|
type=raw,value=latest,enable={{is_default_branch}}
|
||||||
|
|
||||||
- name: Create and push manifest
|
- name: Extract Docker metadata (Docker Hub)
|
||||||
|
id: meta-hub
|
||||||
|
uses: docker/metadata-action@v5.0.0
|
||||||
|
with:
|
||||||
|
images: ${{ env.DOCKERHUB_BACKEND }}
|
||||||
|
tags: |
|
||||||
|
type=semver,pattern={{version}}
|
||||||
|
type=semver,pattern={{major}}.{{minor}}
|
||||||
|
type=raw,value=latest,enable={{is_default_branch}}
|
||||||
|
|
||||||
|
- name: Create and push GHCR manifest
|
||||||
working-directory: /tmp/digests/backend
|
working-directory: /tmp/digests/backend
|
||||||
run: |
|
run: |
|
||||||
docker buildx imagetools create \
|
docker buildx imagetools create \
|
||||||
$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
|
$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
|
||||||
$(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-backend@sha256:%s ' *)
|
$(printf '${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}-backend@sha256:%s ' *)
|
||||||
|
env:
|
||||||
|
DOCKER_METADATA_OUTPUT_JSON: ${{ steps.meta-ghcr.outputs.json }}
|
||||||
|
|
||||||
|
- name: Push to Docker Hub
|
||||||
|
working-directory: /tmp/digests/backend
|
||||||
|
run: |
|
||||||
|
docker buildx imagetools create \
|
||||||
|
$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
|
||||||
|
$(printf '${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}-backend@sha256:%s ' *)
|
||||||
|
env:
|
||||||
|
DOCKER_METADATA_OUTPUT_JSON: ${{ steps.meta-hub.outputs.json }}
|
||||||
|
|||||||
+4
-7
@@ -46,17 +46,14 @@ if [ ! -f "$COMPOSE_FILE" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Detect stale compose file from pre-migration clones (before March 2026).
|
# Detect stale compose file from pre-migration clones (before March 2026).
|
||||||
# The current compose file uses "image:" to pull pre-built images from GHCR.
|
# Old versions used ghcr.io which requires auth. Current file uses Docker Hub.
|
||||||
# Old versions had "build:" directives that compile from local source — much
|
if grep -q 'ghcr\.io' "$COMPOSE_FILE" 2>/dev/null; then
|
||||||
# slower and will NOT pick up new releases.
|
|
||||||
if grep -q '^\s*build:' "$COMPOSE_FILE" 2>/dev/null; then
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "================================================================"
|
echo "================================================================"
|
||||||
echo " [!] WARNING: Your docker-compose.yml is outdated."
|
echo " [!] WARNING: Your docker-compose.yml is outdated."
|
||||||
echo ""
|
echo ""
|
||||||
echo " It contains 'build:' directives, which means Docker is"
|
echo " It references ghcr.io which may require authentication."
|
||||||
echo " compiling from local source instead of pulling pre-built"
|
echo " The current version uses Docker Hub for anonymous pulls."
|
||||||
echo " images. You will NOT receive updates this way."
|
|
||||||
echo ""
|
echo ""
|
||||||
echo " Fix: re-clone the repository:"
|
echo " Fix: re-clone the repository:"
|
||||||
echo " cd .. && rm -rf $(basename "$SCRIPT_DIR")"
|
echo " cd .. && rm -rf $(basename "$SCRIPT_DIR")"
|
||||||
|
|||||||
+7
-2
@@ -1,6 +1,9 @@
|
|||||||
services:
|
services:
|
||||||
backend:
|
backend:
|
||||||
image: ghcr.io/bigbodycobain/shadowbroker-backend:latest
|
image: bigbodycobain/shadowbroker-backend:latest
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: backend/Dockerfile
|
||||||
container_name: shadowbroker-backend
|
container_name: shadowbroker-backend
|
||||||
ports:
|
ports:
|
||||||
- "${BIND:-127.0.0.1}:8000:8000"
|
- "${BIND:-127.0.0.1}:8000:8000"
|
||||||
@@ -33,7 +36,9 @@ services:
|
|||||||
cpus: '2'
|
cpus: '2'
|
||||||
|
|
||||||
frontend:
|
frontend:
|
||||||
image: ghcr.io/bigbodycobain/shadowbroker-frontend:latest
|
image: bigbodycobain/shadowbroker-frontend:latest
|
||||||
|
build:
|
||||||
|
context: ./frontend
|
||||||
container_name: shadowbroker-frontend
|
container_name: shadowbroker-frontend
|
||||||
ports:
|
ports:
|
||||||
- "${BIND:-127.0.0.1}:3000:3000"
|
- "${BIND:-127.0.0.1}:3000:3000"
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ shadowbroker:
|
|||||||
runAsGroup: 1001
|
runAsGroup: 1001
|
||||||
image:
|
image:
|
||||||
pullPolicy: Always
|
pullPolicy: Always
|
||||||
repository: ghcr.io/bigbodycobain/shadowbroker-backend
|
repository: bigbodycobain/shadowbroker-backend
|
||||||
tag: latest
|
tag: latest
|
||||||
env:
|
env:
|
||||||
AIS_API_KEY:
|
AIS_API_KEY:
|
||||||
@@ -41,7 +41,7 @@ shadowbroker:
|
|||||||
runAsGroup: 1001
|
runAsGroup: 1001
|
||||||
image:
|
image:
|
||||||
pullPolicy: Always
|
pullPolicy: Always
|
||||||
repository: ghcr.io/bigbodycobain/shadowbroker-frontend
|
repository: bigbodycobain/shadowbroker-frontend
|
||||||
tag: latest
|
tag: latest
|
||||||
|
|
||||||
env:
|
env:
|
||||||
|
|||||||
@@ -7,15 +7,14 @@ echo ===================================================
|
|||||||
echo.
|
echo.
|
||||||
|
|
||||||
:: Check for stale docker-compose.yml from pre-migration clones
|
:: Check for stale docker-compose.yml from pre-migration clones
|
||||||
findstr /R /C:"build:" docker-compose.yml >nul 2>&1
|
findstr /C:"ghcr.io" docker-compose.yml >nul 2>&1
|
||||||
if %errorlevel% equ 0 (
|
if %errorlevel% equ 0 (
|
||||||
echo.
|
echo.
|
||||||
echo ================================================================
|
echo ================================================================
|
||||||
echo [!] WARNING: Your docker-compose.yml is outdated.
|
echo [!] WARNING: Your docker-compose.yml is outdated.
|
||||||
echo.
|
echo.
|
||||||
echo It contains 'build:' directives, which means Docker will
|
echo It references ghcr.io which may require authentication.
|
||||||
echo compile from local source instead of pulling pre-built images.
|
echo The current version uses Docker Hub for anonymous pulls.
|
||||||
echo You will NOT receive updates this way.
|
|
||||||
echo.
|
echo.
|
||||||
echo If you use Docker, re-clone the repository:
|
echo If you use Docker, re-clone the repository:
|
||||||
echo git clone https://github.com/BigBodyCobain/Shadowbroker.git
|
echo git clone https://github.com/BigBodyCobain/Shadowbroker.git
|
||||||
|
|||||||
@@ -10,14 +10,13 @@ echo ""
|
|||||||
|
|
||||||
# Check for stale docker-compose.yml from pre-migration clones
|
# Check for stale docker-compose.yml from pre-migration clones
|
||||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
if [ -f "$SCRIPT_DIR/docker-compose.yml" ] && grep -q '^\s*build:' "$SCRIPT_DIR/docker-compose.yml" 2>/dev/null; then
|
if [ -f "$SCRIPT_DIR/docker-compose.yml" ] && grep -q 'ghcr\.io' "$SCRIPT_DIR/docker-compose.yml" 2>/dev/null; then
|
||||||
echo ""
|
echo ""
|
||||||
echo "================================================================"
|
echo "================================================================"
|
||||||
echo " [!] WARNING: Your docker-compose.yml is outdated."
|
echo " [!] WARNING: Your docker-compose.yml is outdated."
|
||||||
echo ""
|
echo ""
|
||||||
echo " It contains 'build:' directives, which means Docker will"
|
echo " It references ghcr.io which may require authentication."
|
||||||
echo " compile from local source instead of pulling pre-built images."
|
echo " The current version uses Docker Hub for anonymous pulls."
|
||||||
echo " You will NOT receive updates this way."
|
|
||||||
echo ""
|
echo ""
|
||||||
echo " If you use Docker, re-clone the repository:"
|
echo " If you use Docker, re-clone the repository:"
|
||||||
echo " git clone https://github.com/BigBodyCobain/Shadowbroker.git"
|
echo " git clone https://github.com/BigBodyCobain/Shadowbroker.git"
|
||||||
|
|||||||
Reference in New Issue
Block a user