From 3114521a35dbb581cbe7730005ef20ad921a1f00 Mon Sep 17 00:00:00 2001 From: Wang Defa <1+wangdefa@noreply.gitea.bcde.io> Date: Wed, 10 Jun 2026 09:40:10 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E7=94=A8=20musl=20=E5=85=A8=E9=9D=99?= =?UTF-8?q?=E6=80=81=E4=BF=AE=E5=A4=8D=20DNS=20=E8=A7=A3=E6=9E=90=EF=BC=8C?= =?UTF-8?q?=E5=B9=B6=E8=A7=84=E8=8C=83=20Dockerfile=20=E4=B8=8E=E4=BA=A7?= =?UTF-8?q?=E7=89=A9=E5=91=BD=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- .gitea/workflows/ci.yaml | 12 +++--- CLAUDE.md | 13 +++--- README.md | 12 +++--- debian/build-deb.sh | 2 +- docker/{Dockerfile.alpine => Dockerfile} | 0 docker/Dockerfile.ubuntu | 50 ------------------------ 6 files changed, 19 insertions(+), 70 deletions(-) rename docker/{Dockerfile.alpine => Dockerfile} (100%) delete mode 100644 docker/Dockerfile.ubuntu diff --git a/.gitea/workflows/ci.yaml b/.gitea/workflows/ci.yaml index 5da9beb..603fae7 100644 --- a/.gitea/workflows/ci.yaml +++ b/.gitea/workflows/ci.yaml @@ -18,7 +18,6 @@ jobs: strategy: matrix: arch: [amd64, arm64] - distro: [ubuntu, alpine] steps: - uses: actions/checkout@v4 @@ -39,7 +38,7 @@ jobs: PLATFORM="linux/${{ matrix.arch }}" echo "🏗️ Building ${PLATFORM} on native ${{ matrix.arch }} runner" - echo "📦 Distribution: ${{ matrix.distro }}" + echo "📦 Build: musl 全静态 (docker/Dockerfile, 基于 alpine)" # 设置 BuildKit 优化参数 export BUILDKIT_PROGRESS=plain @@ -48,7 +47,7 @@ jobs: --platform ${PLATFORM} \ --build-arg XXXIG_PROXY_VERSION=${XXXIG_PROXY_VERSION} \ --output type=local,dest=./output \ - -f docker/Dockerfile.${{ matrix.distro }} . + -f docker/Dockerfile . - name: Package and test run: | @@ -59,7 +58,7 @@ jobs: exit 1 fi - TARGZ="${PRODUCT_NAME}-${{ matrix.arch }}-${{ matrix.distro }}-${PACKAGE_VERSION}.tar.gz" + TARGZ="${PRODUCT_NAME}-${{ matrix.arch }}-linux-static-${PACKAGE_VERSION}.tar.gz" tar -czf "${TARGZ}" -C "$DIR" . echo "📦 Created package: ${TARGZ}" @@ -71,12 +70,11 @@ jobs: rm -rf test - name: Build Debian package - if: matrix.distro == 'ubuntu' run: | # 安装 dpkg-deb(如果需要) sudo apt-get update && sudo apt-get install -y dpkg-dev - TARGZ="${PRODUCT_NAME}-${{ matrix.arch }}-${{ matrix.distro }}-${PACKAGE_VERSION}.tar.gz" + TARGZ="${PRODUCT_NAME}-${{ matrix.arch }}-linux-static-${PACKAGE_VERSION}.tar.gz" echo "📦 Building Debian package for ${{ matrix.arch }}..." chmod +x debian/build-deb.sh @@ -86,7 +84,7 @@ jobs: - uses: https://github.com/ChristopherHX/gitea-upload-artifact@v4 with: - name: binaries-${{ matrix.arch }}-${{ matrix.distro }} + name: binaries-${{ matrix.arch }} path: | *.tar.gz *.deb diff --git a/CLAUDE.md b/CLAUDE.md index 2a3badc..f1f28df 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -21,15 +21,16 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co [.gitea/workflows/ci.yaml](.gitea/workflows/ci.yaml) 是 Gitea Actions 流水线: -1. **build-and-test**(矩阵 `arch=[amd64,arm64] × distro=[ubuntu,alpine]`,跑在对应架构的原生 runner 上):用 `docker buildx` 按 `docker/Dockerfile.{distro}` 原生编译 → 打成 tar.gz → 仅 ubuntu distro 再调 `debian/build-deb.sh` 打 .deb → 上传 artifact。 +1. **build-and-test**(矩阵 `arch=[amd64,arm64]`,跑在对应架构的原生 runner 上):用 `docker buildx` 按 `docker/Dockerfile` 原生编译 → 打成 tar.gz → 调 `debian/build-deb.sh` 打 .deb → 上传 artifact。 2. **release**(仅 tag 触发):下载 artifact,上传 tar.gz 到 Generic Package Registry、上传 .deb 到 Debian Registry(stable/main),并用 `jq` 生成描述创建 Gitea Release。 关键点: - 版本号**硬编码**在 ci.yaml 的 `PACKAGE_VERSION: "6.26.0"`(纯数字,符合 Debian 版本规范),发版改这里。**关键分界**:上游源码 git tag 带 `v`(CI 用 `XXXIG_PROXY_VERSION=v${PACKAGE_VERSION}` 检出 `v6.26.0`),而 tar.gz/deb/registry 路径等包版本一律用数字;release job 用 `VERSION="${TAG#v}"` 归一,build-deb.sh 用 `DEB_VERSION="${VERSION#v}"` 归一。 - Dockerfile build-arg 名为 `XXXIG_PROXY_VERSION`(注意 `_PROXY_`,与矿工的 `XXXIG_VERSION` 区分),ci.yaml 与两个 Dockerfile 三处必须一致。 -- **静态构建(对齐矿工)**:Dockerfile 先 `cd scripts && ./build_deps.sh` 编译静态 libuv/OpenSSL 到 `scripts/deps`,再 `cmake .. -DXMRIG_DEPS=scripts/deps -DBUILD_STATIC=ON` 全静态链接(proxy 的 `cmake/OpenSSL.cmake` 仅在 WIN/APPLE 下设静态,Linux 靠 flags.cmake 在 `BUILD_STATIC` 下加 `-static` 强制全静态)。产物 `ldd` 为 "not a dynamic executable",任意发行版可跑。Dockerfile.ubuntu 基于 `ubuntu:20.04`。 +- **静态构建(musl,对齐矿工)**:Dockerfile 先 `cd scripts && ./build_deps.sh` 编译静态 libuv/OpenSSL 到 `scripts/deps`,再 `cmake .. -DXMRIG_DEPS=scripts/deps -DBUILD_STATIC=ON` 全静态链接(proxy 的 `cmake/OpenSSL.cmake` 仅在 WIN/APPLE 下设静态,Linux 靠 flags.cmake 在 `BUILD_STATIC` 下加 `-static` 强制全静态)。产物 `ldd` 为 "not a dynamic executable",任意发行版可跑。`docker/Dockerfile` 基于 `alpine:latest`(musl libc)。 +- **为何必须用 musl 而非 glibc(关键,勿改回)**:glibc 的 `getaddrinfo` 依赖运行时 `dlopen` NSS 模块(`libnss_*.so`),`-static` 全静态后无法加载,跨 glibc 版本运行时 DNS 解析直接失败——表现为 `DNS error: "resource busy or locked"`(`getaddrinfo` 返回 `EAI_SYSTEM` + `errno=EBUSY`,libuv 经 `uv__getaddrinfo_translate_error` 转成 `UV_EBUSY`,见 `src/base/net/dns/DnsUvBackend.cpp`)。musl 的 `getaddrinfo` 自带实现、不依赖 NSS dlopen,全静态也能正常解析。曾用的 glibc(`ubuntu:20.04`) 全静态构建线因此被删除。 - 架构名映射:`x86_64→amd64`、`aarch64→arm64`。 -- tar.gz 下载 URL 形如 `https://gitea.bcde.io/api/packages/wangdefa/generic/xxxig-proxy/{version}/xxxig-proxy-{arch}-{os}-{version}.tar.gz`。 +- tar.gz 下载 URL 形如 `https://gitea.bcde.io/api/packages/wangdefa/generic/xxxig-proxy/{version}/xxxig-proxy-{arch}-linux-static-{version}.tar.gz`。 ## 本地常用命令 @@ -38,10 +39,10 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co docker buildx build --platform linux/amd64 \ --build-arg XXXIG_PROXY_VERSION=v6.26.0 \ --output type=local,dest=./output \ - -f docker/Dockerfile.ubuntu . + -f docker/Dockerfile . # 用已有 tar.gz 打 .deb 包 -./debian/build-deb.sh amd64 6.26.0 xxxig-proxy-amd64-ubuntu-6.26.0.tar.gz +./debian/build-deb.sh amd64 6.26.0 xxxig-proxy-amd64-linux-static-6.26.0.tar.gz # 改 shell 脚本后做静态检查(需自行安装 shellcheck) shellcheck debian/*.sh @@ -54,4 +55,4 @@ shellcheck debian/*.sh - 二进制装到 `/opt/xxxig-proxy/`,systemd 服务文件 `debian/xxxig-proxy.service`,维护脚本 `debian/{postinst,prerm,postrm}`。 - postinst 创建 `xxxig-proxy` 系统用户、把默认配置复制到 `/etc/xxxig-proxy/config.json`、`/opt` 归 `root:root`(目录/二进制 755、数据文件 644)。**服务不自动启用/启动**(默认上游 `localhost` 无效),升级时仅 `try-restart` 已在运行的服务。 - 本仓库**不含 `script/` 安装脚本**(与矿工项目不同),.deb 安装后需用户手动 `systemctl enable --now xxxig-proxy`。 -- **运行时依赖**:产物全静态(含 OpenSSL/libuv),`control.template` 仅 `Depends: libc6` 即可,无需 libssl/libuv。改用静态构建正是为修复动态链接 OpenSSL 1.1 在新发行版上 `libssl.so.1.1 not found` 的问题。源码 `scripts/`(build_deps/build.uv/build.openssl3)由矿工项目移植、去掉 hwloc。 +- **运行时依赖**:产物 musl 全静态(含 OpenSSL/libuv),无任何外部动态库依赖(`ldd` 为 "not a dynamic executable");`control.template` 的 `Depends: libc6` 对 musl 静态并非必需,仅作保守声明(deb 安装环境必有 libc6,无害)。改用静态构建正是为修复动态链接 OpenSSL 1.1 在新发行版上 `libssl.so.1.1 not found` 的问题。源码 `scripts/`(build_deps/build.uv/build.openssl3)由矿工项目移植、去掉 hwloc。 diff --git a/README.md b/README.md index 6871469..1a3b6e5 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ XXXig Proxy 是 [XMRig-Proxy](https://github.com/xmrig/xmrig-proxy) 的定制构 |---|---| | `xxxig-proxy` | 矿机代理服务:监听矿机接入,聚合转发到上游矿池 | -支持架构 `amd64` / `arm64`,发行版 Ubuntu/Debian、Alpine。 +支持架构 `amd64` / `arm64`;musl 全静态,任意 Linux 发行版(Debian/Ubuntu/Alpine/CentOS 等)开箱即跑。 > 与矿工项目 `xxxig`(`xxxig` / `xxxigDaemon` / `xxxigServer` 三件套 + Web 控制台)不同,proxy 是**单二进制、无 C&C、无 GPU**。 @@ -49,7 +49,7 @@ sudo apt-get update && sudo apt-get install xxxig-proxy ```bash curl -fSL -o xxxig-proxy.tar.gz \ - https://gitea.bcde.io/api/packages/wangdefa/generic/xxxig-proxy/6.26.0/xxxig-proxy-amd64-ubuntu-6.26.0.tar.gz + https://gitea.bcde.io/api/packages/wangdefa/generic/xxxig-proxy/6.26.0/xxxig-proxy-amd64-linux-static-6.26.0.tar.gz tar -xzf xxxig-proxy.tar.gz ./xxxig-proxy -c config.json ``` @@ -58,7 +58,7 @@ tar -xzf xxxig-proxy.tar.gz CI 定义于 [.gitea/workflows/ci.yaml](.gitea/workflows/ci.yaml): -- **push 到 `main`/`develop`**:矩阵 `arch=[amd64,arm64] × distro=[ubuntu,alpine]`,在原生 runner 上用 Docker 编译为 tar.gz,ubuntu 再打 `.deb`。 +- **push 到 `main`/`develop`**:矩阵 `arch=[amd64,arm64]`,在原生 runner 上用 Docker(musl 全静态)编译为 tar.gz 并打 `.deb`。 - **打 tag**:产物上传到 Generic / Debian 包仓库并创建 Release。 本地构建: @@ -68,10 +68,10 @@ CI 定义于 [.gitea/workflows/ci.yaml](.gitea/workflows/ci.yaml): docker buildx build --platform linux/amd64 \ --build-arg XXXIG_PROXY_VERSION=v6.26.0 \ --output type=local,dest=./output \ - -f docker/Dockerfile.ubuntu . + -f docker/Dockerfile . # 用产物 tar.gz 打 .deb -./debian/build-deb.sh amd64 6.26.0 xxxig-proxy-amd64-ubuntu-6.26.0.tar.gz +./debian/build-deb.sh amd64 6.26.0 xxxig-proxy-amd64-linux-static-6.26.0.tar.gz ``` ## 版本号约定 @@ -85,6 +85,6 @@ docker buildx build --platform linux/amd64 \ ``` .gitea/workflows/ CI 流水线 -docker/ 各发行版 Dockerfile(从上游源码编译) +docker/ Dockerfile(musl 全静态,从上游源码编译) debian/ .deb 打包:control 模板、维护脚本、systemd 服务 ``` diff --git a/debian/build-deb.sh b/debian/build-deb.sh index 2117a36..90581a0 100755 --- a/debian/build-deb.sh +++ b/debian/build-deb.sh @@ -4,7 +4,7 @@ set -e # 参数检查 if [ $# -ne 3 ]; then echo "Usage: $0 " - echo "Example: $0 amd64 6.26.0 xxxig-proxy-amd64-ubuntu-6.26.0.tar.gz" + echo "Example: $0 amd64 6.26.0 xxxig-proxy-amd64-linux-static-6.26.0.tar.gz" exit 1 fi diff --git a/docker/Dockerfile.alpine b/docker/Dockerfile similarity index 100% rename from docker/Dockerfile.alpine rename to docker/Dockerfile diff --git a/docker/Dockerfile.ubuntu b/docker/Dockerfile.ubuntu deleted file mode 100644 index 2173e48..0000000 --- a/docker/Dockerfile.ubuntu +++ /dev/null @@ -1,50 +0,0 @@ -# 使用 Ubuntu 20.04 作为基础镜像(glibc 2.31,兼容更老系统) -FROM ubuntu:20.04 AS base - -ARG TARGETARCH -ARG BUILDPLATFORM - -ENV DEBIAN_FRONTEND=noninteractive - -RUN apt-get update && apt-get install -y \ - git \ - wget \ - build-essential \ - cmake \ - automake \ - autoconf \ - libtool \ - perl \ - && rm -rf /var/lib/apt/lists/* - -FROM base AS build - -ARG XXXIG_PROXY_VERSION -ARG TARGETARCH -ARG BUILDPLATFORM -ARG TARGETPLATFORM - -RUN git clone --recursive https://github.com/wangdefaa/xxxig-proxy.git && \ - cd xxxig-proxy && \ - git checkout ${XXXIG_PROXY_VERSION} - -WORKDIR /xxxig-proxy - -# 先编译静态依赖(libuv/OpenSSL)到 scripts/deps,再静态链接构建 proxy -RUN mkdir build && cd scripts && chmod +x ./*.sh && \ - if [ "$BUILDPLATFORM" != "$TARGETPLATFORM" ]; then \ - MAKE_JOBS="-j2"; \ - else \ - MAKE_JOBS="-j$(nproc)"; \ - fi && \ - echo "Building with parallel jobs: $MAKE_JOBS (cross-compile: $([ "$BUILDPLATFORM" != "$TARGETPLATFORM" ] && echo yes || echo no))" && \ - ./build_deps.sh $MAKE_JOBS && cd ../build && \ - cmake .. -DCMAKE_BUILD_TYPE=Release -DXMRIG_DEPS=scripts/deps -DBUILD_STATIC=ON && \ - make $MAKE_JOBS - -FROM scratch - -ARG TARGETARCH - -COPY --from=build /xxxig-proxy/build/xxxig-proxy /linux_${TARGETARCH}/xxxig-proxy -COPY --from=build /xxxig-proxy/src/config.json /linux_${TARGETARCH}/config.json \ No newline at end of file