fa
Some checks failed
CI / lint (push) Has been cancelled
CI / build (push) Has been cancelled

This commit is contained in:
2026-02-26 21:29:54 +08:00
commit 2c4549ad79
85 changed files with 14664 additions and 0 deletions

185
docker-update.sh Normal file
View File

@@ -0,0 +1,185 @@
#!/bin/bash
# STARK Todo List - Docker 快速更新脚本
# 用于快速停止、重新构建并启动 Docker 容器
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
# 默认配置
USE_CACHE=true
PULL_CODE=true
SHOW_LOGS=false
# 帮助信息
show_help() {
echo -e "${CYAN}STARK Todo List - Docker 快速更新脚本${NC}"
echo ""
echo "用法: ./docker-update.sh [选项]"
echo ""
echo "选项:"
echo " -f, --full 完全重建(不使用缓存,较慢但更彻底)"
echo " -q, --quick 快速更新(跳过 git pull使用缓存"
echo " -l, --logs 更新完成后显示日志"
echo " -h, --help 显示帮助信息"
echo ""
echo "示例:"
echo " ./docker-update.sh # 默认:拉取代码 + 使用缓存构建"
echo " ./docker-update.sh -f # 完全重建(不使用缓存)"
echo " ./docker-update.sh -q # 快速模式(跳过 git pull"
echo " ./docker-update.sh -q -l # 快速模式 + 显示日志"
echo ""
}
# 解析命令行参数
while [[ $# -gt 0 ]]; do
case $1 in
-f|--full)
USE_CACHE=false
shift
;;
-q|--quick)
PULL_CODE=false
shift
;;
-l|--logs)
SHOW_LOGS=true
shift
;;
-h|--help)
show_help
exit 0
;;
*)
echo -e "${RED}未知选项: $1${NC}"
show_help
exit 1
;;
esac
done
echo ""
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${CYAN} 🔄 STARK Todo List - Docker 更新${NC}"
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""
# 显示当前配置
echo -e "${BLUE}📋 更新配置:${NC}"
if [ "$PULL_CODE" = true ]; then
echo -e " • Git Pull: ${GREEN}${NC}"
else
echo -e " • Git Pull: ${YELLOW}跳过${NC}"
fi
if [ "$USE_CACHE" = true ]; then
echo -e " • 构建缓存: ${GREEN}启用${NC} (快速)"
else
echo -e " • 构建缓存: ${YELLOW}禁用${NC} (完全重建)"
fi
echo ""
# 记录开始时间
START_TIME=$(date +%s)
# 1. 拉取最新代码
if [ "$PULL_CODE" = true ] && [ -d ".git" ]; then
echo -e "${BLUE}📥 正在获取远程最新代码...${NC}"
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
echo -e " 当前分支: ${CYAN}$CURRENT_BRANCH${NC}"
if git pull origin "$CURRENT_BRANCH" 2>&1; then
echo -e "${GREEN} ✓ 代码已更新${NC}"
else
echo -e "${RED} ✗ 代码拉取失败!${NC}"
echo -e "${YELLOW} 💡 提示: 运行 'git reset --hard origin/$CURRENT_BRANCH' 强制覆盖本地更改${NC}"
exit 1
fi
echo ""
fi
# 2. 停止现有容器(保留数据卷)
echo -e "${BLUE}📦 停止现有容器...${NC}"
# 注意:不使用 -v 参数,以保留 todos-data 卷中的 todos.json 和 stats.json
docker compose down --remove-orphans 2>/dev/null || true
echo -e "${GREEN} ✓ 容器已停止 (数据卷已保留)${NC}"
echo ""
# 3. 构建镜像
echo -e "${BLUE}🏗️ 构建 Docker 镜像...${NC}"
if [ "$USE_CACHE" = true ]; then
# 使用缓存构建(快速)
if docker compose build 2>&1 | while read line; do echo -e " $line"; done; then
echo -e "${GREEN} ✓ 镜像构建成功${NC}"
else
echo -e "${RED} ✗ 镜像构建失败!${NC}"
exit 1
fi
else
# 不使用缓存(完全重建)
echo -e "${YELLOW} (完全重建模式,可能需要几分钟...)${NC}"
docker compose down --rmi local 2>/dev/null || true
if docker compose build --no-cache 2>&1 | while read line; do echo -e " $line"; done; then
echo -e "${GREEN} ✓ 镜像构建成功${NC}"
else
echo -e "${RED} ✗ 镜像构建失败!${NC}"
exit 1
fi
fi
echo ""
# 4. 启动新容器
echo -e "${BLUE}🚀 启动新容器...${NC}"
docker compose up -d --force-recreate
echo -e "${GREEN} ✓ 容器已启动${NC}"
echo ""
# 5. 验证数据持久化
echo -e "${BLUE}📊 验证数据持久化...${NC}"
sleep 2 # 等待容器完全启动
CONTAINER_ID=$(docker compose ps -q app 2>/dev/null)
if [ -n "$CONTAINER_ID" ]; then
# 检查 todos.json
TODOS_COUNT=$(docker exec "$CONTAINER_ID" sh -c 'cat /app/data/todos.json 2>/dev/null | grep -o "\"id\"" | wc -l' 2>/dev/null || echo "0")
# 检查 stats.json
STATS=$(docker exec "$CONTAINER_ID" sh -c 'cat /app/data/stats.json 2>/dev/null' 2>/dev/null || echo '{"pv":0,"uv":0}')
PV=$(echo "$STATS" | grep -o '"pv":[0-9]*' | grep -o '[0-9]*' || echo "0")
UV=$(echo "$STATS" | grep -o '"uv":[0-9]*' | grep -o '[0-9]*' || echo "0")
echo -e "${GREEN} ✓ 数据卷挂载正常${NC}"
echo -e " • Todos 数量: ${CYAN}${TODOS_COUNT}${NC}"
echo -e " • 访问量 (PV): ${CYAN}${PV}${NC}"
echo -e " • 访客数 (UV): ${CYAN}${UV}${NC}"
else
echo -e "${YELLOW} ⚠ 无法获取容器信息,请手动验证数据${NC}"
fi
echo ""
# 6. 清理悬空镜像(静默执行)
docker image prune -f > /dev/null 2>&1 || true
# 计算耗时
END_TIME=$(date +%s)
DURATION=$((END_TIME - START_TIME))
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${GREEN} ✅ 更新完成!${NC}"
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""
echo -e " 📍 访问地址: ${CYAN}http://localhost:4000${NC}"
echo -e " ⏱️ 总耗时: ${YELLOW}${DURATION}${NC}"
echo -e " 💾 数据卷: ${CYAN}todos-data${NC} (todos.json + stats.json)"
echo ""
# 显示日志
if [ "$SHOW_LOGS" = true ]; then
echo -e "${BLUE}📋 显示容器日志 (Ctrl+C 退出)...${NC}"
echo ""
docker compose logs -f --tail 50
fi