feat(ops): add optional runtime registry mirroring

This commit is contained in:
binfan5 2026-03-15 13:18:37 +08:00
parent 9d5154cedf
commit f5c029fbe8
9 changed files with 179 additions and 8 deletions

View file

@ -3,6 +3,8 @@
SKILLHUB_VERSION=edge
SKILLHUB_SERVER_IMAGE=ghcr.io/iflytek/skillhub-server
SKILLHUB_WEB_IMAGE=ghcr.io/iflytek/skillhub-web
POSTGRES_IMAGE=postgres:16-alpine
REDIS_IMAGE=redis:7-alpine
# Public entrypoint seen by browsers/CLI, no trailing slash.
SKILLHUB_PUBLIC_BASE_URL=https://skillhub.example.com

View file

@ -19,6 +19,11 @@ env:
jobs:
publish:
runs-on: ubuntu-latest
env:
MIRROR_REGISTRY: ${{ secrets.MIRROR_REGISTRY || secrets.ALIYUN_REGISTRY }}
MIRROR_NAMESPACE: ${{ secrets.MIRROR_NAMESPACE || secrets.ALIYUN_NAME_SPACE }}
MIRROR_REGISTRY_USERNAME: ${{ secrets.MIRROR_REGISTRY_USERNAME || secrets.ALIYUN_REGISTRY_USER }}
MIRROR_REGISTRY_PASSWORD: ${{ secrets.MIRROR_REGISTRY_PASSWORD || secrets.ALIYUN_REGISTRY_PASSWORD }}
strategy:
fail-fast: false
matrix:
@ -27,10 +32,12 @@ jobs:
context: ./server
dockerfile: ./server/Dockerfile
image: ghcr.io/${{ github.repository_owner }}/skillhub-server
mirror_image: skillhub-server
- name: web
context: ./web
dockerfile: ./web/Dockerfile
image: ghcr.io/${{ github.repository_owner }}/skillhub-web
mirror_image: skillhub-web
steps:
- name: Check out repository
@ -49,11 +56,41 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Detect mirror configuration
id: mirror
shell: bash
run: |
if [[ -n "${MIRROR_REGISTRY}" && -n "${MIRROR_NAMESPACE}" && -n "${MIRROR_REGISTRY_USERNAME}" && -n "${MIRROR_REGISTRY_PASSWORD}" ]]; then
echo "enabled=true" >> "$GITHUB_OUTPUT"
else
echo "enabled=false" >> "$GITHUB_OUTPUT"
fi
- name: Log in to mirror registry
if: ${{ steps.mirror.outputs.enabled == 'true' }}
shell: bash
run: |
echo "${MIRROR_REGISTRY_PASSWORD}" | docker login "${MIRROR_REGISTRY}" \
--username "${MIRROR_REGISTRY_USERNAME}" \
--password-stdin
- name: Prepare image targets
id: targets
run: |
{
echo "images<<EOF"
echo "${{ matrix.image }}"
if [ "${{ steps.mirror.outputs.enabled }}" = "true" ]; then
echo "${MIRROR_REGISTRY%/}/${MIRROR_NAMESPACE}/${{ matrix.mirror_image }}"
fi
echo "EOF"
} >> "$GITHUB_OUTPUT"
- name: Extract image metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ matrix.image }}
images: ${{ steps.targets.outputs.images }}
tags: |
type=raw,value=edge,enable={{is_default_branch}}
type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/v') }}
@ -75,3 +112,47 @@ jobs:
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha,scope=${{ matrix.name }}
cache-to: type=gha,mode=max,scope=${{ matrix.name }}
mirror-runtime-images:
name: Mirror Runtime Images
runs-on: ubuntu-latest
needs: publish
env:
MIRROR_REGISTRY: ${{ secrets.MIRROR_REGISTRY || secrets.ALIYUN_REGISTRY }}
MIRROR_NAMESPACE: ${{ secrets.MIRROR_NAMESPACE || secrets.ALIYUN_NAME_SPACE }}
MIRROR_REGISTRY_USERNAME: ${{ secrets.MIRROR_REGISTRY_USERNAME || secrets.ALIYUN_REGISTRY_USER }}
MIRROR_REGISTRY_PASSWORD: ${{ secrets.MIRROR_REGISTRY_PASSWORD || secrets.ALIYUN_REGISTRY_PASSWORD }}
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Detect mirror configuration
id: mirror
shell: bash
run: |
if [[ -n "${MIRROR_REGISTRY}" && -n "${MIRROR_NAMESPACE}" && -n "${MIRROR_REGISTRY_USERNAME}" && -n "${MIRROR_REGISTRY_PASSWORD}" ]]; then
echo "enabled=true" >> "$GITHUB_OUTPUT"
else
echo "enabled=false" >> "$GITHUB_OUTPUT"
fi
- name: Set up Docker Buildx
if: ${{ steps.mirror.outputs.enabled == 'true' }}
uses: docker/setup-buildx-action@v3
- name: Log in to mirror registry
if: ${{ steps.mirror.outputs.enabled == 'true' }}
shell: bash
run: |
echo "${MIRROR_REGISTRY_PASSWORD}" | docker login "${MIRROR_REGISTRY}" \
--username "${MIRROR_REGISTRY_USERNAME}" \
--password-stdin
- name: Mirror runtime dependency images
if: ${{ steps.mirror.outputs.enabled == 'true' }}
run: bash scripts/mirror-runtime-images.sh
- name: Skip mirroring when registry secrets are not configured
if: ${{ steps.mirror.outputs.enabled != 'true' }}
run: echo "Mirror registry secrets are not configured; skipping runtime image mirroring."

View file

@ -137,6 +137,13 @@ Recommended image tags:
- `SKILLHUB_VERSION=edge` for the latest `main` build
- `SKILLHUB_VERSION=vX.Y.Z` for a fixed release
If you maintain a closer registry mirror, start the runtime with:
```bash
curl -fsSL https://raw.githubusercontent.com/iflytek/skillhub/main/scripts/runtime.sh | sh -s -- up \
--mirror-registry <registry>/<namespace>
```
Start the runtime:
```bash

View file

@ -1,6 +1,6 @@
services:
postgres:
image: postgres:16-alpine
image: ${POSTGRES_IMAGE:-postgres:16-alpine}
restart: unless-stopped
ports:
- "${POSTGRES_BIND_ADDRESS:-127.0.0.1}:${POSTGRES_PORT:-5432}:5432"
@ -17,7 +17,7 @@ services:
retries: 10
redis:
image: redis:7-alpine
image: ${REDIS_IMAGE:-redis:7-alpine}
restart: unless-stopped
ports:
- "${REDIS_BIND_ADDRESS:-127.0.0.1}:${REDIS_PORT:-6379}:6379"

View file

@ -0,0 +1,7 @@
# source_image target_image
postgres:16-alpine postgres:16-alpine
redis:7-alpine redis:7-alpine
minio/minio:latest minio:latest
prom/prometheus:latest prometheus:latest
grafana/grafana:latest grafana:latest
nginx:alpine nginx:alpine

View file

@ -1,6 +1,6 @@
services:
postgres:
image: postgres:16-alpine
image: ${POSTGRES_IMAGE:-postgres:16-alpine}
ports:
- "5432:5432"
environment:
@ -16,7 +16,7 @@ services:
retries: 5
redis:
image: redis:7-alpine
image: ${REDIS_IMAGE:-redis:7-alpine}
ports:
- "6379:6379"
healthcheck:
@ -26,7 +26,7 @@ services:
retries: 5
minio:
image: minio/minio:latest
image: ${MINIO_IMAGE:-minio/minio:latest}
ports:
- "9000:9000"
- "9001:9001"

View file

@ -1,13 +1,13 @@
services:
prometheus:
image: prom/prometheus:latest
image: ${PROMETHEUS_IMAGE:-prom/prometheus:latest}
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
grafana:
image: grafana/grafana:latest
image: ${GRAFANA_IMAGE:-grafana/grafana:latest}
ports:
- "3001:3000"
environment:

View file

@ -0,0 +1,29 @@
#!/usr/bin/env bash
set -euo pipefail
IMAGES_FILE="${1:-deploy/runtime-mirror-images.txt}"
: "${MIRROR_REGISTRY:?MIRROR_REGISTRY is required}"
: "${MIRROR_NAMESPACE:?MIRROR_NAMESPACE is required}"
target_prefix="${MIRROR_REGISTRY%/}/${MIRROR_NAMESPACE}"
while read -r source target; do
if [[ -z "${source}" || "${source}" == \#* ]]; then
continue
fi
if [[ -z "${target:-}" ]]; then
echo "Missing target image mapping for ${source}" >&2
exit 1
fi
if docker buildx imagetools inspect "${target_prefix}/${target}" >/dev/null 2>&1; then
echo "Skipping existing image ${target_prefix}/${target}"
continue
fi
echo "Mirroring ${source} -> ${target_prefix}/${target}"
docker buildx imagetools create --tag "${target_prefix}/${target}" "${source}"
done < "${IMAGES_FILE}"

View file

@ -12,8 +12,11 @@ SKILLHUB_REF="${SKILLHUB_REF:-main}"
SKILLHUB_HOME_DEFAULT="${TMPDIR:-/tmp}/skillhub-runtime"
SKILLHUB_HOME="${SKILLHUB_HOME:-$SKILLHUB_HOME_DEFAULT}"
SKILLHUB_VERSION_VALUE="${SKILLHUB_VERSION:-}"
SKILLHUB_MIRROR_REGISTRY_VALUE="${SKILLHUB_MIRROR_REGISTRY:-}"
SKILLHUB_SERVER_IMAGE_VALUE="${SKILLHUB_SERVER_IMAGE:-}"
SKILLHUB_WEB_IMAGE_VALUE="${SKILLHUB_WEB_IMAGE:-}"
POSTGRES_IMAGE_VALUE="${POSTGRES_IMAGE:-}"
REDIS_IMAGE_VALUE="${REDIS_IMAGE:-}"
while [ "$#" -gt 0 ]; do
case "$1" in
@ -22,6 +25,11 @@ while [ "$#" -gt 0 ]; do
SKILLHUB_VERSION_VALUE="$2"
shift 2
;;
--mirror-registry)
[ "$#" -ge 2 ] || { echo "Missing value for --mirror-registry" >&2; exit 1; }
SKILLHUB_MIRROR_REGISTRY_VALUE="$2"
shift 2
;;
--home)
[ "$#" -ge 2 ] || { echo "Missing value for --home" >&2; exit 1; }
SKILLHUB_HOME="$2"
@ -42,16 +50,29 @@ while [ "$#" -gt 0 ]; do
SKILLHUB_WEB_IMAGE_VALUE="$2"
shift 2
;;
--postgres-image)
[ "$#" -ge 2 ] || { echo "Missing value for --postgres-image" >&2; exit 1; }
POSTGRES_IMAGE_VALUE="$2"
shift 2
;;
--redis-image)
[ "$#" -ge 2 ] || { echo "Missing value for --redis-image" >&2; exit 1; }
REDIS_IMAGE_VALUE="$2"
shift 2
;;
--help|-h)
cat <<EOF
Usage: sh runtime.sh [up|down|clean|ps|logs|pull] [options]
Options:
--version <tag> Use a specific image tag, for example v0.1.0
--mirror-registry <r> Use mirrored images from <registry>/<namespace>
--home <dir> Store runtime files in a specific directory
--ref <git-ref> Download runtime files from a specific Git ref
--server-image <img> Override backend image repository
--web-image <img> Override frontend image repository
--postgres-image <i> Override PostgreSQL image
--redis-image <img> Override Redis image
EOF
exit 0
;;
@ -117,10 +138,34 @@ prepare_runtime_files() {
cp "$ENV_EXAMPLE_FILE" "$ENV_FILE"
fi
if [ -n "$SKILLHUB_MIRROR_REGISTRY_VALUE" ]; then
mirror_registry="${SKILLHUB_MIRROR_REGISTRY_VALUE%/}"
if [ -z "$POSTGRES_IMAGE_VALUE" ]; then
POSTGRES_IMAGE_VALUE="$mirror_registry/postgres:16-alpine"
fi
if [ -z "$REDIS_IMAGE_VALUE" ]; then
REDIS_IMAGE_VALUE="$mirror_registry/redis:7-alpine"
fi
if [ -z "$SKILLHUB_SERVER_IMAGE_VALUE" ]; then
SKILLHUB_SERVER_IMAGE_VALUE="$mirror_registry/skillhub-server"
fi
if [ -z "$SKILLHUB_WEB_IMAGE_VALUE" ]; then
SKILLHUB_WEB_IMAGE_VALUE="$mirror_registry/skillhub-web"
fi
fi
if [ -n "$SKILLHUB_VERSION_VALUE" ]; then
set_env_value "SKILLHUB_VERSION" "$SKILLHUB_VERSION_VALUE"
fi
if [ -n "$POSTGRES_IMAGE_VALUE" ]; then
set_env_value "POSTGRES_IMAGE" "$POSTGRES_IMAGE_VALUE"
fi
if [ -n "$REDIS_IMAGE_VALUE" ]; then
set_env_value "REDIS_IMAGE" "$REDIS_IMAGE_VALUE"
fi
if [ -n "$SKILLHUB_SERVER_IMAGE_VALUE" ]; then
set_env_value "SKILLHUB_SERVER_IMAGE" "$SKILLHUB_SERVER_IMAGE_VALUE"
fi