侧边栏壁纸
博主头像
Ivan Zhang

所谓更牛,就是换个罪受

  • 累计撰写 52 篇文章
  • 累计创建 57 个标签
  • 累计收到 6 条评论

目 录CONTENT

文章目录

ZeroTier One 1.16.2 QPKG 离线构建方案

Ivan Zhang
2026-05-27 / 0 评论 / 0 点赞 / 4 阅读 / 6,913 字
温馨提示:
本文最后更新于 ,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。
有什么问题或观点欢迎评论留言,或者 交流。
如果觉得文章对您有所帮助,可以给博主打赏鼓励一下。

存在一个小问题,没有图标文件,官方 QDK 文档上用的图标格式是 gif,官网的图标文件是 png。影响不大,懒得折腾了,有好事者有处理的话,欢迎评论区交流。

本文档提供一套可复现、可对外分享的工程化构建方案,用于在 Debian/Ubuntu 环境中,通过 Docker Compose 一键构建适用于 QNAP x86_64 设备的 zerotier_1.16.2_x86_64.qpkg

该方案采用 多阶段构建

  • Alpine 3.20:负责编译 ZeroTier One(静态链接,适配 QNAP 老设备)
  • Ubuntu 22.04:负责离线安装 QDK 并执行打包

一、目录结构

zerotier-qpkg/
├── build.sh                 # 一键构建脚本
├── docker-compose.yml      # Docker Compose 编排文件
├── Dockerfile.builder       # Ubuntu 构建镜像(QDK 与打包环境)
├── Dockerfile.alpine       # Alpine 构建镜像(编译 ZeroTier)
├── qpkg-template/
│   ├── build/            # qbuild 生成目录(最终产物在此)
│   ├── package_routines  # QPKG 生命周期脚本
│   ├── qpkg.cfg         # QPKG 元数据配置
│   ├── shared/
│   │   └── zerotier.sh # 服务启停脚本
│   └── x86_64/         # 二进制文件存放目录
│       ├── zerotier-one
│       ├── zerotier-cli
│       └── zerotier-idtool
├── qdk.deb  # QDK 离线安装包
└── ZeroTierOne-src/ # ZeroTier 1.16.2 源码

二、一键构建脚本

该脚本负责自动下载源码生成 Dockerfile 与 Compose 文件(使用 cat EOF),并执行 Docker Compose 构建。增加了 curl 失败处理--download-only 参数支持

#!/bin/bash
set -e

PROJECT_DIR="."

QDK_URL="https://github.com/qnap-dev/QDK/releases/download/v2.5.0/qdk_2.5.0_amd64.deb"
ZT_SRC_URL="https://github.com/zerotier/ZeroTierOne/archive/refs/heads/1.16.2.zip"

# 新增:三级控制
DOWNLOAD_ONLY=false
CONFIG_ONLY=false

# 参数解析(支持多参数)
for arg in "$@"; do
  case "$arg" in
    --download-only)
      DOWNLOAD_ONLY=true
      ;;
    --config-only)
      CONFIG_ONLY=true
      ;;
  esac
done

echo "==> 创建项目目录结构..."
mkdir -p ${PROJECT_DIR}/qpkg-template/{build,shared,x86_64}
mkdir -p ${PROJECT_DIR}/output

# ===== 仅在非 config-only 模式下执行下载 =====
if [ "$CONFIG_ONLY" = false ]; then

  echo "==> 下载 QDK 2.5.0..."
  if ! curl -L -o ${PROJECT_DIR}/qdk.deb ${QDK_URL}; then
      echo "ERROR: 下载 QDK 失败,请检查网络连接或 URL 有效性。"
      exit 1
  fi

  echo "==> 下载 ZeroTier One 1.16.2 源码..."
  if ! curl -L -o /tmp/zt.zip ${ZT_SRC_URL}; then
      echo "ERROR: 下载 ZeroTier 源码失败,请检查网络连接或 URL 有效性。"
      exit 1
  fi

  unzip -q /tmp/zt.zip -d ${PROJECT_DIR}/
  rm -rf ${PROJECT_DIR}/ZeroTierOne-src
  mv ${PROJECT_DIR}/ZeroTierOne-1.16.2 ${PROJECT_DIR}/ZeroTierOne-src
  rm -f /tmp/zt.zip

fi

echo "==> 生成 Dockerfile.alpine..."
cat > ${PROJECT_DIR}/Dockerfile.alpine <<'EOF'
FROM alpine:3.20

RUN apk update && apk add --no-cache \
    make gcc g++ linux-headers musl-dev \
    openssl-dev openssl-libs-static curl

RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
ENV PATH="/root/.cargo/bin:${PATH}"

WORKDIR /tmp/ZeroTierOne
COPY ZeroTierOne-src /tmp/ZeroTierOne

RUN make ZT_STATIC=1 -j${nproc}

RUN strip zerotier-one

CMD ["sh", "-c", "cp /tmp/ZeroTierOne/zerotier-one /build/qpkg-template/x86_64/ && cp /tmp/ZeroTierOne/zerotier-cli /build/qpkg-template/x86_64/ && cp /tmp/ZeroTierOne/zerotier-idtool /build/qpkg-template/x86_64/"]
EOF

echo "==> 生成 Dockerfile.builder..."
cat > ${PROJECT_DIR}/Dockerfile.builder <<'EOF'
FROM ubuntu:22.04

RUN apt-get update && apt-get install -y \
    pv xz-utils rsync gnupg2 curl openssl bsdextrautils

COPY qdk.deb /tmp/qdk.deb
RUN dpkg -i /tmp/qdk.deb

WORKDIR /build/qpkg-template
COPY qpkg-template /build/qpkg-template

CMD ["sh", "-c", "qbuild --build-arch x86_64 && cp /build/qpkg-template/build/* /output/"]
EOF

echo "==> 生成 docker-compose.yml..."
cat > ${PROJECT_DIR}/docker-compose.yml <<'EOF'
services:
  alpine-builder:
    platform: linux/amd64
    build:
      context: .
      dockerfile: Dockerfile.alpine
    volumes:
      - ./qpkg-template:/build/qpkg-template
    container_name: zerotier-alpine-builder

  ubuntu-packager:
    platform: linux/amd64
    build:
      context: .
      dockerfile: Dockerfile.builder
    volumes:
      - ./qpkg-template:/build/qpkg-template
      - ./output:/output
    container_name: zerotier-ubuntu-packager
    depends_on:
      - alpine-builder
EOF

echo "==> 生成 QPKG 模板基础文件..."

cat > ${PROJECT_DIR}/qpkg-template/package_routines <<'EOF'
#!/bin/sh

pkg_install() {
    ln -sf "$QPKG_ROOT/usr/bin/zerotier-cli" "/usr/local/bin/zerotier-cli"
}

pkg_post_install() {
    echo "ZeroTier One installed successfully."
}

pkg_pre_remove() {
    $QPKG_SERVICE_PROGRAM stop
}

pkg_main_remove() {
    rm -f "/usr/local/bin/zerotier-cli"
}
EOF

cat > ${PROJECT_DIR}/qpkg-template/qpkg.cfg <<'EOF'
QPKG_NAME="zerotier"
QPKG_VER="1.16.2"
QPKG_AUTHOR="Ivan Zhang"
QPKG_LICENSE="GPL"
QPKG_DISPLAY_NAME="ZeroTier One"
QPKG_ARCH="x86_64"
QPKG_SERVICE_PROGRAM="zerotier.sh"
EOF

cat > ${PROJECT_DIR}/qpkg-template/shared/zerotier.sh <<'EOF'
#!/bin/sh

QPKG_NAME="zerotier"
CONF=/etc/config/qpkg.conf
QPKG_ROOT=/share/CACHEDEV1_DATA/.qpkg/${QPKG_NAME}

case "$1" in
  start)
    ENABLED=$(/sbin/getcfg $QPKG_NAME Enable -u -d FALSE -f $CONF)
    if [ "$ENABLED" != "TRUE" ]; then
        echo "$QPKG_NAME is disabled."
        exit 1
    fi
    $QPKG_ROOT/zerotier-one -d
    ;;
  stop)
    killall zerotier-one
    ;;
  restart)
    $0 stop
    $0 start
    ;;
  *)
    echo "Usage: $0 {start|stop|restart}"
    exit 1
esac

exit 0
EOF

chmod +x ${PROJECT_DIR}/qpkg-template/package_routines
chmod +x ${PROJECT_DIR}/qpkg-template/shared/zerotier.sh

# ===== 仅在非 config-only 模式下执行构建 =====
if [ "$CONFIG_ONLY" = false ]; then
  if [ "$DOWNLOAD_ONLY" = false ]; then
      echo "==> 开始构建..."
      cd ${PROJECT_DIR}
      docker compose up --build --force-recreate
      echo "==> 构建完成!"
      echo "最终 QPKG 文件位于:output/zerotier_1.16.2_x86_64.qpkg"
  else
      echo "==> 下载和文件生成完成。使用 './build.sh --download-only' 跳过构建。"
  fi
else
  echo "==> 仅生成/更新配置文件完成。使用 './build.sh --config-only' 跳过下载和构建。"
fi

三、Dockerfile.alpine(编译 ZeroTier)

此镜像基于 Alpine 3.20,使用 单线程 make 规避 Argument list too long 内核限制,并通过 静态链接 生成兼容 QNAP 的二进制文件。

FROM alpine:3.20

RUN apk update && apk add --no-cache \
    make gcc g++ linux-headers musl-dev \
    openssl-dev openssl-libs-static curl

RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
ENV PATH="/root/.cargo/bin:${PATH}"

WORKDIR /tmp/ZeroTierOne
COPY ZeroTierOne-src /tmp/ZeroTierOne

RUN make ZT_STATIC=1 -j${nproc}

RUN strip zerotier-one

CMD ["sh", "-c", "cp /tmp/ZeroTierOne/zerotier-one /build/qpkg-template/x86_64/ && cp /tmp/ZeroTierOne/zerotier-cli /build/qpkg-template/x86_64/ && cp /tmp/ZeroTierOne/zerotier-idtool /build/qpkg-template/x86_64/"]

四、Dockerfile.builder(QDK 打包环境)

此镜像基于 Ubuntu 22.04,负责离线安装 QDK 并对 qpkg-template 执行打包操作。

FROM ubuntu:22.04

RUN apt-get update && apt-get install -y \
    pv xz-utils rsync gnupg2 curl openssl bsdextrautils

COPY qdk.deb /tmp/qdk.deb
RUN dpkg -i /tmp/qdk.deb

WORKDIR /build/qpkg-template
COPY qpkg-template /build/qpkg-template

CMD ["sh", "-c", "qbuild --build-arch x86_64 && cp /build/qpkg-template/build/* /output/"]

五、docker-compose.yml(编排文件)

该文件整合了 Alpine 编译Ubuntu 打包 两个阶段。构建指令完全由 Dockerfile 的 CMD 定义。

services:
  alpine-builder:
    platform: linux/amd64
    build:
      context: .
      dockerfile: Dockerfile.alpine
    volumes:
      - ./qpkg-template:/build/qpkg-template
    container_name: zerotier-alpine-builder

  ubuntu-packager:
    platform: linux/amd64
    build:
      context: .
      dockerfile: Dockerfile.builder
    volumes:
      - ./qpkg-template:/build/qpkg-template
      - ./output:/output
    container_name: zerotier-ubuntu-packager
    depends_on:
      - alpine-builder

六、构建与提取

使用场景命令行为
第一次全量构建./build.sh下载 + 生成配置 + 构建
只改配置./build.sh --config-only不下载、不构建,只更新 cat 文件
下载构建./build.sh --download-only下载 + 生成 Dockerfile
重新构建docker compose up --build --force-recreate不下载、不更新,只构建
完整流程./build.sh全部执行

构建完成后,最终产物位于:

output/zerotier_1.16.2_x86_64.qpkg
0

评论区