Files
server/archive-manager.sh
2025-11-01 17:37:42 +08:00

614 lines
15 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# 数字档案系统统一管理脚本
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
# 项目配置
PROJECT_NAME="digital-archive"
VERSION="latest"
DEFAULT_DEPLOY_DIR="/root/server/archive"
DOCKERFILE="Dockerfile"
VERBOSE=false
# 显示横幅
show_banner() {
echo -e "${CYAN}"
echo "╔══════════════════════════════════════════════════════════════════╗"
echo "║ 数字档案系统管理脚本 ║"
echo "║ ║"
echo "║ 功能: 构建、部署、检查、管理数字档案系统 ║"
echo "║ 版本: v2.0 ║"
echo "╚════════════════════════════════════════════════════════════════╝"
echo -e "${NC}"
}
# 显示帮助信息
show_help() {
show_banner
echo -e "${GREEN}用法: $0 <命令> [选项] [参数]${NC}"
echo ""
echo -e "${BLUE}命令:${NC}"
echo " build 构建Docker镜像"
echo " deploy 部署应用到指定目录"
echo " check 检查环境配置"
echo " start 启动服务"
echo " stop 停止服务"
echo " restart 重启服务"
echo " logs 查看日志"
echo " status 查看服务状态"
echo " update 更新服务"
echo " clean 清理资源"
echo ""
echo -e "${BLUE}选项:${NC}"
echo " -h, --help 显示帮助信息"
echo " -v, --verbose 详细输出"
echo " -f, --force 强制执行(跳过确认)"
echo " -q, --quiet 静默模式"
echo ""
echo -e "${BLUE}参数:${NC}"
echo " 部署目录 目标部署目录 (默认: ${DEFAULT_DEPLOY_DIR})"
echo ""
echo -e "${YELLOW}示例:${NC}"
echo " $0 build # 构建镜像"
echo " $0 deploy /opt/myapp # 部署到指定目录"
echo " $0 check # 检查环境"
echo " $0 start # 启动服务"
echo " $0 stop # 停止服务"
echo " $0 logs -f # 查看实时日志"
echo ""
}
# 日志函数
log_info() {
if [ "$VERBOSE" = true ]; then
echo -e "${GREEN}[INFO]${NC} $1"
fi
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
# 检查Docker环境
check_docker() {
if ! command -v docker &> /dev/null; then
log_error "Docker未安装"
exit 1
fi
# 检测Docker Compose命令类型
if docker compose version &> /dev/null; then
COMPOSE_CMD="docker compose"
elif command -v docker-compose &> /dev/null; then
COMPOSE_CMD="docker-compose"
else
log_error "Docker Compose未安装"
exit 1
fi
log_info "使用命令: ${COMPOSE_CMD}"
}
# 检查脚本文件
check_scripts() {
local scripts=("settings.xml")
for script in "${scripts[@]}"; do
if [ ! -f "$script" ]; then
log_error "必需文件 $script 不存在"
exit 1
fi
done
}
# 构建镜像
build_image() {
log_info "开始构建Docker镜像..."
# 检查必需文件
check_scripts
# 构建镜像
docker build -f ${DOCKERFILE} -t ${PROJECT_NAME}:${VERSION} .
if [ $? -eq 0 ]; then
log_success "镜像构建成功: ${PROJECT_NAME}:${VERSION}"
# 显示镜像信息
if [ "$VERBOSE" = true ]; then
echo -e "${YELLOW}镜像信息:${NC}"
docker images ${PROJECT_NAME}:${VERSION} --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}\t{{.CreatedAt}}"
fi
else
log_error "镜像构建失败"
exit 1
fi
}
# 检查环境
check_environment() {
log_info "检查环境配置..."
# 检查Docker网络
if ! docker network ls | grep -q proxy; then
log_error "proxy网络不存在请创建: docker network create proxy"
exit 1
fi
# 检查容器
local mysql_container=$(docker network inspect proxy --format '{{range .Containers}}{{.Name}} {{end}}' 2>/dev/null | tr ' ' '\n' | grep -i mysql | head -1 || true)
local redis_container=$(docker network inspect proxy --format '{{range .Containers}}{{.Name}} {{end}}' 2>/dev/null | tr ' ' '\n' | grep -i redis | head -1 || true)
local es_container=$(docker network inspect proxy --format '{{range .Containers}}{{.Name}} {{end}}' 2>/dev/null | tr ' ' '
' | grep -w "es" | head -1 || true)
if [ -z "$mysql_container" ]; then
log_error "proxy网络中未找到MySQL容器"
exit 1
fi
if [ -z "$redis_container" ]; then
log_error "proxy网络中未找到Redis容器"
exit 1
fi
if [ -z "$es_container" ]; then
log_warn "proxy网络中未找到Elasticsearch容器可选"
fi
log_success "环境检查完成"
log_info "MySQL: $mysql_container"
log_info "Redis: $redis_container"
[ ! -z "$es_container" ] && log_info "Elasticsearch: $es_container"
}
# 部署应用
deploy_app() {
local deploy_dir=${1:-$DEFAULT_DEPLOY_DIR}
log_info "部署应用到: $deploy_dir"
# 检查镜像
if ! docker images | grep -q "${PROJECT_NAME}:${VERSION}"; then
log_error "镜像 ${PROJECT_NAME}:${VERSION} 不存在,请先构建: $0 build"
exit 1
fi
# 创建部署目录
mkdir -p "$deploy_dir"/{data/{upload,temp,unzip,images,reports,elasticsearch},logs,nginx}
# 设置日志目录权限(确保容器内 app 用户可以写入)
chmod 755 "$deploy_dir/logs"
chown -R 1001:1001 "$deploy_dir/logs" 2>/dev/null || true
# 动态生成 docker-compose.yml 文件
cat > "$deploy_dir/docker-compose.yml" << EOF
version: '3.8'
services:
# 主应用服务
app:
image: ${PROJECT_NAME}:${VERSION}
container_name: digital-archive-app
ports:
- "9081:9081"
volumes:
- ./data/upload:/app/data/upload
- ./data/temp:/app/data/temp
- ./data/unzip:/app/data/unzip
- ./data/images:/app/data/images
- ./data/reports:/app/data/reports
- ./logs:/app/logs
environment:
- SPRING_PROFILES_ACTIVE=prod
- SERVER_PORT=9081
# MySQL数据库配置
- DB_HOST=mysql
- DB_PORT=3306
- DB_NAME=enterprise_digital_archives
- DB_USERNAME=root
- DB_PASSWORD=Abc@123456
- DB_DRIVER=com.mysql.cj.jdbc.Driver
# Redis配置
- REDIS_HOST=redis
- REDIS_PORT=6379
- REDIS_PASSWORD=Abc123456
# Elasticsearch配置 - 使用已有的 "es" 容器
- ELASTICSEARCH_HOST=es
- ELASTICSEARCH_PORT=9200
- ELASTICSEARCH_SCHEME=http
# OCR配置
- TESS_PATH=/usr/bin/tesseract
# 其他配置
- SWAGGER_SHOW=false
- LOG_ROOT_LEVEL=info
- LOG_APP_LEVEL=info
networks:
- proxy
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9081/point-strategy/actuator/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
# Elasticsearch - 使用已有的 "es" 容器
# 注意:确保已有的 "es" 容器已连接到 proxy 网络
networks:
proxy:
external: true
EOF
# 创建环境配置
cat > "$deploy_dir/.env" << EOF
COMPOSE_PROJECT_NAME=digital-archive
# 服务配置
SERVER_PORT=9081
SERVER_CONTEXT_PATH=/point-strategy
# MySQL数据库配置
DB_HOST=mysql
DB_PORT=3306
DB_NAME=enterprise_digital_archives
DB_USERNAME=root
DB_PASSWORD=Abc@123456
DB_DRIVER=com.mysql.cj.jdbc.Driver
# Redis配置
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=Abc123456
# Elasticsearch配置 - 使用已有的 "es" 容器
ELASTICSEARCH_HOST=es
ELASTICSEARCH_PORT=9200
ELASTICSEARCH_SCHEME=http
# OCR配置
TESS_PATH=/usr/bin/tesseract
# 其他配置
SWAGGER_SHOW=false
LOG_ROOT_LEVEL=info
LOG_APP_LEVEL=info
JAVA_OPTS=-Xmx2g -Xms1g -XX:+UseG1GC -XX:MaxGCPauseMillis=200
EOF
# 创建管理脚本
cat > "$deploy_dir/start.sh" << 'EOF'
#!/bin/bash
echo "启动数字档案系统..."
# 检测Docker Compose命令类型
if docker compose version &> /dev/null; then
COMPOSE_CMD="docker compose"
else
COMPOSE_CMD="docker-compose"
fi
${COMPOSE_CMD} up -d
echo "等待服务启动..."
sleep 30
echo "检查服务状态..."
${COMPOSE_CMD} ps
echo "服务启动完成!"
EOF
cat > "$deploy_dir/stop.sh" << 'EOF'
#!/bin/bash
echo "停止数字档案系统..."
# 检测Docker Compose命令类型
if docker compose version &> /dev/null; then
COMPOSE_CMD="docker compose"
else
COMPOSE_CMD="docker-compose"
fi
${COMPOSE_CMD} down
echo "清理未使用的镜像和容器..."
docker system prune -f
EOF
cat > "$deploy_dir/update.sh" << 'EOF'
#!/bin/bash
echo "更新数字档案系统..."
# 检测Docker Compose命令类型
if docker compose version &> /dev/null; then
COMPOSE_CMD="docker compose"
else
COMPOSE_CMD="docker-compose"
fi
echo "停止服务..."
${COMPOSE_CMD} down
echo "拉取最新镜像..."
${COMPOSE_CMD} pull
echo "启动服务..."
${COMPOSE_CMD} up -d
echo "清理旧镜像..."
docker image prune -f
EOF
# 设置执行权限
chmod +x "$deploy_dir"/{start.sh,stop.sh,update.sh}
log_success "应用部署完成: $deploy_dir"
log_info "管理命令:"
echo " 启动: cd $deploy_dir && ./start.sh"
echo " 停止: cd $deploy_dir && ./stop.sh"
echo " 更新: cd $deploy_dir && ./update.sh"
}
# 启动服务
start_services() {
local deploy_dir=${1:-$DEFAULT_DEPLOY_DIR}
if [ ! -d "$deploy_dir" ]; then
log_error "部署目录不存在: $deploy_dir"
exit 1
fi
cd "$deploy_dir"
if [ ! -f "start.sh" ]; then
log_error "启动脚本不存在,请先部署: $0 deploy $deploy_dir"
exit 1
fi
./start.sh
log_success "服务启动完成"
if [ "$VERBOSE" = true ]; then
echo -e "${YELLOW}访问地址: http://localhost:9081/point-strategy${NC}"
fi
}
# 停止服务
stop_services() {
local deploy_dir=${1:-$DEFAULT_DEPLOY_DIR}
if [ ! -d "$deploy_dir" ]; then
log_error "部署目录不存在: $deploy_dir"
exit 1
fi
cd "$deploy_dir"
if [ -f "stop.sh" ]; then
./stop.sh
log_success "服务停止完成"
else
log_warn "停止脚本不存在尝试使用Docker Compose"
if docker compose version &> /dev/null; then
docker compose down
else
docker-compose down
fi
fi
}
# 重启服务
restart_services() {
local deploy_dir=${1:-$DEFAULT_DEPLOY_DIR}
log_info "重启服务..."
stop_services "$deploy_dir"
sleep 2
start_services "$deploy_dir"
log_success "服务重启完成"
}
# 查看日志
show_logs() {
local deploy_dir=${1:-$DEFAULT_DEPLOY_DIR}
local follow=$2
if [ ! -d "$deploy_dir" ]; then
log_error "部署目录不存在: $deploy_dir"
exit 1
fi
cd "$deploy_dir"
if [ "$follow" = "-f" ]; then
if docker compose version &> /dev/null; then
docker compose logs -f app
else
docker-compose logs -f app
fi
else
if docker compose version &> /dev/null; then
docker compose logs --tail=100 app
else
docker-compose logs --tail=100 app
fi
fi
}
# 查看状态
show_status() {
local deploy_dir=${1:-$DEFAULT_DEPLOY_DIR}
if [ ! -d "$deploy_dir" ]; then
log_error "部署目录不存在: $deploy_dir"
exit 1
fi
cd "$deploy_dir"
echo -e "${CYAN}=== 数字档案系统服务状态 ===${NC}"
if docker compose version &> /dev/null; then
docker compose ps
else
docker-compose ps
fi
echo ""
echo -e "${CYAN}=== 容器资源使用情况 ===${NC}"
docker stats --no-stream
}
# 更新服务
update_services() {
local deploy_dir=${1:-$DEFAULT_DEPLOY_DIR}
if [ ! -d "$deploy_dir" ]; then
log_error "部署目录不存在: $deploy_dir"
exit 1
fi
cd "$deploy_dir"
if [ -f "update.sh" ]; then
./update.sh
log_success "服务更新完成"
else
log_warn "更新脚本不存在,请先部署: $0 deploy $deploy_dir"
fi
}
# 清理资源
clean_resources() {
log_info "清理Docker资源..."
# 清理停止的容器
docker container prune -f
# 清理未使用的镜像
docker image prune -f
# 清理未使用的网络
docker network prune -f
# 清理未使用的卷
docker volume prune -f
log_success "资源清理完成"
}
# 主函数
main() {
# 解析命令行参数
COMMAND=""
VERBOSE=false
FORCE=false
while [[ $# -gt 0 ]]; do
case $1 in
build|deploy|check|start|stop|restart|logs|status|update|clean)
COMMAND=$1
shift
;;
-h|--help)
show_help
exit 0
;;
-v|--verbose)
VERBOSE=true
shift
;;
--force)
FORCE=true
shift
;;
-q|--quiet)
# 重定向输出到/dev/null
exec 1>/dev/null 2>&1
;;
-*)
log_error "未知选项: $1"
show_help
exit 1
;;
*)
# 参数传递给具体命令
break
;;
esac
done
# 如果没有命令,显示帮助
if [ -z "$COMMAND" ]; then
show_help
exit 0
fi
# 显示横幅
if [ "$VERBOSE" = true ]; then
show_banner
fi
# 检查Docker环境
check_docker
# 执行对应命令
case $COMMAND in
build)
build_image
;;
deploy)
deploy_app "$@"
;;
check)
check_environment
;;
start)
start_services "$@"
;;
stop)
stop_services "$@"
;;
restart)
restart_services "$@"
;;
logs)
show_logs "$@"
;;
status)
show_status "$@"
;;
update)
update_services "$@"
;;
clean)
clean_resources
;;
*)
log_error "未知命令: $COMMAND"
show_help
exit 1
;;
esac
}
# 执行主函数
main "$@"