- 仪表盘「实时流量」新增数据源切换:本机读本地 Nginx 访问日志,公网读 frps 逐规则的 today_traffic_in/out 与 cur_conns(速率由后端两次采样算出,口径与公网反代页一致);两源归一成同一形状供汇总/Top/曲线共用,切换时清空 5 分钟曲线避免混采样,无穿透规则时公网按钮禁用 - Docker 交付(方案 1):Dockerfile 加 docker/dockerfile:1 语法与四处 RUN --mount=type=cache(npm/go 模块/编译缓存复用);三个 compose 统一 name: fonu(防止改目录名后 fonu-data 变新空卷)与 image: fonu:\(tag 随版本走便于回滚),.host.yml 补上缺失的 image - 新增 scripts/upgrade.sh:一条命令完成拉代码→构建→重建→健康检查,支持 --no-pull / --rollback <tag>(不重建) / COMPOSE_FILE=(host 网络那份) - 验证:bash -n 与 --help 实跑通过;容器构建与 compose 配置解析本机无 docker,需在 NAS 上执行一次确认
90 lines
3.2 KiB
Bash
90 lines
3.2 KiB
Bash
#!/usr/bin/env bash
|
||
# Fonu 容器升级:在部署机(NAS)上直接构建,不需要再从别处传镜像包
|
||
#
|
||
# sudo bash scripts/upgrade.sh # 拉取最新源码 → 构建 → 重建容器
|
||
# sudo bash scripts/upgrade.sh --no-pull # 不拉代码,用当前源码重建
|
||
# sudo bash scripts/upgrade.sh --rollback 1.2.13 # 回滚到已存在的镜像 tag(不构建)
|
||
#
|
||
# 用 COMPOSE_FILE 指定编排文件(默认 docker-compose.yml):
|
||
# COMPOSE_FILE=docker-compose.host.yml sudo bash scripts/upgrade.sh
|
||
#
|
||
# 数据在 fonu-data 卷里,重建容器不会丢。每次构建按仓库 VERSION 打一个新 tag
|
||
# (旧的 tag 会留着),所以出问题可以直接 --rollback 回上一个版本。
|
||
set -euo pipefail
|
||
|
||
COMPOSE_FILE="${COMPOSE_FILE:-docker-compose.yml}"
|
||
APP_CONTAINER="${APP_CONTAINER:-fonu}"
|
||
HEALTH_URL="${HEALTH_URL:-http://127.0.0.1:6893/api/version}"
|
||
NO_PULL=0
|
||
ROLLBACK_TAG=""
|
||
|
||
usage() {
|
||
sed -n '2,12p' "$0" | sed 's/^# \{0,1\}//'
|
||
exit "${1:-0}"
|
||
}
|
||
|
||
while [ $# -gt 0 ]; do
|
||
case "$1" in
|
||
--no-pull) NO_PULL=1; shift ;;
|
||
--rollback) ROLLBACK_TAG="${2:?--rollback 需要一个镜像 tag,例如 1.2.13}"; shift 2 ;;
|
||
-h|--help) usage 0 ;;
|
||
*) echo "未知参数:$1" >&2; usage 1 ;;
|
||
esac
|
||
done
|
||
|
||
if ! command -v docker >/dev/null 2>&1; then
|
||
echo "没有找到 docker 命令:这个脚本要在运行 Fonu 容器的那台机器上执行" >&2
|
||
exit 1
|
||
fi
|
||
if [ ! -f "$COMPOSE_FILE" ]; then
|
||
echo "找不到 $COMPOSE_FILE:请在仓库根目录运行(或用 COMPOSE_FILE=... 指定编排文件)" >&2
|
||
exit 1
|
||
fi
|
||
|
||
# 当前容器实际使用的镜像 tag,升级前后各打印一次,回滚时心里有数
|
||
current_image() {
|
||
docker inspect --format '{{.Config.Image}}' "$APP_CONTAINER" 2>/dev/null || echo '(容器未运行)'
|
||
}
|
||
|
||
echo "==> 升级前:$(current_image)"
|
||
|
||
if [ -n "$ROLLBACK_TAG" ]; then
|
||
if ! docker image inspect "fonu:$ROLLBACK_TAG" >/dev/null 2>&1; then
|
||
echo "本机没有 fonu:$ROLLBACK_TAG;已有 tag:$(docker images --format '{{.Tag}}' fonu | tr '\n' ' ')" >&2
|
||
exit 1
|
||
fi
|
||
FONU_VERSION="$ROLLBACK_TAG" docker compose -f "$COMPOSE_FILE" up -d
|
||
echo "==> 已切回 fonu:$ROLLBACK_TAG"
|
||
else
|
||
if [ "$NO_PULL" -eq 0 ]; then
|
||
if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
||
echo '==> git pull --ff-only'
|
||
git pull --ff-only
|
||
else
|
||
echo '==> 当前目录不是 git 仓库,跳过拉取(请先自行更新源码)'
|
||
fi
|
||
fi
|
||
if [ ! -f VERSION ]; then
|
||
echo '找不到 VERSION 文件:请在仓库根目录运行' >&2
|
||
exit 1
|
||
fi
|
||
FONU_VERSION="$(tr -d ' \t\n\r' < VERSION)"
|
||
export FONU_VERSION
|
||
echo "==> 构建并重建:fonu:$FONU_VERSION(首次构建较慢,之后有构建缓存)"
|
||
docker compose -f "$COMPOSE_FILE" up -d --build
|
||
fi
|
||
|
||
echo '==> 等待服务就绪…'
|
||
for _ in $(seq 1 30); do
|
||
if curl -fsS "$HEALTH_URL" >/dev/null 2>&1; then
|
||
echo "==> 升级后:$(current_image)"
|
||
echo " 版本接口:$(curl -fsS "$HEALTH_URL" 2>/dev/null)"
|
||
echo " 日志:docker logs --tail 50 $APP_CONTAINER"
|
||
exit 0
|
||
fi
|
||
sleep 2
|
||
done
|
||
|
||
echo "服务在 60 秒内没有响应 $HEALTH_URL,请看:docker logs --tail 100 $APP_CONTAINER" >&2
|
||
exit 1
|