ci: use domestic mirrors and persistent caches

This commit is contained in:
2026-08-13 23:15:48 +08:00
parent fdab9978bf
commit 96ed3396d9
8 changed files with 67 additions and 58 deletions
Vendored
+42 -39
View File
@@ -29,24 +29,27 @@ pipeline {
FNPACK_SHA256 = '54b97fa7b70968c4d05c79840f5daeff508957d0bb2062fdb0376d00d9615c93' FNPACK_SHA256 = '54b97fa7b70968c4d05c79840f5daeff508957d0bb2062fdb0376d00d9615c93'
DOTNET = '/home/nanxunai/.local/bin/dotnet' DOTNET = '/home/nanxunai/.local/bin/dotnet'
BUILDER_NAME = "liverecorder-${BUILD_NUMBER}" BUILDER_NAME = 'liverecorder-ci'
BUILDKIT_IMAGE = 'docker.m.daocloud.io/moby/buildkit:buildx-stable-1' BUILDKIT_IMAGE = 'docker.m.daocloud.io/moby/buildkit:buildx-stable-1'
BINFMT_IMAGE = 'docker.m.daocloud.io/tonistiigi/binfmt:latest' BINFMT_IMAGE = 'docker.m.daocloud.io/tonistiigi/binfmt:latest'
ARM_TEST_IMAGE = 'docker.m.daocloud.io/library/alpine:latest' ARM_TEST_IMAGE = 'docker.m.daocloud.io/library/alpine:latest'
NODE_BUILD_IMAGE = 'docker.m.daocloud.io/library/node:22-alpine' NODE_BUILD_IMAGE = 'docker.m.daocloud.io/library/node:22-alpine'
NGINX_IMAGE = 'docker.m.daocloud.io/library/nginx:1.27-alpine' NGINX_IMAGE = 'docker.m.daocloud.io/library/nginx:1.27-alpine'
DOTNET_SDK_IMAGE = 'mcr.m.daocloud.io/dotnet/sdk:8.0-bookworm-slim'
DOTNET_RUNTIME_IMAGE = 'mcr.m.daocloud.io/dotnet/aspnet:8.0-bookworm-slim'
HTTP_PROXY_URL = 'http://192.168.5.200:7890' HTTP_PROXY_URL = 'http://192.168.5.200:7890'
NO_PROXY_HOSTS = '127.0.0.1,localhost,reg.nxsir.cn,gitea.nxsir.cn,openlist.nxsir.cn,mirrors.tuna.tsinghua.edu.cn,.tsinghua.edu.cn,mcr.microsoft.com' NO_PROXY_HOSTS = '127.0.0.1,localhost,reg.nxsir.cn,gitea.nxsir.cn,openlist.nxsir.cn,mirrors.tuna.tsinghua.edu.cn,.tsinghua.edu.cn,mirrors.huaweicloud.com,.huaweicloud.com,mcr.m.daocloud.io,docker.m.daocloud.io,.m.daocloud.io'
CI_ROOT = "${WORKSPACE}/.ci" CI_ROOT = "${WORKSPACE}/.ci"
DOCKER_CONFIG = "${WORKSPACE}/.ci/docker" CI_CACHE_ROOT = '/home/nanxunai/.cache/liverecorder-ci'
NUGET_PACKAGES = "${WORKSPACE}/.ci/nuget-packages" DOCKER_CONFIG = '/home/nanxunai/.cache/liverecorder-ci/docker'
NUGET_HTTP_CACHE_PATH = "${WORKSPACE}/.ci/nuget-http" NUGET_PACKAGES = '/home/nanxunai/.cache/liverecorder-ci/nuget-packages'
NUGET_PLUGINS_CACHE_PATH = "${WORKSPACE}/.ci/nuget-plugins" NUGET_HTTP_CACHE_PATH = '/home/nanxunai/.cache/liverecorder-ci/nuget-http'
DOTNET_CLI_HOME = "${WORKSPACE}/.ci/dotnet-home" NUGET_PLUGINS_CACHE_PATH = '/home/nanxunai/.cache/liverecorder-ci/nuget-plugins'
NPM_CONFIG_CACHE = "${WORKSPACE}/.ci/npm-cache" DOTNET_CLI_HOME = '/home/nanxunai/.cache/liverecorder-ci/dotnet-home'
LIVERECORDER_NUGET_FEED = "${WORKSPACE}/.ci/nuget-feed" NPM_CONFIG_CACHE = '/home/nanxunai/.cache/liverecorder-ci/npm-cache'
LIVERECORDER_NUGET_FEED = '/home/nanxunai/.cache/liverecorder-ci/nuget-feed'
LIVERECORDER_BUILD_TMPDIR = "${WORKSPACE}/.ci/fnos-tmp" LIVERECORDER_BUILD_TMPDIR = "${WORKSPACE}/.ci/fnos-tmp"
LIVERECORDER_VERIFY_TMPDIR = "${WORKSPACE}/.ci/fnos-verify" LIVERECORDER_VERIFY_TMPDIR = "${WORKSPACE}/.ci/fnos-verify"
LIVERECORDER_SKIP_NPM_CI = '1' LIVERECORDER_SKIP_NPM_CI = '1'
@@ -139,6 +142,7 @@ pipeline {
fi fi
mkdir -p \ mkdir -p \
"$CI_CACHE_ROOT" \
"$DOCKER_CONFIG" \ "$DOCKER_CONFIG" \
"$NUGET_PACKAGES" \ "$NUGET_PACKAGES" \
"$NUGET_HTTP_CACHE_PATH" \ "$NUGET_HTTP_CACHE_PATH" \
@@ -193,19 +197,22 @@ pipeline {
fi fi
./scripts/ci-docker.sh run --rm --platform linux/arm64 "$ARM_TEST_IMAGE" uname -m | grep -q aarch64 ./scripts/ci-docker.sh run --rm --platform linux/arm64 "$ARM_TEST_IMAGE" uname -m | grep -q aarch64
./scripts/ci-docker.sh buildx rm -f "$BUILDER_NAME" >/dev/null 2>&1 || true if ./scripts/ci-docker.sh buildx inspect "$BUILDER_NAME" >/dev/null 2>&1; then
./scripts/ci-docker.sh buildx create \ ./scripts/ci-docker.sh buildx use "$BUILDER_NAME"
--name "$BUILDER_NAME" \ else
--driver docker-container \ ./scripts/ci-docker.sh buildx create \
--driver-opt "image=$BUILDKIT_IMAGE" \ --name "$BUILDER_NAME" \
--driver-opt network=host \ --driver docker-container \
--driver-opt "env.http_proxy=$HTTP_PROXY_URL" \ --driver-opt "image=$BUILDKIT_IMAGE" \
--driver-opt "env.https_proxy=$HTTP_PROXY_URL" \ --driver-opt network=host \
--driver-opt "env.HTTP_PROXY=$HTTP_PROXY_URL" \ --driver-opt "env.http_proxy=$HTTP_PROXY_URL" \
--driver-opt "env.HTTPS_PROXY=$HTTP_PROXY_URL" \ --driver-opt "env.https_proxy=$HTTP_PROXY_URL" \
--driver-opt "env.no_proxy=reg.nxsir.cn" \ --driver-opt "env.HTTP_PROXY=$HTTP_PROXY_URL" \
--driver-opt "env.NO_PROXY=reg.nxsir.cn" \ --driver-opt "env.HTTPS_PROXY=$HTTP_PROXY_URL" \
--use --driver-opt "env.no_proxy=reg.nxsir.cn,mcr.m.daocloud.io,docker.m.daocloud.io,mirrors.huaweicloud.com" \
--driver-opt "env.NO_PROXY=reg.nxsir.cn,mcr.m.daocloud.io,docker.m.daocloud.io,mirrors.huaweicloud.com" \
--use
fi
./scripts/ci-docker.sh buildx inspect "$BUILDER_NAME" --bootstrap ./scripts/ci-docker.sh buildx inspect "$BUILDER_NAME" --bootstrap
''' '''
} }
@@ -248,7 +255,9 @@ pipeline {
./scripts/ci-docker.sh buildx build \ ./scripts/ci-docker.sh buildx build \
--builder "$BUILDER_NAME" --platform "$platform" --network host \ --builder "$BUILDER_NAME" --platform "$platform" --network host \
--progress=plain --provenance=false --no-cache \ --progress=plain --provenance=false \
--build-arg DOTNET_SDK_IMAGE="$DOTNET_SDK_IMAGE" \
--build-arg DOTNET_RUNTIME_IMAGE="$DOTNET_RUNTIME_IMAGE" \
--build-arg HTTP_PROXY="$HTTP_PROXY_URL" \ --build-arg HTTP_PROXY="$HTTP_PROXY_URL" \
--build-arg HTTPS_PROXY="$HTTP_PROXY_URL" \ --build-arg HTTPS_PROXY="$HTTP_PROXY_URL" \
--build-arg NO_PROXY="$NO_PROXY_HOSTS" \ --build-arg NO_PROXY="$NO_PROXY_HOSTS" \
@@ -256,12 +265,9 @@ pipeline {
--build-arg https_proxy="$HTTP_PROXY_URL" \ --build-arg https_proxy="$HTTP_PROXY_URL" \
--build-arg no_proxy="$NO_PROXY_HOSTS" \ --build-arg no_proxy="$NO_PROXY_HOSTS" \
-f src/LiveRecorder.WebApi/Dockerfile -t "$api_ref" --push . -f src/LiveRecorder.WebApi/Dockerfile -t "$api_ref" --push .
./scripts/ci-docker.sh buildx prune \
--builder "$BUILDER_NAME" --all --force
./scripts/ci-docker.sh buildx build \ ./scripts/ci-docker.sh buildx build \
--builder "$BUILDER_NAME" --platform "$platform" --network host \ --builder "$BUILDER_NAME" --platform "$platform" --network host \
--progress=plain --provenance=false --no-cache \ --progress=plain --provenance=false \
--build-arg NODE_IMAGE="$NODE_BUILD_IMAGE" \ --build-arg NODE_IMAGE="$NODE_BUILD_IMAGE" \
--build-arg NGINX_IMAGE="$NGINX_IMAGE" \ --build-arg NGINX_IMAGE="$NGINX_IMAGE" \
--build-arg HTTP_PROXY="$HTTP_PROXY_URL" \ --build-arg HTTP_PROXY="$HTTP_PROXY_URL" \
@@ -272,8 +278,6 @@ pipeline {
--build-arg no_proxy="$NO_PROXY_HOSTS" \ --build-arg no_proxy="$NO_PROXY_HOSTS" \
--build-arg VITE_API_BASE_URL=/api \ --build-arg VITE_API_BASE_URL=/api \
-f frontend/Dockerfile -t "$web_ref" --push frontend -f frontend/Dockerfile -t "$web_ref" --push frontend
./scripts/ci-docker.sh buildx prune \
--builder "$BUILDER_NAME" --all --force
''' '''
} }
} }
@@ -295,7 +299,9 @@ pipeline {
./scripts/ci-docker.sh buildx build \ ./scripts/ci-docker.sh buildx build \
--builder "$BUILDER_NAME" --platform "$platform" --network host \ --builder "$BUILDER_NAME" --platform "$platform" --network host \
--progress=plain --provenance=false --no-cache \ --progress=plain --provenance=false \
--build-arg DOTNET_SDK_IMAGE="$DOTNET_SDK_IMAGE" \
--build-arg DOTNET_RUNTIME_IMAGE="$DOTNET_RUNTIME_IMAGE" \
--build-arg HTTP_PROXY="$HTTP_PROXY_URL" \ --build-arg HTTP_PROXY="$HTTP_PROXY_URL" \
--build-arg HTTPS_PROXY="$HTTP_PROXY_URL" \ --build-arg HTTPS_PROXY="$HTTP_PROXY_URL" \
--build-arg NO_PROXY="$NO_PROXY_HOSTS" \ --build-arg NO_PROXY="$NO_PROXY_HOSTS" \
@@ -303,12 +309,9 @@ pipeline {
--build-arg https_proxy="$HTTP_PROXY_URL" \ --build-arg https_proxy="$HTTP_PROXY_URL" \
--build-arg no_proxy="$NO_PROXY_HOSTS" \ --build-arg no_proxy="$NO_PROXY_HOSTS" \
-f src/LiveRecorder.WebApi/Dockerfile -t "$api_ref" --push . -f src/LiveRecorder.WebApi/Dockerfile -t "$api_ref" --push .
./scripts/ci-docker.sh buildx prune \
--builder "$BUILDER_NAME" --all --force
./scripts/ci-docker.sh buildx build \ ./scripts/ci-docker.sh buildx build \
--builder "$BUILDER_NAME" --platform "$platform" --network host \ --builder "$BUILDER_NAME" --platform "$platform" --network host \
--progress=plain --provenance=false --no-cache \ --progress=plain --provenance=false \
--build-arg NODE_IMAGE="$NODE_BUILD_IMAGE" \ --build-arg NODE_IMAGE="$NODE_BUILD_IMAGE" \
--build-arg NGINX_IMAGE="$NGINX_IMAGE" \ --build-arg NGINX_IMAGE="$NGINX_IMAGE" \
--build-arg HTTP_PROXY="$HTTP_PROXY_URL" \ --build-arg HTTP_PROXY="$HTTP_PROXY_URL" \
@@ -319,8 +322,6 @@ pipeline {
--build-arg no_proxy="$NO_PROXY_HOSTS" \ --build-arg no_proxy="$NO_PROXY_HOSTS" \
--build-arg VITE_API_BASE_URL=/api \ --build-arg VITE_API_BASE_URL=/api \
-f frontend/Dockerfile -t "$web_ref" --push frontend -f frontend/Dockerfile -t "$web_ref" --push frontend
./scripts/ci-docker.sh buildx prune \
--builder "$BUILDER_NAME" --all --force
''' '''
} }
} }
@@ -410,9 +411,6 @@ pipeline {
)]) { )]) {
sh ''' sh '''
set +e set +e
if [ -x ./scripts/ci-docker.sh ] && [ -n "${BUILDER_NAME:-}" ]; then
./scripts/ci-docker.sh buildx rm -f "$BUILDER_NAME" >/dev/null 2>&1 || true
fi
if [ -x ./scripts/ci-docker.sh ] && [ -n "${IMMUTABLE_TAG:-}" ]; then if [ -x ./scripts/ci-docker.sh ] && [ -n "${IMMUTABLE_TAG:-}" ]; then
for repository in "$API_IMAGE_REPO" "$WEB_IMAGE_REPO"; do for repository in "$API_IMAGE_REPO" "$WEB_IMAGE_REPO"; do
for suffix in amd64 arm64; do for suffix in amd64 arm64; do
@@ -424,6 +422,11 @@ pipeline {
if [ -f "$DOCKER_CONFIG/config.json" ]; then if [ -f "$DOCKER_CONFIG/config.json" ]; then
: >"$DOCKER_CONFIG/config.json" : >"$DOCKER_CONFIG/config.json"
fi fi
if [ -x ./scripts/ci-docker.sh ] && [ -n "${BUILDER_NAME:-}" ]; then
./scripts/ci-docker.sh buildx prune \
--builder "$BUILDER_NAME" --filter until=168h \
--keep-storage 8gb --force >/dev/null 2>&1 || true
fi
if [ -d "${CI_ROOT:-}" ]; then if [ -d "${CI_ROOT:-}" ]; then
printf '%s\n' "$JENKINS_NODE_PASSWORD" | \ printf '%s\n' "$JENKINS_NODE_PASSWORD" | \
sudo -S -p '' chown -R -- "$(id -u):$(id -g)" "$CI_ROOT" || true sudo -S -p '' chown -R -- "$(id -u):$(id -g)" "$CI_ROOT" || true
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="HuaweiCloud" value="https://mirrors.huaweicloud.com/repository/nuget/v3/index.json" protocolVersion="3" />
</packageSources>
</configuration>
+5 -5
View File
@@ -1,6 +1,6 @@
services: services:
postgres: postgres:
image: ${POSTGRES_IMAGE:-postgres:16-alpine} image: ${POSTGRES_IMAGE:-docker.m.daocloud.io/library/postgres:16-alpine}
restart: unless-stopped restart: unless-stopped
environment: environment:
POSTGRES_DB: ${POSTGRES_DB:-live_recorder} POSTGRES_DB: ${POSTGRES_DB:-live_recorder}
@@ -21,8 +21,8 @@ services:
dockerfile: src/LiveRecorder.WebApi/Dockerfile dockerfile: src/LiveRecorder.WebApi/Dockerfile
network: host network: host
args: args:
DOTNET_SDK_IMAGE: ${DOTNET_SDK_IMAGE:-mcr.microsoft.com/dotnet/sdk:8.0-bookworm-slim} DOTNET_SDK_IMAGE: ${DOTNET_SDK_IMAGE:-mcr.m.daocloud.io/dotnet/sdk:8.0-bookworm-slim}
DOTNET_RUNTIME_IMAGE: ${DOTNET_RUNTIME_IMAGE:-mcr.microsoft.com/dotnet/aspnet:8.0-bookworm-slim} DOTNET_RUNTIME_IMAGE: ${DOTNET_RUNTIME_IMAGE:-mcr.m.daocloud.io/dotnet/aspnet:8.0-bookworm-slim}
restart: unless-stopped restart: unless-stopped
depends_on: depends_on:
postgres: postgres:
@@ -43,8 +43,8 @@ services:
dockerfile: Dockerfile dockerfile: Dockerfile
network: host network: host
args: args:
NODE_IMAGE: ${NODE_IMAGE:-node:22-alpine} NODE_IMAGE: ${NODE_IMAGE:-docker.m.daocloud.io/library/node:22-alpine}
NGINX_IMAGE: ${NGINX_IMAGE:-nginx:1.27-alpine} NGINX_IMAGE: ${NGINX_IMAGE:-docker.m.daocloud.io/library/nginx:1.27-alpine}
VITE_API_BASE_URL: /api VITE_API_BASE_URL: /api
restart: unless-stopped restart: unless-stopped
depends_on: depends_on:
+2 -2
View File
@@ -1,5 +1,5 @@
ARG NODE_IMAGE=node:22-alpine ARG NODE_IMAGE=docker.m.daocloud.io/library/node:22-alpine
ARG NGINX_IMAGE=nginx:1.27-alpine ARG NGINX_IMAGE=docker.m.daocloud.io/library/nginx:1.27-alpine
FROM ${NODE_IMAGE} AS build FROM ${NODE_IMAGE} AS build
WORKDIR /app WORKDIR /app
+1 -1
View File
@@ -1,4 +1,4 @@
ARG NGINX_IMAGE=nginx:1.27-alpine ARG NGINX_IMAGE=docker.m.daocloud.io/library/nginx:1.27-alpine
FROM ${NGINX_IMAGE} FROM ${NGINX_IMAGE}
+5 -5
View File
@@ -12,7 +12,7 @@
# #
# Target environment: Windows + Docker Desktop (WSL2 backend) + a host HTTP proxy. # Target environment: Windows + Docker Desktop (WSL2 backend) + a host HTTP proxy.
# It encodes the workarounds discovered while building from a network where the # It encodes the workarounds discovered while building from a network where the
# Docker daemon cannot reliably reach mcr.microsoft.com / Docker Hub: # Docker daemon cannot reliably reach upstream MCR / Docker Hub:
# #
# 1. ARM64 QEMU emulation is registered via binfmt_misc with the `F` # 1. ARM64 QEMU emulation is registered via binfmt_misc with the `F`
# (fix-binary) flag so the kernel-held fd works inside build containers. # (fix-binary) flag so the kernel-held fd works inside build containers.
@@ -42,10 +42,10 @@ API_IMAGE_TAG="${API_IMAGE_TAG:-live-recorder-webapi:arm64}"
FRONTEND_IMAGE_TAG="${FRONTEND_IMAGE_TAG:-live-recorder-frontend:arm64}" FRONTEND_IMAGE_TAG="${FRONTEND_IMAGE_TAG:-live-recorder-frontend:arm64}"
OUTPUT="${OUTPUT:-live-recorder-arm64.tar.gz}" OUTPUT="${OUTPUT:-live-recorder-arm64.tar.gz}"
WSL_DISTRO="${WSL_DISTRO:-Ubuntu}" WSL_DISTRO="${WSL_DISTRO:-Ubuntu}"
DOTNET_SDK_IMAGE="mcr.microsoft.com/dotnet/sdk:8.0-bookworm-slim" DOTNET_SDK_IMAGE="${DOTNET_SDK_IMAGE:-mcr.m.daocloud.io/dotnet/sdk:8.0-bookworm-slim}"
DOTNET_RUNTIME_IMAGE="mcr.microsoft.com/dotnet/aspnet:8.0-bookworm-slim" DOTNET_RUNTIME_IMAGE="${DOTNET_RUNTIME_IMAGE:-mcr.m.daocloud.io/dotnet/aspnet:8.0-bookworm-slim}"
NGINX_IMAGE="${NGINX_IMAGE:-nginx:1.27-alpine}" NGINX_IMAGE="${NGINX_IMAGE:-docker.m.daocloud.io/library/nginx:1.27-alpine}"
NO_PROXY_HOSTS="mirrors.tuna.tsinghua.edu.cn,.tsinghua.edu.cn,localhost,127.0.0.1" NO_PROXY_HOSTS="mirrors.tuna.tsinghua.edu.cn,.tsinghua.edu.cn,mirrors.huaweicloud.com,.huaweicloud.com,mcr.m.daocloud.io,docker.m.daocloud.io,.m.daocloud.io,localhost,127.0.0.1"
log() { printf '\n\033[1;36m[%s] %s\033[0m\n' "$(date +%H:%M:%S)" "$*"; } log() { printf '\n\033[1;36m[%s] %s\033[0m\n' "$(date +%H:%M:%S)" "$*"; }
die() { printf '\n\033[1;31mERROR: %s\033[0m\n' "$*" >&2; exit 1; } die() { printf '\n\033[1;31mERROR: %s\033[0m\n' "$*" >&2; exit 1; }
+1 -1
View File
@@ -75,7 +75,7 @@ npm run build --prefix "$ROOT_DIR/frontend"
printf 'Publishing self-contained .NET application...\n' printf 'Publishing self-contained .NET application...\n'
export NUGET_PACKAGES DOTNET_CLI_HOME export NUGET_PACKAGES DOTNET_CLI_HOME
RESTORE_SOURCES=(--source "https://api.nuget.org/v3/index.json") RESTORE_SOURCES=(--source "https://mirrors.huaweicloud.com/repository/nuget/v3/index.json")
if [ -d "$NUGET_FEED" ]; then if [ -d "$NUGET_FEED" ]; then
RESTORE_SOURCES=(--source "$NUGET_FEED" "${RESTORE_SOURCES[@]}") RESTORE_SOURCES=(--source "$NUGET_FEED" "${RESTORE_SOURCES[@]}")
fi fi
+4 -5
View File
@@ -1,12 +1,11 @@
ARG DOTNET_SDK_IMAGE=mcr.microsoft.com/dotnet/sdk:8.0-bookworm-slim ARG DOTNET_SDK_IMAGE=mcr.m.daocloud.io/dotnet/sdk:8.0-bookworm-slim
ARG DOTNET_RUNTIME_IMAGE=mcr.microsoft.com/dotnet/aspnet:8.0-bookworm-slim ARG DOTNET_RUNTIME_IMAGE=mcr.m.daocloud.io/dotnet/aspnet:8.0-bookworm-slim
FROM ${DOTNET_SDK_IMAGE} AS build FROM ${DOTNET_SDK_IMAGE} AS build
WORKDIR /src WORKDIR /src
# Proxy settings for NuGet restore (nuget.org is only reachable via the proxy # Keep proxy settings available for any package endpoint fallback. The primary
# from the build network). Declared as ARG then promoted to ENV so dotnet and # NuGet source is pinned to the domestic mirror in the repository NuGet.config.
# the underlying HttpClient pick them up during restore/publish.
ARG HTTP_PROXY ARG HTTP_PROXY
ARG HTTPS_PROXY ARG HTTPS_PROXY
ARG NO_PROXY ARG NO_PROXY