Files
SubConverter-Extended/docker/Dockerfile.debian
2026-05-30 23:03:43 +08:00

214 lines
7.9 KiB
Docker

# ========== GO BUILD STAGE ==========
FROM mirror.gcr.io/library/golang:latest AS go-builder
# Docker Buildx 自动注入目标架构信息
ARG TARGETARCH
ARG TARGETVARIANT
ARG MIHOMO_REF="Meta"
ARG MIHOMO_CACHE_BUST=1
ARG REFRESH_GO_DEPS=false
WORKDIR /build/bridge
# Install build dependencies (gcc required for CGO)
# 包含 ARMv7 交叉编译工具链
RUN apt-get update && \
apt-get install -y --no-install-recommends git build-essential && \
if [ "$(dpkg --print-architecture)" != "armhf" ]; then \
apt-get install -y --no-install-recommends gcc-arm-linux-gnueabihf; \
fi && \
rm -rf /var/lib/apt/lists/*
# Copy committed Go module files and source.
COPY bridge/go.mod bridge/go.sum ./
COPY bridge/converter.go ./
COPY bridge/preprocess.go ./
RUN set -xe && \
if [ "${REFRESH_GO_DEPS}" = "true" ]; then \
echo "MIHOMO_CACHE_BUST=$MIHOMO_CACHE_BUST" && \
go get github.com/metacubex/mihomo@${MIHOMO_REF} && \
go get -u all && \
go mod tidy; \
else \
go mod download; \
fi
# Copy scripts for scheme generation
COPY scripts/ ../scripts/
RUN go run ../scripts/generate_schemes.go mihomo_schemes.h
RUN go run ../scripts/generate_param_compat.go -o param_compat.h
# Build static library (enable CGO for glibc)
# 根据目标架构自动配置交叉编译环境
# 注意:不使用 -ldflags="-s -w",因为移除符号表会导致 CGO 程序 Segfault
RUN if [ "$TARGETARCH" = "arm" ] && [ "$TARGETVARIANT" = "v7" ]; then \
echo "==> Building for ARMv7" && \
export CGO_ENABLED=1 \
GOOS=linux \
GOARCH=arm \
GOARM=7; \
if [ "$(dpkg --print-architecture)" != "armhf" ]; then \
export CC=arm-linux-gnueabihf-gcc; \
fi; \
else \
echo "==> Native build for $TARGETARCH" && \
export CGO_ENABLED=1; \
fi && \
go build \
-buildmode=c-archive \
-o libmihomo.a \
.
# Verify build output
RUN ls -lh libmihomo.a libmihomo.h
# ========== C++ BUILD STAGE ==========
FROM mirror.gcr.io/library/debian:latest AS builder
ARG THREADS="4"
ARG SHA=""
ARG VERSION="dev"
ARG BUILD_DATE=""
ARG REFRESH_HEADERS=false
ARG QUICKJSPP_REF="01cdd3047ced48265b127790848a0ca88204f2c7"
ARG LIBCRON_REF="v1.3.3"
ARG TOML11_REF="v4.4.0"
WORKDIR /
# Install build dependencies
RUN apt-get update && \
apt-get install -y --no-install-recommends \
git g++ build-essential cmake python3 python3-pip \
pkg-config curl \
libcurl4-openssl-dev libpcre2-dev rapidjson-dev \
libyaml-cpp-dev ca-certificates ninja-build ccache && \
rm -rf /var/lib/apt/lists/*
# quickjspp
RUN set -xe && \
git init quickjspp && \
cd quickjspp && \
git remote add origin https://github.com/ftk/quickjspp.git && \
git fetch --depth=1 origin "${QUICKJSPP_REF}" && \
git checkout --detach FETCH_HEAD && \
git submodule update --init && \
cmake -DCMAKE_BUILD_TYPE=Release . && \
make quickjs -j ${THREADS} && \
install -d /usr/lib/quickjs/ && \
install -m644 quickjs/libquickjs.a /usr/lib/quickjs/ && \
install -d /usr/include/quickjs/ && \
install -m644 quickjs/quickjs.h quickjs/quickjs-libc.h /usr/include/quickjs/ && \
install -m644 quickjspp.hpp /usr/include
# libcron
RUN set -xe && \
git init libcron && \
cd libcron && \
git remote add origin https://github.com/PerMalmberg/libcron && \
git fetch --depth=1 origin "${LIBCRON_REF}" && \
git checkout --detach FETCH_HEAD && \
git submodule update --init && \
cmake -DCMAKE_BUILD_TYPE=Release . && \
make libcron -j ${THREADS} && \
install -m644 libcron/out/Release/liblibcron.a /usr/lib/ && \
install -d /usr/include/libcron/ && \
install -m644 libcron/include/libcron/* /usr/include/libcron/ && \
install -d /usr/include/date/ && \
install -m644 libcron/externals/date/include/date/* /usr/include/date/
RUN set -xe && \
git init toml11 && \
cd toml11 && \
git remote add origin https://github.com/ToruNiina/toml11 && \
git fetch --depth=1 origin "${TOML11_REF}" && \
git checkout --detach FETCH_HEAD && \
cmake -DCMAKE_CXX_STANDARD=11 . && \
make install -j ${THREADS}
# Copy Go library and module files from go-builder stage
COPY --from=go-builder /build/bridge/libmihomo.a /usr/lib/
COPY --from=go-builder /build/bridge/libmihomo.h /usr/include/
COPY --from=go-builder /build/bridge/go.mod /src/bridge/go.mod
COPY --from=go-builder /build/bridge/go.sum /src/bridge/go.sum
# build SubConverter-Extended from THIS repository source (provided by build context)
WORKDIR /src
COPY . /src
COPY --from=go-builder /build/bridge/mihomo_schemes.h /src/src/parser/mihomo_schemes.h
COPY --from=go-builder /build/bridge/param_compat.h /src/src/parser/param_compat.h
RUN set -xe && \
if [ "${REFRESH_HEADERS}" = "true" ]; then \
echo "Downloading latest cpp-httplib..." && \
curl -fsSL https://raw.githubusercontent.com/yhirose/cpp-httplib/master/httplib.h -o include/httplib.h && \
echo "Downloading latest nlohmann/json..." && \
curl -fsSL https://github.com/nlohmann/json/releases/latest/download/json.hpp -o include/nlohmann/json.hpp && \
echo "Downloading latest inja..." && \
curl -fsSL https://raw.githubusercontent.com/pantor/inja/master/single_include/inja/inja.hpp -o include/inja.hpp && \
echo "Downloading latest jpcre2..." && \
curl -fsSL https://raw.githubusercontent.com/jpcre2/jpcre2/master/src/jpcre2.hpp -o include/jpcre2.hpp && \
echo "Copying pinned quickjspp from compiled source..." && \
cp /usr/include/quickjspp.hpp include/quickjspp.hpp; \
else \
echo "Using committed header-only libraries"; \
fi
RUN set -xe && \
[ -n "${SHA}" ] && sed -i "s/#define BUILD_ID \"\"/#define BUILD_ID \"${SHA}\"/ " src/version.h || true && \
[ -n "${VERSION}" ] && sed -i "s/#define VERSION \"dev\"/#define VERSION \"${VERSION}\"/" src/version.h || true && \
[ -n "${BUILD_DATE}" ] && sed -i "s/#define BUILD_DATE \"\"/#define BUILD_DATE \"${BUILD_DATE}\"/" src/version.h || true && \
# Copy Go library to bridge directory for CMake detection
mkdir -p bridge && \
cp /usr/lib/libmihomo.a bridge/ && \
cp /usr/include/libmihomo.h bridge/ && \
# Configure ccache
export PATH="/usr/lib/ccache:$PATH" && \
export CCACHE_DIR=/tmp/ccache && \
export CCACHE_COMPILERCHECK=content && \
# Use Ninja generator and enable ccache
cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER_LAUNCHER=ccache . && \
# Parallelism is controlled by the workflow to avoid OOM on smaller targets.
ninja -j ${THREADS}
# ========== FINAL STAGE ==========
FROM mirror.gcr.io/library/debian:latest
ARG VERSION="dev"
ARG SHA=""
ARG BUILD_DATE=""
LABEL \
org.opencontainers.image.title="SubConverter-Extended" \
org.opencontainers.image.description="A Modern Evolution of subconverter; an enhanced implementation aligned with Mihomo configuration" \
org.opencontainers.image.url="https://github.com/Aethersailor/SubConverter-Extended" \
org.opencontainers.image.source="https://github.com/Aethersailor/SubConverter-Extended" \
org.opencontainers.image.licenses="GPL-3.0" \
org.opencontainers.image.version="${VERSION}" \
org.opencontainers.image.revision="${SHA}" \
org.opencontainers.image.created="${BUILD_DATE}" \
maintainer="Aethersailor"
# Install runtime dependencies
ENV TZ=Asia/Shanghai
RUN apt-get update && \
if apt-cache policy libcurl4 | grep -q 'Candidate: (none)'; then \
curl_runtime=libcurl4t64; \
else \
curl_runtime=libcurl4; \
fi && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
libpcre2-8-0 "$curl_runtime" libyaml-cpp-dev ca-certificates tzdata && \
ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && \
echo $TZ > /etc/timezone && \
rm -rf /var/lib/apt/lists/*
COPY --from=builder /src/subconverter /usr/bin/subconverter
COPY --from=builder /src/base /base/
# 确保二进制可执行
RUN chmod +x /usr/bin/subconverter
WORKDIR /base
CMD ["/usr/bin/subconverter"]
EXPOSE 25500/tcp