diff --git a/.gitea/workflows/gateway-build.yml b/.gitea/workflows/gateway-build.yml index 4285837..deda33e 100644 --- a/.gitea/workflows/gateway-build.yml +++ b/.gitea/workflows/gateway-build.yml @@ -7,13 +7,12 @@ on: env: DEPLOY_PATH: /opt/vpn-proxy - DEPLOY_HOST: 192.168.50.111 BASE_IMAGE: vpn-proxy-runtime-base:bookworm-slim RUNTIME_BASE_SOURCE_IMAGE: mirror.gcr.io/library/debian:bookworm-slim SINGBOX_VERSION: 1.12.13 jobs: - build-and-deploy: + build-and-push: runs-on: ubuntu-22.04 steps: - name: Clone repository @@ -27,16 +26,67 @@ jobs: cd repo git checkout ${{ gitea.sha }} - - name: Build on runner 107 and deploy to 111 + - name: Build and push gateway image run: | set -euo pipefail cd repo - BUILD_HOST=local \ - DEPLOY_HOST="${{ env.DEPLOY_HOST }}" \ - DEPLOY_PATH="${{ env.DEPLOY_PATH }}" \ - BASE_IMAGE="${{ env.BASE_IMAGE }}" \ - RUNTIME_BASE_SOURCE_IMAGE="${{ env.RUNTIME_BASE_SOURCE_IMAGE }}" \ - SINGBOX_VERSION="${{ env.SINGBOX_VERSION }}" \ - IMAGE_TAG="${{ gitea.sha }}" \ - bash scripts/build-on-107-deploy-111.sh + npm ci --no-audit --no-fund + npm run build + + REGISTRY_HOST=$(echo "${{ gitea.server_url }}" | sed 's|https\?://||') + IMAGE="${REGISTRY_HOST}/${{ gitea.repository }}/gateway" + + echo "Build runner: $(hostname)" + echo "Base image: ${{ env.BASE_IMAGE }}" + echo "Docker context: $(docker context show 2>/dev/null || true)" + docker info 2>/dev/null | sed -n '/HTTP Proxy:/p;/HTTPS Proxy:/p;/Name:/p' + + if ! docker image inspect "${{ env.BASE_IMAGE }}" >/dev/null 2>&1; then + echo "Runtime base image ${{ env.BASE_IMAGE }} is missing; building it now." + BASE_IMAGE="${{ env.RUNTIME_BASE_SOURCE_IMAGE }}" \ + RUNTIME_BASE_IMAGE="${{ env.BASE_IMAGE }}" \ + SINGBOX_VERSION="${{ env.SINGBOX_VERSION }}" \ + ./scripts/build-runtime-base.sh + fi + + echo "${{ secrets.REGISTRY_TOKEN }}" | docker login "$REGISTRY_HOST" -u "${{ gitea.actor }}" --password-stdin + DOCKER_BUILDKIT=1 docker build \ + --network host \ + --pull=false \ + --build-arg BASE_IMAGE="${{ env.BASE_IMAGE }}" \ + --build-arg SINGBOX_VERSION="${{ env.SINGBOX_VERSION }}" \ + --build-arg INSTALL_RUNTIME_DEPS=false \ + --build-arg INSTALL_SINGBOX=false \ + -t "${IMAGE}:latest" \ + -t "${IMAGE}:${{ gitea.sha }}" \ + . + docker push "${IMAGE}:latest" + docker push "${IMAGE}:${{ gitea.sha }}" + + deploy: + runs-on: lxc-113 + needs: build-and-push + steps: + - name: Clone repository + env: + GIT_TOKEN: ${{ secrets.REGISTRY_TOKEN }} + run: | + set -euo pipefail + SERVER_HOST=$(echo "${{ gitea.server_url }}" | sed 's|https\?://||') + rm -rf repo + git clone --depth 2 "http://${{ gitea.actor }}:${GIT_TOKEN}@${SERVER_HOST}/${{ gitea.repository }}.git" repo + cd repo + git checkout ${{ gitea.sha }} + + - name: Pull and deploy gateway image + run: | + set -euo pipefail + cd repo + + REGISTRY_HOST=$(echo "${{ gitea.server_url }}" | sed 's|https\?://||') + IMAGE="${REGISTRY_HOST}/${{ gitea.repository }}/gateway" + + echo "Deploy runner: $(hostname)" + echo "${{ secrets.REGISTRY_TOKEN }}" | docker login "$REGISTRY_HOST" -u "${{ gitea.actor }}" --password-stdin + DEPLOY_PATH="${{ env.DEPLOY_PATH }}" GATEWAY_IMAGE="${IMAGE}:${{ gitea.sha }}" bash scripts/deploy-gateway.sh diff --git a/scripts/build-on-107-deploy-111.sh b/scripts/build-on-107-deploy-111.sh index 356c60a..ebbe678 100755 --- a/scripts/build-on-107-deploy-111.sh +++ b/scripts/build-on-107-deploy-111.sh @@ -16,6 +16,7 @@ DOCKER_BUILD_PULL="${DOCKER_BUILD_PULL:-false}" INSTALL_RUNTIME_DEPS="${INSTALL_RUNTIME_DEPS:-false}" INSTALL_SINGBOX="${INSTALL_SINGBOX:-false}" AUTO_BUILD_RUNTIME_BASE="${AUTO_BUILD_RUNTIME_BASE:-true}" +SSH_CONNECT_TIMEOUT="${SSH_CONNECT_TIMEOUT:-10}" echo "Build host: ${BUILD_HOST}" echo "Deploy host: ${DEPLOY_HOST}" @@ -35,13 +36,24 @@ ensure_known_host() { fi } +ssh_cmd() { + ssh \ + -o BatchMode=yes \ + -o ConnectTimeout="${SSH_CONNECT_TIMEOUT}" \ + -o ServerAliveInterval=15 \ + -o ServerAliveCountMax=4 \ + "$@" +} + echo "Syncing source to ${BUILD_HOST}:${BUILD_PATH}" if [ "${BUILD_HOST}" = "local" ]; then BUILD_PATH="$(pwd)" echo "Using local source at ${BUILD_PATH}" else - ssh "${BUILD_HOST}" "mkdir -p '${BUILD_PATH}'" + ensure_known_host "${BUILD_HOST}" + ssh_cmd "${BUILD_HOST}" "mkdir -p '${BUILD_PATH}'" rsync -az --delete \ + -e "ssh -o BatchMode=yes -o ConnectTimeout=${SSH_CONNECT_TIMEOUT} -o ServerAliveInterval=15 -o ServerAliveCountMax=4" \ --exclude '.git' \ --exclude '.vpn-proxy' \ --exclude 'node_modules' \ @@ -54,7 +66,8 @@ BUILD_COMMAND="set -e; echo 'Docker context:' \$(docker context show 2>/dev/null if [ "${BUILD_HOST}" = "local" ]; then bash -lc "${BUILD_COMMAND}" else - ssh "${BUILD_HOST}" "${BUILD_COMMAND}" + ensure_known_host "${BUILD_HOST}" + ssh_cmd "${BUILD_HOST}" "${BUILD_COMMAND}" fi echo "Loading image into ${DEPLOY_HOST}" @@ -62,12 +75,17 @@ if [ "${BUILD_HOST}" = "local" ] && [ "${DEPLOY_HOST}" = "local" ]; then docker image inspect "${GATEWAY_IMAGE}" >/dev/null elif [ "${BUILD_HOST}" = "local" ]; then ensure_known_host "${DEPLOY_HOST}" - docker save "${GATEWAY_IMAGE}" | ssh "${DEPLOY_HOST}" "docker load" + echo "Checking SSH access to ${DEPLOY_HOST}" + ssh_cmd "${DEPLOY_HOST}" "true" + echo "Transferring image to ${DEPLOY_HOST}" + docker save "${GATEWAY_IMAGE}" | ssh_cmd "${DEPLOY_HOST}" "docker load" elif [ "${DEPLOY_HOST}" = "local" ]; then - ssh "${BUILD_HOST}" "docker save '${GATEWAY_IMAGE}'" | docker load + ensure_known_host "${BUILD_HOST}" + ssh_cmd "${BUILD_HOST}" "docker save '${GATEWAY_IMAGE}'" | docker load else + ensure_known_host "${BUILD_HOST}" ensure_known_host "${DEPLOY_HOST}" - ssh "${BUILD_HOST}" "docker save '${GATEWAY_IMAGE}'" | ssh "${DEPLOY_HOST}" "docker load" + ssh_cmd "${BUILD_HOST}" "docker save '${GATEWAY_IMAGE}'" | ssh_cmd "${DEPLOY_HOST}" "docker load" fi echo "Copying deploy script to ${DEPLOY_HOST}:${DEPLOY_PATH}" @@ -76,8 +94,10 @@ if [ "${DEPLOY_HOST}" = "local" ]; then cp scripts/deploy-gateway.sh "${DEPLOY_PATH}/deploy-gateway.sh" else ensure_known_host "${DEPLOY_HOST}" - ssh "${DEPLOY_HOST}" "mkdir -p '${DEPLOY_PATH}'" - rsync -az scripts/deploy-gateway.sh "${DEPLOY_HOST}:${DEPLOY_PATH}/deploy-gateway.sh" + ssh_cmd "${DEPLOY_HOST}" "mkdir -p '${DEPLOY_PATH}'" + rsync -az \ + -e "ssh -o BatchMode=yes -o ConnectTimeout=${SSH_CONNECT_TIMEOUT} -o ServerAliveInterval=15 -o ServerAliveCountMax=4" \ + scripts/deploy-gateway.sh "${DEPLOY_HOST}:${DEPLOY_PATH}/deploy-gateway.sh" fi echo "Starting gateway on ${DEPLOY_HOST}" @@ -87,6 +107,6 @@ if [ "${DEPLOY_HOST}" = "local" ]; then DEPLOY_PATH="${DEPLOY_PATH}" GATEWAY_IMAGE="${GATEWAY_IMAGE}" PULL_IMAGE=false ./deploy-gateway.sh else ensure_known_host "${DEPLOY_HOST}" - ssh "${DEPLOY_HOST}" \ + ssh_cmd "${DEPLOY_HOST}" \ "cd '${DEPLOY_PATH}' && chmod +x ./deploy-gateway.sh && DEPLOY_PATH='${DEPLOY_PATH}' GATEWAY_IMAGE='${GATEWAY_IMAGE}' PULL_IMAGE=false ./deploy-gateway.sh" fi