614 lines
15 KiB
Bash
Executable File
614 lines
15 KiB
Bash
Executable File
#!/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 "$@"
|