diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9609b6a..bf81893 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -59,6 +59,9 @@ jobs: with: install-only: true + - name: 安装 nFPM + run: go install github.com/goreleaser/nfpm/v2/cmd/nfpm@v2.46.3 + - name: 编译二进制文件 run: | cd src @@ -74,24 +77,11 @@ jobs: upx -9 ../build/hubproxy/hubproxy-linux-amd64 upx -9 ../build/hubproxy/hubproxy-linux-arm64 - - name: 复制配置文件 + - name: 准备压缩包文件 run: | # 复制配置文件 cp src/config.toml build/hubproxy/ - # 复制systemd服务文件 - cp hubproxy.service build/hubproxy/ - - # 复制安装脚本 - cp install.sh build/hubproxy/ - - # 创建README文件 - cat > build/hubproxy/README.md << 'EOF' - # HubProxy - - 项目地址:https://github.com/sky22333/hubproxy - EOF - - name: 创建压缩包 run: | cd build @@ -99,23 +89,56 @@ jobs: # Linux AMD64 包 mkdir -p linux-amd64/hubproxy cp hubproxy/hubproxy-linux-amd64 linux-amd64/hubproxy/hubproxy - cp hubproxy/config.toml hubproxy/hubproxy.service hubproxy/install.sh hubproxy/README.md linux-amd64/hubproxy/ - tar -czf hubproxy-${{ steps.version.outputs.version }}-linux-amd64.tar.gz -C linux-amd64 hubproxy + cp hubproxy/config.toml linux-amd64/hubproxy/ + tar -czf hubproxy-linux-amd64.tar.gz -C linux-amd64 hubproxy # Linux ARM64 包 mkdir -p linux-arm64/hubproxy cp hubproxy/hubproxy-linux-arm64 linux-arm64/hubproxy/hubproxy - cp hubproxy/config.toml hubproxy/hubproxy.service hubproxy/install.sh hubproxy/README.md linux-arm64/hubproxy/ - tar -czf hubproxy-${{ steps.version.outputs.version }}-linux-arm64.tar.gz -C linux-arm64 hubproxy + cp hubproxy/config.toml linux-arm64/hubproxy/ + tar -czf hubproxy-linux-arm64.tar.gz -C linux-arm64 hubproxy # 列出生成的文件 ls -la *.tar.gz - - - name: 计算文件校验和 + + - name: 创建Linux发行版安装包 run: | - cd build - sha256sum *.tar.gz > checksums.txt - cat checksums.txt + mkdir -p build/packages + VERSION="${{ steps.version.outputs.version }}" + NFPM_VERSION="${VERSION#v}" + + package() { + hubproxy_arch="$1" + nfpm_arch="$2" + packager="$3" + config="$4" + target="build/packages/hubproxy-linux-${hubproxy_arch}.${packager}" + temp_dir="build/packages/${hubproxy_arch}-${packager}" + + rm -rf "${temp_dir}" + mkdir -p "${temp_dir}" + HUBPROXY_ARCH="${hubproxy_arch}" NFPM_ARCH="${nfpm_arch}" NFPM_VERSION="${NFPM_VERSION}" nfpm package --config "${config}" --packager "${packager}" --target "${temp_dir}/" + mv "${temp_dir}"/*.${packager} "${target}" + rm -rf "${temp_dir}" + } + + # AMD64 包 + package amd64 amd64 deb packaging/nfpm.deb-rpm.yaml + package amd64 amd64 rpm packaging/nfpm.deb-rpm.yaml + package amd64 amd64 apk packaging/nfpm.apk.yaml + + # ARM64 包 + package arm64 arm64 deb packaging/nfpm.deb-rpm.yaml + package arm64 arm64 rpm packaging/nfpm.deb-rpm.yaml + package arm64 arm64 apk packaging/nfpm.apk.yaml + + ls -la build/packages + + - name: 检查安装包内容 + run: | + dpkg-deb -c build/packages/hubproxy-linux-amd64.deb + rpm -qpl build/packages/hubproxy-linux-amd64.rpm + tar -tf build/packages/hubproxy-linux-amd64.apk - name: 创建或更新Release uses: softprops/action-gh-release@v3 @@ -128,12 +151,16 @@ jobs: ## 下载文件 - - **Linux AMD64**: `hubproxy-${{ steps.version.outputs.version }}-linux-amd64.tar.gz` - - **Linux ARM64**: `hubproxy-${{ steps.version.outputs.version }}-linux-arm64.tar.gz` + - **Linux AMD64**: `hubproxy-linux-amd64.tar.gz` + - **Linux ARM64**: `hubproxy-linux-arm64.tar.gz` + - **Debian/Ubuntu**: `.deb` + - **RHEL/CentOS/Fedora**: `.rpm` + - **Alpine Linux**: `.apk` files: | build/*.tar.gz - build/checksums.txt + build/packages/* + overwrite_files: true draft: false prerelease: false token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 2177864..f26d439 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ .idea .vscode .DS_Store -hubproxy* -!hubproxy.service \ No newline at end of file +/hubproxy* +*.exe diff --git a/README.md b/README.md index 016f4b3..21d3e57 100644 --- a/README.md +++ b/README.md @@ -40,19 +40,35 @@ docker run -d \ ghcr.io/sky22333/hubproxy ``` -### 一键脚本安装 +### 脚本安装 + +自动识别系统与架构,从 GitHub Releases 下载对应的 `.deb`、`.rpm` 或 `.apk` 安装包: ```bash -curl -fsSL https://raw.githubusercontent.com/sky22333/hubproxy/main/install.sh | sudo bash +curl -fsSL https://raw.githubusercontent.com/sky22333/hubproxy/main/install.sh | sudo sh ``` -支持单个二进制文件直接启动,无需其他配置,内置默认配置,支持所有功能。 +安装包会自动安装并启动 `hubproxy` 服务。 -这个脚本会: -- 自动检测系统架构(AMD64/ARM64) -- 从 GitHub Releases 下载最新版本 -- 自动配置系统服务 -- 保留现有配置(升级时) +```bash +# systemd 系统 +sudo systemctl status hubproxy +sudo systemctl restart hubproxy + +# Alpine / OpenRC 系统 +sudo rc-service hubproxy status +sudo rc-service hubproxy restart +``` + +### 文件路径 + +- Docker 容器配置文件:`/app/config.toml` +- Linux 安装包配置文件:`/etc/hubproxy/config.toml` +- Linux 安装包二进制文件:`/usr/bin/hubproxy` +- systemd 服务文件:`/lib/systemd/system/hubproxy.service` +- Alpine OpenRC 服务文件:`/etc/init.d/hubproxy` +- Alpine 日志文件:`/var/log/hubproxy.log` +- Alpine 日志轮转配置:`/etc/logrotate.d/hubproxy` ## 使用方法 @@ -202,10 +218,6 @@ defaultTTL = "20m" -容器内的配置文件位于 `/app/config.toml` - -脚本部署配置文件位于 `/opt/hubproxy/config.toml` - ### 环境变量(可选) 支持通过环境变量覆盖部分配置,优先级高于`config.toml`,以下是默认值: diff --git a/install.sh b/install.sh index 37a9112..77fd70b 100644 --- a/install.sh +++ b/install.sh @@ -1,213 +1,121 @@ -#!/bin/bash +#!/bin/sh +set -eu -# HubProxy 一键安装脚本 -# 支持自动下载最新版本或使用本地文件安装 -set -e +REPO="${REPO:-sky22333/hubproxy}" +VERSION="${VERSION:-latest}" +TMP_DIR="${TMP_DIR:-/tmp/hubproxy-install}" -# 颜色定义 -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' # No Color +log() { + printf '%s\n' "$*" +} -# 配置 -REPO="sky22333/hubproxy" -GITHUB_API="https://api.github.com/repos/${REPO}" -GITHUB_RELEASES="${GITHUB_API}/releases" -SERVICE_NAME="hubproxy" -INSTALL_DIR="/opt/hubproxy" -CONFIG_FILE="config.toml" -BINARY_NAME="hubproxy" -LOG_DIR="/var/log/hubproxy" -TEMP_DIR="/tmp/hubproxy-install" +fail() { + printf 'HubProxy 安装失败:%s\n' "$*" >&2 + exit 1 +} -echo -e "${BLUE}HubProxy 一键安装脚本${NC}" -echo "=================================================" +need_cmd() { + command -v "$1" >/dev/null 2>&1 || fail "缺少必要命令:$1" +} -# 检查是否以root权限运行 -if [[ $EUID -ne 0 ]]; then - echo -e "${RED}此脚本需要root权限运行${NC}" - echo "请使用: sudo $0" - exit 1 -fi - -# 检测系统架构 detect_arch() { - local arch=$(uname -m) - case $arch in - x86_64) + case "$(uname -m)" in + x86_64|amd64) echo "amd64" ;; aarch64|arm64) echo "arm64" ;; *) - echo -e "${RED}不支持的架构: $arch${NC}" - exit 1 + fail "不支持的系统架构:$(uname -m)" ;; esac } -ARCH=$(detect_arch) -echo -e "${BLUE}检测到架构: linux-${ARCH}${NC}" - -# 检查是否为本地安装模式 -if [ -f "${BINARY_NAME}" ]; then - echo -e "${BLUE}发现本地文件,使用本地安装模式${NC}" - LOCAL_INSTALL=true -else - echo -e "${BLUE}本地无文件,使用自动下载模式${NC}" - LOCAL_INSTALL=false - - # 检查依赖 - missing_deps=() - for cmd in curl jq tar; do - if ! command -v $cmd &> /dev/null; then - missing_deps+=($cmd) - fi - done - - if [ ${#missing_deps[@]} -gt 0 ]; then - echo -e "${YELLOW}检测到缺少依赖: ${missing_deps[*]}${NC}" - echo -e "${BLUE}正在自动安装依赖...${NC}" - - apt update && apt install -y curl jq - if [ $? -ne 0 ]; then - echo -e "${RED}依赖安装失败${NC}" - exit 1 - fi - - # 重新检查依赖 - for cmd in curl jq tar; do - if ! command -v $cmd &> /dev/null; then - echo -e "${RED}依赖安装后仍缺少: $cmd${NC}" - exit 1 - fi - done - - echo -e "${GREEN}依赖安装成功${NC}" - fi -fi - -# 自动下载功能 -if [ "$LOCAL_INSTALL" = false ]; then - echo -e "${BLUE}获取最新版本信息...${NC}" - LATEST_RELEASE=$(curl -s "${GITHUB_RELEASES}/latest") - if [ $? -ne 0 ]; then - echo -e "${RED}无法获取版本信息${NC}" - exit 1 - fi - - VERSION=$(echo "$LATEST_RELEASE" | jq -r '.tag_name') - if [ "$VERSION" = "null" ]; then - echo -e "${RED}无法解析版本信息${NC}" - exit 1 - fi - - echo -e "${GREEN}最新版本: ${VERSION}${NC}" - - # 构造下载URL - ASSET_NAME="hubproxy-${VERSION}-linux-${ARCH}.tar.gz" - DOWNLOAD_URL="https://github.com/${REPO}/releases/download/${VERSION}/${ASSET_NAME}" - - echo -e "${BLUE}下载: ${ASSET_NAME}${NC}" - - # 创建临时目录并下载 - rm -rf "${TEMP_DIR}" - mkdir -p "${TEMP_DIR}" - cd "${TEMP_DIR}" - - curl -L -o "${ASSET_NAME}" "${DOWNLOAD_URL}" - if [ $? -ne 0 ]; then - echo -e "${RED}下载失败${NC}" - exit 1 - fi - - # 解压 - tar -xzf "${ASSET_NAME}" - if [ $? -ne 0 ] || [ ! -d "hubproxy" ]; then - echo -e "${RED}解压失败${NC}" - exit 1 - fi - - cd hubproxy - echo -e "${GREEN}下载完成${NC}" -fi - -echo -e "${YELLOW}开始安装 HubProxy...${NC}" - -# 停止现有服务(如果存在) -if systemctl is-active --quiet ${SERVICE_NAME} 2>/dev/null; then - echo -e "${YELLOW}停止现有服务...${NC}" - systemctl stop ${SERVICE_NAME} -fi - -# 备份现有配置(如果存在) -CONFIG_BACKUP_EXISTS=false -if [ -f "${INSTALL_DIR}/${CONFIG_FILE}" ]; then - echo -e "${BLUE}备份现有配置...${NC}" - cp "${INSTALL_DIR}/${CONFIG_FILE}" "${TEMP_DIR}/config.toml.backup" - CONFIG_BACKUP_EXISTS=true -fi - -# 1. 创建目录结构 -echo -e "${BLUE}创建目录结构${NC}" -mkdir -p ${INSTALL_DIR} -mkdir -p ${LOG_DIR} -chmod 755 ${INSTALL_DIR} -chmod 755 ${LOG_DIR} - -# 2. 复制二进制文件 -echo -e "${BLUE}复制二进制文件${NC}" -cp "${BINARY_NAME}" "${INSTALL_DIR}/" -chmod +x "${INSTALL_DIR}/${BINARY_NAME}" - -# 3. 复制配置文件 -echo -e "${BLUE}复制配置文件${NC}" -if [ -f "${CONFIG_FILE}" ]; then - if [ "$CONFIG_BACKUP_EXISTS" = false ]; then - cp "${CONFIG_FILE}" "${INSTALL_DIR}/" - echo -e "${GREEN}配置文件复制成功${NC}" +detect_packager() { + if command -v apk >/dev/null 2>&1; then + echo "apk" + elif command -v apt-get >/dev/null 2>&1; then + echo "deb" + elif command -v dnf >/dev/null 2>&1 || command -v yum >/dev/null 2>&1 || command -v rpm >/dev/null 2>&1; then + echo "rpm" else - echo -e "${YELLOW}保留现有配置文件${NC}" + fail "不支持的系统:需要 apt、dnf、yum、rpm 或 apk" fi -else - echo -e "${YELLOW}配置文件不存在,将使用默认配置${NC}" +} + +asset_name() { + packager="$1" + arch="$2" + + case "$packager:$arch" in + deb:amd64|rpm:amd64|apk:amd64) echo "hubproxy-linux-amd64.${packager}" ;; + deb:arm64|rpm:arm64|apk:arm64) echo "hubproxy-linux-arm64.${packager}" ;; + *) fail "不支持的安装包目标:${packager}/${arch}" ;; + esac +} + +asset_url() { + asset="$1" + + if [ "$VERSION" = "latest" ]; then + echo "https://github.com/${REPO}/releases/latest/download/${asset}" + else + echo "https://github.com/${REPO}/releases/download/${VERSION}/${asset}" + fi +} + +install_package() { + package_file="$1" + packager="$2" + + case "$packager" in + deb) + apt-get install -y "$package_file" + ;; + rpm) + if command -v dnf >/dev/null 2>&1; then + dnf install -y "$package_file" + elif command -v yum >/dev/null 2>&1; then + yum install -y "$package_file" + else + rpm -Uvh "$package_file" + fi + ;; + apk) + apk add --allow-untrusted "$package_file" + ;; + *) + fail "不支持的包管理器:$packager" + ;; + esac +} + +if [ "$(id -u)" -ne 0 ]; then + fail "请使用 root 权限运行,例如:curl -fsSL https://raw.githubusercontent.com/${REPO}/main/install.sh | sudo sh" fi -# 5. 安装systemd服务文件 -echo -e "${BLUE}安装systemd服务文件${NC}" -cp "${SERVICE_NAME}.service" "/etc/systemd/system/" -systemctl daemon-reload +need_cmd curl -# 6. 恢复配置文件(如果有备份) -if [ "$CONFIG_BACKUP_EXISTS" = true ]; then - echo -e "${BLUE}恢复配置文件...${NC}" - cp "${TEMP_DIR}/config.toml.backup" "${INSTALL_DIR}/${CONFIG_FILE}" -fi +ARCH="$(detect_arch)" +PACKAGER="$(detect_packager)" -# 7. 启用并启动服务 -echo -e "${BLUE}启用并启动服务${NC}" -systemctl enable ${SERVICE_NAME} -systemctl start ${SERVICE_NAME} +rm -rf "$TMP_DIR" +mkdir -p "$TMP_DIR" +trap 'rm -rf "$TMP_DIR"' EXIT INT TERM -# 8. 清理临时文件 -if [ "$LOCAL_INSTALL" = false ]; then - echo -e "${BLUE}清理临时文件...${NC}" - cd / - rm -rf "${TEMP_DIR}" -fi +log "安装 HubProxy:linux/${ARCH}(${PACKAGER})" -# 9. 检查服务状态 -sleep 2 -if systemctl is-active --quiet ${SERVICE_NAME}; then - echo "" - echo -e "${GREEN}HubProxy 安装成功!${NC}" - echo -e "${GREEN}默认运行端口: 5000${NC}" - echo -e "${GREEN}配置文件路径: ${INSTALL_DIR}/${CONFIG_FILE}${NC}" -else - echo -e "${RED}服务启动失败${NC}" - echo "查看错误日志: sudo journalctl -u ${SERVICE_NAME} -f" - exit 1 -fi +ASSET="$(asset_name "$PACKAGER" "$ARCH")" +ASSET_URL="$(asset_url "$ASSET")" + +PACKAGE_FILE="${TMP_DIR}/$(basename "$ASSET_URL")" +log "下载安装包..." +curl -fL -o "$PACKAGE_FILE" "$ASSET_URL" || fail "下载安装包失败" + +log "安装软件包..." +install_package "$PACKAGE_FILE" "$PACKAGER" + +log "安装完成" +log "默认端口:5000" +log "配置文件:/etc/hubproxy/config.toml" diff --git a/packaging/hubproxy.logrotate b/packaging/hubproxy.logrotate new file mode 100644 index 0000000..f5f9358 --- /dev/null +++ b/packaging/hubproxy.logrotate @@ -0,0 +1,9 @@ +/var/log/hubproxy.log { + weekly + maxsize 50M + rotate 4 + compress + missingok + notifempty + copytruncate +} diff --git a/packaging/hubproxy.openrc b/packaging/hubproxy.openrc new file mode 100644 index 0000000..86b8b50 --- /dev/null +++ b/packaging/hubproxy.openrc @@ -0,0 +1,18 @@ +#!/sbin/openrc-run + +name="hubproxy" +description="Docker and GitHub acceleration proxy server" +command="/usr/bin/hubproxy" +pidfile="/run/${RC_SVCNAME}.pid" +output_log="/var/log/hubproxy.log" +error_log="/var/log/hubproxy.log" +supervisor="supervise-daemon" +respawn_delay=5 +respawn_max=0 + +export CONFIG_PATH="/etc/hubproxy/config.toml" + +depend() { + need net + after firewall +} diff --git a/hubproxy.service b/packaging/hubproxy.service similarity index 65% rename from hubproxy.service rename to packaging/hubproxy.service index 640651b..50c15df 100644 --- a/hubproxy.service +++ b/packaging/hubproxy.service @@ -7,11 +7,10 @@ Wants=network-online.target Type=simple User=root Group=root -WorkingDirectory=/opt/hubproxy -ExecStart=/opt/hubproxy/hubproxy +Environment=CONFIG_PATH=/etc/hubproxy/config.toml +ExecStart=/usr/bin/hubproxy Restart=always RestartSec=5 -Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin StandardOutput=journal StandardError=journal SyslogIdentifier=hubproxy diff --git a/packaging/nfpm.apk.yaml b/packaging/nfpm.apk.yaml new file mode 100644 index 0000000..a9c8925 --- /dev/null +++ b/packaging/nfpm.apk.yaml @@ -0,0 +1,45 @@ +name: hubproxy +arch: ${NFPM_ARCH} +platform: linux +version: ${NFPM_VERSION} +release: "1" +section: net +priority: optional +maintainer: sky22333 +description: Docker and GitHub acceleration proxy server +vendor: sky22333 +homepage: https://github.com/sky22333/hubproxy +license: MIT +depends: + - logrotate + +contents: + - src: ./build/hubproxy/hubproxy-linux-${HUBPROXY_ARCH} + dst: /usr/bin/hubproxy + file_info: + mode: 0755 + + - src: ./src/config.toml + dst: /etc/hubproxy/config.toml + type: config|noreplace + file_info: + mode: 0644 + + - src: ./packaging/hubproxy.openrc + dst: /etc/init.d/hubproxy + file_info: + mode: 0755 + + - src: ./packaging/hubproxy.logrotate + dst: /etc/logrotate.d/hubproxy + file_info: + mode: 0644 + +scripts: + postinstall: ./packaging/postinstall.sh + preremove: ./packaging/preremove.sh + postremove: ./packaging/postremove.sh + +apk: + scripts: + postupgrade: ./packaging/postinstall.sh diff --git a/packaging/nfpm.deb-rpm.yaml b/packaging/nfpm.deb-rpm.yaml new file mode 100644 index 0000000..8f76e6b --- /dev/null +++ b/packaging/nfpm.deb-rpm.yaml @@ -0,0 +1,34 @@ +name: hubproxy +arch: ${NFPM_ARCH} +platform: linux +version: ${NFPM_VERSION} +release: "1" +section: net +priority: optional +maintainer: sky22333 +description: Docker and GitHub acceleration proxy server +vendor: sky22333 +homepage: https://github.com/sky22333/hubproxy +license: MIT + +contents: + - src: ./build/hubproxy/hubproxy-linux-${HUBPROXY_ARCH} + dst: /usr/bin/hubproxy + file_info: + mode: 0755 + + - src: ./src/config.toml + dst: /etc/hubproxy/config.toml + type: config|noreplace + file_info: + mode: 0644 + + - src: ./packaging/hubproxy.service + dst: /lib/systemd/system/hubproxy.service + file_info: + mode: 0644 + +scripts: + postinstall: ./packaging/postinstall.sh + preremove: ./packaging/preremove.sh + postremove: ./packaging/postremove.sh diff --git a/packaging/postinstall.sh b/packaging/postinstall.sh new file mode 100644 index 0000000..fe4c67d --- /dev/null +++ b/packaging/postinstall.sh @@ -0,0 +1,27 @@ +#!/bin/sh +set -e + +warn() { + echo "hubproxy: $1" +} + +if command -v systemctl >/dev/null 2>&1; then + systemctl daemon-reload || warn "systemd reload failed" + systemctl enable hubproxy >/dev/null 2>&1 || warn "systemd enable failed" + + if [ -d /run/systemd/system ]; then + systemctl restart hubproxy || systemctl start hubproxy || { + warn "service start failed, check: journalctl -u hubproxy" + } + fi +fi + +if command -v rc-update >/dev/null 2>&1; then + rc-update add hubproxy default >/dev/null 2>&1 || warn "OpenRC enable failed" +fi + +if command -v rc-service >/dev/null 2>&1; then + rc-service hubproxy restart || rc-service hubproxy start || { + warn "service start failed, check: rc-service hubproxy status" + } +fi diff --git a/packaging/postremove.sh b/packaging/postremove.sh new file mode 100644 index 0000000..e545c9e --- /dev/null +++ b/packaging/postremove.sh @@ -0,0 +1,6 @@ +#!/bin/sh +set -e + +if command -v systemctl >/dev/null 2>&1; then + systemctl daemon-reload >/dev/null 2>&1 || true +fi diff --git a/packaging/preremove.sh b/packaging/preremove.sh new file mode 100644 index 0000000..a4021e5 --- /dev/null +++ b/packaging/preremove.sh @@ -0,0 +1,21 @@ +#!/bin/sh +set -e + +case "${1:-}" in + 1|upgrade) + exit 0 + ;; +esac + +if command -v systemctl >/dev/null 2>&1; then + systemctl stop hubproxy >/dev/null 2>&1 || true + systemctl disable hubproxy >/dev/null 2>&1 || true +fi + +if command -v rc-service >/dev/null 2>&1; then + rc-service hubproxy stop >/dev/null 2>&1 || true +fi + +if command -v rc-update >/dev/null 2>&1; then + rc-update del hubproxy default >/dev/null 2>&1 || true +fi