Files
BackupX/deploy/install.sh
T
Wu Qing 00151e466c feat: 解决 CDC 去重、集中备份与首次初始化问题 (#105)
实现 CDC 内容寻址仓库、远程 Agent 中央中转备份与首次初始化体验,并补充安全校验、测试及双语文档。

Closes #94
Closes #101
Closes #104
2026-08-07 23:01:29 +08:00

169 lines
5.9 KiB
Bash
Executable File

#!/bin/sh
set -eu
SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
PROJECT_ROOT=$(CDPATH= cd -- "$SCRIPT_DIR/.." && pwd)
PREFIX="${PREFIX:-/opt/backupx}"
ETC_DIR="${ETC_DIR:-/etc/backupx}"
SERVICE_NAME="backupx"
APP_USER="backupx"
APP_GROUP="backupx"
if [ -f "$SCRIPT_DIR/backupx" ] && [ -d "$SCRIPT_DIR/web" ]; then
BIN_SOURCE="${BIN_SOURCE:-$SCRIPT_DIR/backupx}"
WEB_SOURCE="${WEB_SOURCE:-$SCRIPT_DIR/web}"
CONFIG_TEMPLATE="${CONFIG_TEMPLATE:-$SCRIPT_DIR/config.example.yaml}"
NGINX_SOURCE="${NGINX_SOURCE:-$SCRIPT_DIR/nginx.conf}"
else
SOURCE_BIN_DEFAULT="$PROJECT_ROOT/server/bin/backupx"
# Keep compatibility with contributors who built the historical path by
# hand, while matching the canonical `make build` output first.
if [ ! -f "$SOURCE_BIN_DEFAULT" ] && [ -f "$PROJECT_ROOT/server/backupx" ]; then
SOURCE_BIN_DEFAULT="$PROJECT_ROOT/server/backupx"
fi
BIN_SOURCE="${BIN_SOURCE:-$SOURCE_BIN_DEFAULT}"
WEB_SOURCE="${WEB_SOURCE:-$PROJECT_ROOT/web/dist}"
CONFIG_TEMPLATE="${CONFIG_TEMPLATE:-$PROJECT_ROOT/server/config.example.yaml}"
NGINX_SOURCE="${NGINX_SOURCE:-$PROJECT_ROOT/deploy/nginx.conf}"
fi
SERVICE_SOURCE="${SERVICE_SOURCE:-$PROJECT_ROOT/deploy/backupx.service}"
if [ "$(id -u)" -ne 0 ]; then
echo "请使用 root 或 sudo 执行安装脚本。" >&2
exit 1
fi
if [ ! -f "$BIN_SOURCE" ]; then
echo "Backend binary not found / 未找到后端二进制:$BIN_SOURCE" >&2
echo "源码树安装请先在仓库根目录执行 make build(产物:server/bin/backupx)。" >&2
echo "For a source install, run 'make build' in the repository root first." >&2
echo "发布包安装请确认当前目录包含 ./backupx、./web 和 ./install.sh。" >&2
exit 1
fi
if [ ! -d "$WEB_SOURCE" ]; then
echo "未找到前端构建产物:$WEB_SOURCE" >&2
echo "源码树安装请先执行:cd \"$PROJECT_ROOT/web\" && npm run build" >&2
echo "发布包安装请确认当前目录包含 ./web。" >&2
exit 1
fi
if [ ! -f "$CONFIG_TEMPLATE" ]; then
echo "未找到配置模板:$CONFIG_TEMPLATE" >&2
exit 1
fi
if ! getent group "$APP_GROUP" >/dev/null 2>&1; then
groupadd --system "$APP_GROUP"
fi
if ! id "$APP_USER" >/dev/null 2>&1; then
useradd --system --gid "$APP_GROUP" --home-dir "$PREFIX" --shell /usr/sbin/nologin "$APP_USER"
fi
install -d -o "$APP_USER" -g "$APP_GROUP" "$PREFIX" "$PREFIX/bin" "$PREFIX/web" "$PREFIX/data" "$ETC_DIR"
install -m 0755 "$BIN_SOURCE" "$PREFIX/bin/backupx"
cp -R "$WEB_SOURCE/." "$PREFIX/web/"
chown -R "$APP_USER:$APP_GROUP" "$PREFIX"
if [ ! -f "$ETC_DIR/config.yaml" ]; then
install -o "$APP_USER" -g "$APP_GROUP" -m 0640 "$CONFIG_TEMPLATE" "$ETC_DIR/config.yaml"
fi
# 确保服务账户能读取配置:历史版本曾以 root:root 0640 安装配置,
# 导致以 backupx 身份运行的服务因无权读取配置而启动失败(exit 1)。
chown "$APP_USER:$APP_GROUP" "$ETC_DIR/config.yaml"
if [ -f "$SERVICE_SOURCE" ]; then
install -m 0644 "$SERVICE_SOURCE" "/etc/systemd/system/$SERVICE_NAME.service"
else
cat > "/etc/systemd/system/$SERVICE_NAME.service" <<UNIT
[Unit]
Description=BackupX API Service
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=$APP_USER
Group=$APP_GROUP
WorkingDirectory=$PREFIX
ExecStart=$PREFIX/bin/backupx -config $ETC_DIR/config.yaml
Restart=on-failure
RestartSec=5
NoNewPrivileges=true
LimitNOFILE=65535
[Install]
WantedBy=multi-user.target
UNIT
fi
systemctl daemon-reload
systemctl enable --now "$SERVICE_NAME"
# systemctl may return before the process has opened its HTTP listener. Verify
# the same unauthenticated endpoint used by the first-administrator screen so a
# broken bare-metal install cannot print a false success message.
HEALTH_URL="${HEALTH_URL:-http://127.0.0.1:8340/api/auth/setup/status}"
READY=0
ATTEMPT=1
while [ "$ATTEMPT" -le 30 ]; do
if systemctl is-active --quiet "$SERVICE_NAME"; then
if command -v curl >/dev/null 2>&1; then
if curl -fsS --max-time 2 "$HEALTH_URL" >/dev/null 2>&1; then
READY=1
break
fi
elif command -v wget >/dev/null 2>&1; then
if wget -q -T 2 -O /dev/null "$HEALTH_URL"; then
READY=1
break
fi
else
echo "Warning / 警告:未找到 curl 或 wget,仅验证 systemd 服务状态。" >&2
READY=1
break
fi
fi
ATTEMPT=$((ATTEMPT + 1))
sleep 1
done
if [ "$READY" -ne 1 ]; then
echo "BackupX did not become ready at $HEALTH_URL / 服务未通过就绪检查。" >&2
systemctl status "$SERVICE_NAME" --no-pager >&2 || true
journalctl -u "$SERVICE_NAME" -n 50 --no-pager >&2 || true
exit 1
fi
if [ -d "/etc/nginx/conf.d" ] && [ -f "$NGINX_SOURCE" ]; then
install -m 0644 "$NGINX_SOURCE" "/etc/nginx/conf.d/$SERVICE_NAME.conf"
if command -v nginx >/dev/null 2>&1; then
nginx -t
systemctl reload nginx || true
fi
fi
cat <<MESSAGE
安装完成。
- 二进制目录:$PREFIX/bin/backupx
- 前端目录:$PREFIX/web
- 配置文件:$ETC_DIR/config.yaml
- systemd 服务:/etc/systemd/system/$SERVICE_NAME.service
Web 控制台已由后端直接托管,无需额外的 nginx 反向代理即可访问:
http://<本机IP>:8340
首次访问 / First sign-in:
1. 打开上面的地址,并可在登录页右上角选择 中文 或 English。
2. 页面显示“系统初始化 / System setup”时,创建首个管理员用户名和密码。
3. 如果未显示初始化表单,请先检查:$HEALTH_URL
(如已安装 nginx,脚本会自动写入反向代理配置,可继续用 80 端口访问。)
排查:若服务未监听端口,请查看日志:
journalctl -u "$SERVICE_NAME" -n 50 --no-pager
如需修改监听地址、数据库路径或日志级别,请编辑 "$ETC_DIR/config.yaml" 后执行:
systemctl restart "$SERVICE_NAME"
MESSAGE