Use runtime base to break gateway build cycle
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
PORT=3456
|
||||
BASE_IMAGE=debian:bookworm-slim
|
||||
SINGBOX_VERSION=1.12.13
|
||||
INSTALL_RUNTIME_DEPS=true
|
||||
INSTALL_SINGBOX=true
|
||||
PROXY_PORT=8080
|
||||
PROXY_BIND_IP=0.0.0.0
|
||||
TPROXY_PORT=7895
|
||||
|
||||
@@ -7,7 +7,7 @@ on:
|
||||
|
||||
env:
|
||||
DEPLOY_PATH: /opt/vpn-proxy
|
||||
BASE_IMAGE: mirror.gcr.io/library/debian:bookworm-slim
|
||||
BASE_IMAGE: vpn-proxy-runtime-base:bookworm-slim
|
||||
SINGBOX_VERSION: 1.12.13
|
||||
|
||||
jobs:
|
||||
@@ -39,6 +39,11 @@ jobs:
|
||||
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'
|
||||
docker image inspect "${{ env.BASE_IMAGE }}" >/dev/null || {
|
||||
echo "Runtime base image ${{ env.BASE_IMAGE }} is missing on lxc-107."
|
||||
echo "Seed it once on 107 with: ./scripts/build-runtime-base.sh"
|
||||
exit 1
|
||||
}
|
||||
|
||||
echo "${{ secrets.REGISTRY_TOKEN }}" | docker login "$REGISTRY_HOST" -u "${{ gitea.actor }}" --password-stdin
|
||||
DOCKER_BUILDKIT=1 docker build \
|
||||
@@ -46,6 +51,8 @@ jobs:
|
||||
--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 }}" \
|
||||
.
|
||||
|
||||
43
Dockerfile
43
Dockerfile
@@ -1,24 +1,37 @@
|
||||
ARG BASE_IMAGE=debian:bookworm-slim
|
||||
FROM ${BASE_IMAGE}
|
||||
ARG SINGBOX_VERSION=1.12.13
|
||||
ARG INSTALL_RUNTIME_DEPS=true
|
||||
ARG INSTALL_SINGBOX=true
|
||||
COPY dist /app/dist
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends ca-certificates curl iptables ipset iproute2 nodejs dumb-init \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
RUN if [ "${INSTALL_RUNTIME_DEPS}" = "true" ]; then \
|
||||
apt-get update \
|
||||
&& apt-get install -y --no-install-recommends ca-certificates curl iptables ipset iproute2 nodejs dumb-init \
|
||||
&& rm -rf /var/lib/apt/lists/*; \
|
||||
else \
|
||||
command -v dumb-init >/dev/null \
|
||||
&& command -v node >/dev/null \
|
||||
&& command -v iptables >/dev/null \
|
||||
&& command -v ipset >/dev/null; \
|
||||
fi
|
||||
|
||||
RUN set -eux; \
|
||||
arch="$(dpkg --print-architecture)"; \
|
||||
case "$arch" in \
|
||||
amd64) sb_arch="amd64" ;; \
|
||||
arm64) sb_arch="arm64" ;; \
|
||||
*) echo "Unsupported architecture: $arch" >&2; exit 1 ;; \
|
||||
esac; \
|
||||
curl -fsSL "https://github.com/SagerNet/sing-box/releases/download/v${SINGBOX_VERSION}/sing-box-${SINGBOX_VERSION}-linux-${sb_arch}.tar.gz" -o /tmp/sing-box.tgz; \
|
||||
tar -xzf /tmp/sing-box.tgz -C /tmp; \
|
||||
mv "/tmp/sing-box-${SINGBOX_VERSION}-linux-${sb_arch}/sing-box" /usr/local/bin/sing-box; \
|
||||
chmod +x /usr/local/bin/sing-box; \
|
||||
rm -rf /tmp/sing-box*
|
||||
RUN if [ "${INSTALL_SINGBOX}" = "true" ]; then \
|
||||
set -eux; \
|
||||
arch="$(dpkg --print-architecture)"; \
|
||||
case "$arch" in \
|
||||
amd64) sb_arch="amd64" ;; \
|
||||
arm64) sb_arch="arm64" ;; \
|
||||
*) echo "Unsupported architecture: $arch" >&2; exit 1 ;; \
|
||||
esac; \
|
||||
curl -fsSL "https://github.com/SagerNet/sing-box/releases/download/v${SINGBOX_VERSION}/sing-box-${SINGBOX_VERSION}-linux-${sb_arch}.tar.gz" -o /tmp/sing-box.tgz; \
|
||||
tar -xzf /tmp/sing-box.tgz -C /tmp; \
|
||||
mv "/tmp/sing-box-${SINGBOX_VERSION}-linux-${sb_arch}/sing-box" /usr/local/bin/sing-box; \
|
||||
chmod +x /usr/local/bin/sing-box; \
|
||||
rm -rf /tmp/sing-box*; \
|
||||
else \
|
||||
command -v sing-box >/dev/null; \
|
||||
fi
|
||||
|
||||
WORKDIR /app
|
||||
COPY package.json /app/package.json
|
||||
|
||||
20
Dockerfile.runtime-base
Normal file
20
Dockerfile.runtime-base
Normal file
@@ -0,0 +1,20 @@
|
||||
ARG BASE_IMAGE=mirror.gcr.io/library/debian:bookworm-slim
|
||||
FROM ${BASE_IMAGE}
|
||||
ARG SINGBOX_VERSION=1.12.13
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends ca-certificates curl iptables ipset iproute2 nodejs dumb-init \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN set -eux; \
|
||||
arch="$(dpkg --print-architecture)"; \
|
||||
case "$arch" in \
|
||||
amd64) sb_arch="amd64" ;; \
|
||||
arm64) sb_arch="arm64" ;; \
|
||||
*) echo "Unsupported architecture: $arch" >&2; exit 1 ;; \
|
||||
esac; \
|
||||
curl -fsSL "https://github.com/SagerNet/sing-box/releases/download/v${SINGBOX_VERSION}/sing-box-${SINGBOX_VERSION}-linux-${sb_arch}.tar.gz" -o /tmp/sing-box.tgz; \
|
||||
tar -xzf /tmp/sing-box.tgz -C /tmp; \
|
||||
mv "/tmp/sing-box-${SINGBOX_VERSION}-linux-${sb_arch}/sing-box" /usr/local/bin/sing-box; \
|
||||
chmod +x /usr/local/bin/sing-box; \
|
||||
rm -rf /tmp/sing-box*
|
||||
10
README.md
10
README.md
@@ -288,6 +288,14 @@ BUILD_HOST=107 DEPLOY_HOST=111 ./scripts/build-on-107-deploy-111.sh
|
||||
|
||||
Скрипт собирает image на `BUILD_HOST`, переносит его на `DEPLOY_HOST` через `docker save | docker load` и запускает без `docker pull`. Если `107`/`111` не являются SSH-алиасами, укажите реальные адреса, например `BUILD_HOST=root@192.168.1.107 DEPLOY_HOST=root@192.168.1.111`.
|
||||
|
||||
Чтобы не получать циклическую зависимость "собрать gateway можно только через уже работающий gateway", подготовьте runtime base на `107` один раз:
|
||||
|
||||
```bash
|
||||
./scripts/build-runtime-base.sh
|
||||
```
|
||||
|
||||
После этого CI и `build-on-107-deploy-111.sh` используют локальный `vpn-proxy-runtime-base:bookworm-slim`: основная сборка gateway больше не делает `apt-get`, не качает sing-box и не обращается к Docker Hub за base image.
|
||||
|
||||
UI доступен на `http://<gateway-ip>:3456`.
|
||||
|
||||
На роутере указать шлюз по умолчанию (или нужные подсети) на IP контейнера.
|
||||
@@ -301,6 +309,8 @@ UI доступен на `http://<gateway-ip>:3456`.
|
||||
| `PORT` | `3456` | Порт веб-интерфейса |
|
||||
| `BASE_IMAGE` | `debian:bookworm-slim` | Базовый Docker image для сборки; можно заменить на mirror |
|
||||
| `SINGBOX_VERSION` | `1.12.13` | Версия sing-box для Docker build |
|
||||
| `INSTALL_RUNTIME_DEPS` | `true` | Устанавливать runtime-пакеты в Docker build; `false` для подготовленного runtime base |
|
||||
| `INSTALL_SINGBOX` | `true` | Скачивать sing-box в Docker build; `false` для подготовленного runtime base |
|
||||
| `PROXY_PORT` | `8080` | HTTP/SOCKS mixed inbound |
|
||||
| `TPROXY_PORT` | `7895` | TProxy inbound sing-box |
|
||||
| `DATA_DIR` | `/var/lib/vpn-proxy` | Директория данных (volume) |
|
||||
|
||||
@@ -6,6 +6,8 @@ services:
|
||||
args:
|
||||
BASE_IMAGE: ${BASE_IMAGE:-debian:bookworm-slim}
|
||||
SINGBOX_VERSION: ${SINGBOX_VERSION:-1.12.13}
|
||||
INSTALL_RUNTIME_DEPS: ${INSTALL_RUNTIME_DEPS:-true}
|
||||
INSTALL_SINGBOX: ${INSTALL_SINGBOX:-true}
|
||||
container_name: vpn-proxy-gateway
|
||||
network_mode: host
|
||||
cap_add:
|
||||
|
||||
@@ -9,9 +9,11 @@ IMAGE_NAME="${IMAGE_NAME:-vpn-proxy-gateway}"
|
||||
GIT_REF="$(git rev-parse --short HEAD 2>/dev/null || echo manual)"
|
||||
IMAGE_TAG="${IMAGE_TAG:-${GIT_REF}-$(date +%Y%m%d%H%M%S)}"
|
||||
GATEWAY_IMAGE="${GATEWAY_IMAGE:-${IMAGE_NAME}:${IMAGE_TAG}}"
|
||||
BASE_IMAGE="${BASE_IMAGE:-mirror.gcr.io/library/debian:bookworm-slim}"
|
||||
BASE_IMAGE="${BASE_IMAGE:-vpn-proxy-runtime-base:bookworm-slim}"
|
||||
SINGBOX_VERSION="${SINGBOX_VERSION:-1.12.13}"
|
||||
DOCKER_BUILD_PULL="${DOCKER_BUILD_PULL:-false}"
|
||||
INSTALL_RUNTIME_DEPS="${INSTALL_RUNTIME_DEPS:-false}"
|
||||
INSTALL_SINGBOX="${INSTALL_SINGBOX:-false}"
|
||||
|
||||
echo "Build host: ${BUILD_HOST}"
|
||||
echo "Deploy host: ${DEPLOY_HOST}"
|
||||
@@ -29,7 +31,7 @@ rsync -az --delete \
|
||||
|
||||
echo "Building image on ${BUILD_HOST}"
|
||||
ssh "${BUILD_HOST}" \
|
||||
"set -e; 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'; cd '${BUILD_PATH}' && npm ci && npm run build && docker build --pull='${DOCKER_BUILD_PULL}' --build-arg BASE_IMAGE='${BASE_IMAGE}' --build-arg SINGBOX_VERSION='${SINGBOX_VERSION}' -t '${GATEWAY_IMAGE}' ."
|
||||
"set -e; 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'; docker image inspect '${BASE_IMAGE}' >/dev/null || { echo 'Runtime base image ${BASE_IMAGE} is missing on ${BUILD_HOST}.'; echo 'Seed it once with: ./scripts/build-runtime-base.sh'; exit 1; }; cd '${BUILD_PATH}' && npm ci && npm run build && docker build --pull='${DOCKER_BUILD_PULL}' --build-arg BASE_IMAGE='${BASE_IMAGE}' --build-arg SINGBOX_VERSION='${SINGBOX_VERSION}' --build-arg INSTALL_RUNTIME_DEPS='${INSTALL_RUNTIME_DEPS}' --build-arg INSTALL_SINGBOX='${INSTALL_SINGBOX}' -t '${GATEWAY_IMAGE}' ."
|
||||
|
||||
echo "Loading image into ${DEPLOY_HOST}"
|
||||
ssh "${BUILD_HOST}" "docker save '${GATEWAY_IMAGE}'" | ssh "${DEPLOY_HOST}" "docker load"
|
||||
|
||||
16
scripts/build-runtime-base.sh
Executable file
16
scripts/build-runtime-base.sh
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
BASE_IMAGE="${BASE_IMAGE:-mirror.gcr.io/library/debian:bookworm-slim}"
|
||||
RUNTIME_BASE_IMAGE="${RUNTIME_BASE_IMAGE:-vpn-proxy-runtime-base:bookworm-slim}"
|
||||
SINGBOX_VERSION="${SINGBOX_VERSION:-1.12.13}"
|
||||
|
||||
echo "Building runtime base: ${RUNTIME_BASE_IMAGE}"
|
||||
echo "Source base image: ${BASE_IMAGE}"
|
||||
|
||||
docker build \
|
||||
--build-arg BASE_IMAGE="${BASE_IMAGE}" \
|
||||
--build-arg SINGBOX_VERSION="${SINGBOX_VERSION}" \
|
||||
-f Dockerfile.runtime-base \
|
||||
-t "${RUNTIME_BASE_IMAGE}" \
|
||||
.
|
||||
Reference in New Issue
Block a user