#!/usr/bin/env bash # openvpn-manager 一键部署脚本 # 适用: Ubuntu 20.04+/Debian 11+/CentOS Stream 9+ # 行为: 装依赖 → 编译前端 → 编译 Go 二进制 → 装到 /opt/openvpn-manager → 写 systemd # 用法: sudo ./install.sh [卸载参数 -u] [--port 8089] [--user admin] [--pass xxxx] set -euo pipefail APP_NAME="openvpn-manager" INSTALL_DIR="/opt/openvpn-manager" SERVICE_NAME="openvpn-manager" # 默认配置(可被命令行覆盖) PORT=8089 ADMIN_USER="admin" ADMIN_PASS="admin123" JWT_SECRET="$(openssl rand -hex 32 2>/dev/null || head -c 64 /dev/urandom | xxd -p -c 64)" usage() { cat < 停止并禁用服务" systemctl stop "$SERVICE_NAME" 2>/dev/null || true systemctl disable "$SERVICE_NAME" 2>/dev/null || true rm -f "/etc/systemd/system/${SERVICE_NAME}.service" systemctl daemon-reload echo "==> 删除安装目录 $INSTALL_DIR" rm -rf "$INSTALL_DIR" echo "==> 完成(已保留源码目录, 如需彻底清理请手动 rm -rf 源码目录)" } # ---------- 参数解析 ---------- while [[ $# -gt 0 ]]; do case "$1" in -u|--uninstall) uninstall; exit 0 ;; --port) PORT="$2"; shift 2 ;; --user) ADMIN_USER="$2"; shift 2 ;; --pass) ADMIN_PASS="$2"; shift 2 ;; --dir) INSTALL_DIR="$2"; shift 2 ;; -h|--help) usage; exit 0 ;; *) echo "未知参数: $1"; usage; exit 1 ;; esac done # ---------- 权限检查 ---------- if [[ $EUID -ne 0 ]]; then echo "请使用 root 运行: sudo $0" exit 1 fi # ---------- 发行版识别 ---------- . /etc/os-release 2>/dev/null || true echo "==> 操作系统: ${PRETTY_NAME:-unknown}" SCRIPTPATH="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" SRC_DIR="$( cd -- "$SCRIPTPATH/.." &> /dev/null && pwd )" echo "==> 源码目录: $SRC_DIR" echo "==> 安装目录: $INSTALL_DIR" # ---------- 包管理器 ---------- if command -v apt-get >/dev/null 2>&1; then PKG="apt-get" PKG_INSTALL="apt-get install -y --no-install-recommends" PKG_UPDATE="apt-get update -qq" DEPS=(curl ca-certificates openssl openvpn easy-rsa nodejs npm golang-go git) elif command -v dnf >/dev/null 2>&1; then PKG="dnf" PKG_INSTALL="dnf install -y" PKG_UPDATE="dnf makecache -q" DEPS=(curl ca-certificates openssl openvpn easy-rsa nodejs npm golang git) elif command -v yum >/dev/null 2>&1; then PKG="yum" PKG_INSTALL="yum install -y" PKG_UPDATE="yum makecache fast -q" DEPS=(curl ca-certificates openssl openvpn easy-rsa nodejs npm golang git) else echo "不支持的发行版(需 apt/dnf/yum 之一)" exit 1 fi echo "==> 使用包管理器: $PKG" echo "==> 更新包索引" $PKG_UPDATE || true echo "==> 安装系统依赖" $PKG_INSTALL "${DEPS[@]}" || { echo "依赖安装失败, 请检查网络/源"; exit 1; } # ---------- 校验版本 ---------- echo "==> 检查工具版本" node -v npm -v go version openssl version openvpn --version | head -1 # 若 Go < 1.21, 警告但不中断(本项目最低 1.21) GO_VER=$(go version | awk '{print $3}' | sed 's/go//') echo "==> Go 版本: $GO_VER" # ---------- 构建前端 ---------- echo "==> 构建前端 (npm install + build)" cd "$SRC_DIR/frontend" npm install --include=dev --no-audit --no-fund npm run build # ---------- 构建后端 ---------- echo "==> 编译 Go 后端二进制" cd "$SRC_DIR/backend" go build -ldflags "-s -w" -o "$SRC_DIR/bin/openvpn-manager" ./cmd/server # ---------- 安装 ---------- echo "==> 安装到 $INSTALL_DIR" mkdir -p "$INSTALL_DIR"/{bin,data,dist} cp -r "$SRC_DIR/bin/openvpn-manager" "$INSTALL_DIR/bin/" cp -r "$SRC_DIR/dist/"* "$INSTALL_DIR/dist/" # 写入环境变量文件(便于 systemd 引用) cat > "$INSTALL_DIR/.env" < "/etc/systemd/system/${SERVICE_NAME}.service" systemctl daemon-reload systemctl enable "$SERVICE_NAME" systemctl restart "$SERVICE_NAME" # ---------- 健康检查 ---------- sleep 2 HEALTH_URL="http://127.0.0.1:${PORT}/api/health" echo "==> 健康检查 $HEALTH_URL" for i in 1 2 3 4 5; do if curl -fsS "$HEALTH_URL" >/dev/null 2>&1; then echo "✓ 服务已就绪" break fi if [[ $i -eq 5 ]]; then echo "✗ 健康检查失败, 查看: journalctl -u $SERVICE_NAME -n 50" exit 1 fi sleep 1 done # ---------- 完成提示 ---------- cat <:${PORT} 用户名 : ${ADMIN_USER} 密码 : ${ADMIN_PASS} 安装目录 : ${INSTALL_DIR} 数据目录 : ${INSTALL_DIR}/data 配置单元 : /etc/systemd/system/${SERVICE_NAME}.service 常用命令: systemctl status ${SERVICE_NAME} # 查看状态 systemctl restart ${SERVICE_NAME} # 重启 systemctl stop ${SERVICE_NAME} # 停止 journalctl -u ${SERVICE_NAME} -f # 跟踪日志 ${INSTALL_DIR}/bin/openvpn-manager --help 卸载: sudo $0 -u ================================================================ EOF