From 384171ea56062b3d51fc3ba660e1d2d2c9135923 Mon Sep 17 00:00:00 2001 From: chenqiang Date: Thu, 13 Nov 2025 17:41:38 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E4=B8=94=E5=AE=9E=E7=8E=B0=E4=B8=80?= =?UTF-8?q?=E4=B8=AA=E4=BB=A5docker=E5=90=AF=E5=8A=A8=E7=9A=84seaweedfs?= =?UTF-8?q?=E5=AF=B9=E8=B1=A1=E5=AD=98=E5=82=A8=E6=9C=8D=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 38 +++++ README.md | 120 ++++++++++++++ docker-compose.yml | 37 +++++ init | 260 +++++++++++++++++++++++++++++ service | 396 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 851 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 docker-compose.yml create mode 100755 init create mode 100755 service diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..66f935a --- /dev/null +++ b/.gitignore @@ -0,0 +1,38 @@ +# 数据目录 +filer_data/ +master_data/ +volume_data/ + +# 环境变量文件 +.envrc +.env +.env.local + +# 敏感信息 +seaweedfs_password.enc +*_password.enc + +# 备份文件 +*_bak_* +*_backup_* + +# Docker相关 +.docker/ +*.log +logs/ + +# IDE和编辑器文件 +.idea/ +.vscode/ +*.swp +*.swo +*~ + +# macOS文件 +.DS_Store +.AppleDouble +.LSOverride + +# 其他临时文件 +*.tmp +*.temp \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..f2ba3c2 --- /dev/null +++ b/README.md @@ -0,0 +1,120 @@ +# SeaweedFS 文件存储服务 + +本目录包含基于 [SeaweedFS](https://github.com/seaweedfs/seaweedfs) 的分布式文件存储服务配置,提供S3兼容接口,用于文件的存储和管理。 + +## 服务组件 + +SeaweedFS 服务由以下组件组成: + +- **Master Server**: 负责管理卷服务器和文件分配 +- **Volume Server**: 负责实际存储数据 +- **Filer**: 提供文件系统接口 +- **S3 Gateway**: 提供S3兼容接口 + +## 快速开始 + +### 1. 初始化环境 + +首先执行初始化脚本,设置环境变量和创建必要的配置文件: + +```bash +cd /Users/chenqiang/workspace/work/项目记录/202510铁岭县内网文件分发/demo/server/oss +./init +``` + +初始化过程中会提示设置以下参数: +- S3服务端口(默认:25003) +- S3访问密钥 +- S3密钥(会加密存储) + +### 2. 启动服务 + +使用提供的服务脚本启动SeaweedFS: + +```bash +./service start +``` + +### 3. 停止服务 + +```bash +./service stop +``` + +### 4. 查看服务状态 + +```bash +./service status +``` + +## 环境变量配置 + +初始化后,环境变量将保存在 `.envrc` 文件中。主要配置项包括: + +- `SEAWEEDFS_VERSION`: SeaweedFS 版本 +- `S3_PORT`: S3服务端口 +- `S3_ACCESS_KEY`: S3访问密钥 +- `S3_SECRET_KEY`: S3密钥(加密存储) +- 各容器名称配置 + +## 数据存储 + +- **Master数据**: `./master_data/` +- **Volume数据**: `./volume_data/` +- **Filer数据**: `./filer_data/` + +> **注意**: 数据目录会被 `.gitignore` 忽略,不会提交到代码仓库。 + +## S3客户端配置 + +使用S3兼容的客户端访问服务时,需要配置以下参数: + +- **Endpoint**: `http://localhost:8333` +- **Access Key**: 初始化时设置的值 +- **Secret Key**: 初始化时设置的值 +- **Region**: 可以使用任意值,如 `us-east-1` + +## 安全注意事项 + +- S3密钥使用OpenSSL加密存储在 `seaweedfs_password.enc` 文件中 +- 敏感配置文件(如 `.envrc` 和 `seaweedfs_password.enc`)已添加到 `.gitignore` +- 建议定期备份数据目录 + +## 故障排除 + +### 常见问题 + +1. **服务启动失败** + - 检查端口是否被占用 + - 查看容器日志:`docker logs seaweedfs-master` 等 + +2. **S3访问认证失败** + - 确认访问密钥和密钥是否正确 + - 检查 `.envrc` 文件中的配置 + +3. **数据丢失** + - 确保定期备份数据目录 + - 避免直接修改数据目录中的文件 + +## 维护指南 + +### 更新SeaweedFS版本 + +1. 修改 `.envrc` 中的 `SEAWEEDFS_VERSION` 值 +2. 重启服务:`./service restart` + +### 清理旧数据 + +> **警告**: 清理数据前请确保已备份重要数据! + +可以通过停止服务并清空数据目录来清理所有数据: + +```bash +./service stop +rm -rf master_data/* volume_data/* filer_data/* +./service start +``` + +## 许可证 + +[MIT](LICENSE) \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..5612b02 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,37 @@ +version: '3.9' + +services: + master: + image: chrislusf/seaweedfs:${SEAWEEDFS_VERSION:-4.00} # use a remote image + container_name: ${MASTER_CONTAINER_NAME:-seaweedfs-master} + volumes: + - ./master_data:/data + command: "master -ip=master -ip.bind=0.0.0.0 -metricsPort=9324" + volume: + image: chrislusf/seaweedfs:${SEAWEEDFS_VERSION:-4.00} # use a remote image + container_name: ${VOLUME_CONTAINER_NAME:-seaweedfs-volume} + volumes: + - ./volume_data:/data + command: 'volume -mserver="master:9333" -ip.bind=0.0.0.0 -port=8080 -metricsPort=9325' + depends_on: + - master + filer: + image: chrislusf/seaweedfs:${SEAWEEDFS_VERSION:-4.00} # use a remote image + container_name: ${FILER_CONTAINER_NAME:-seaweedfs-filer} + volumes: + - ./filer_data:/data + command: 'filer -master="master:9333" -ip.bind=0.0.0.0 -port=8888 -metricsPort=9326' + depends_on: + - master + - volume + s3: + image: chrislusf/seaweedfs:${SEAWEEDFS_VERSION:-4.00} # use a remote image + container_name: ${S3_CONTAINER_NAME:-seaweedfs-s3} + ports: + - ${S3_PORT:-8333}:8333 # 只映射S3服务端口给Spring Boot应用访问 + environment: + - S3_ACCESS_KEY=${S3_ACCESS_KEY:-seaweedfs} + - S3_SECRET_KEY=${S3_SECRET_KEY:-seaweedfs} + command: 's3 -filer="filer:8888" -ip.bind=0.0.0.0 -metricsPort=9327' + depends_on: + - filer diff --git a/init b/init new file mode 100755 index 0000000..4f68203 --- /dev/null +++ b/init @@ -0,0 +1,260 @@ +#!/bin/bash + +# SeaweedFS初始化脚本 +# 用于初始化或重新初始化SeaweedFS配置环境 + +# 获取脚本所在目录的绝对路径 +SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) + +# 切换工作目录到脚本所在目录 +cd $SCRIPT_DIR + +# 检查必要的命令 +check_commands() { + if ! command -v openssl &> /dev/null; then + echo "错误: 未找到openssl命令,请先安装" + exit 1 + fi + + if ! command -v direnv &> /dev/null; then + echo "警告: 未找到direnv命令,建议安装以获得最佳体验" + fi + + if ! command -v docker-compose &> /dev/null; then + echo "错误: 未找到docker-compose命令,请先安装" + exit 1 + fi +} + +# 创建必要的目录结构 +create_directories() { + echo "创建必要的目录结构..." + mkdir -p ./master_data + mkdir -p ./volume_data + mkdir -p ./filer_data + echo "目录结构创建完成" +} + +# 检查docker-compose.yml文件是否存在 +check_docker_compose() { + if [ ! -f "docker-compose.yml" ]; then + echo "警告: 未找到docker-compose.yml文件,请确保该文件已存在" + echo "提示: 请手动创建或复制正确的docker-compose.yml文件" + fi +} + +# 初始化配置文件 +initialize_files() { + # 提示用户输入S3访问密钥(步骤1) + default_access_key="seaweedfs" + read -p "请输入S3_ACCESS_KEY [$default_access_key]: " s3_access_key + + # 如果用户直接回车,使用默认值 + if [ -z "$s3_access_key" ]; then + s3_access_key="$default_access_key" + fi + echo "S3_ACCESS_KEY设置为: $s3_access_key" + + # 提示用户输入S3密钥(步骤2) + read -s -p "请输入S3_SECRET_KEY: " s3_secret_key + echo + read -s -p "请再次输入密码确认: " s3_secret_key_confirm + echo + + # 验证密码一致性 + if [ "$s3_secret_key" != "$s3_secret_key_confirm" ]; then + echo "错误: 两次输入的密码不一致" + return 1 + fi + + # 验证密码强度(可选) + if [ ${#s3_secret_key} -lt 8 ]; then + echo "警告: 密码长度少于8个字符,建议使用强密码" + read -p "是否继续使用此密码?(y/n): " continue + if [ "$continue" != "y" ]; then + return 1 + fi + fi + + # 创建加密文件(步骤3) + echo "创建加密的密码文件..." + echo "请为加密文件设置一个密码(主密钥):" + echo -n "$s3_secret_key" | openssl enc -aes-256-cbc -salt -pbkdf2 -iter 10000 -out seaweedfs_password.enc + + # 检查加密是否成功 + if [ $? -ne 0 ]; then + echo "错误: 创建加密文件失败" + return 1 + fi + + # 设置加密文件权限 + chmod 600 seaweedfs_password.enc + echo "加密文件创建成功,权限设置为600" + + # 提示用户输入SeaweedFS镜像版本(步骤4) + default_version="4.00" + read -p "请输入SeaweedFS镜像版本 [$default_version]: " seaweedfs_version + + # 如果用户直接回车,使用默认值 + if [ -z "$seaweedfs_version" ]; then + seaweedfs_version="$default_version" + fi + echo "SeaweedFS镜像版本设置为: $seaweedfs_version" + + # 提示用户输入S3服务映射端口号(步骤5) + default_port="8333" + read -p "请输入S3服务映射端口号 [$default_port]: " s3_port + + # 如果用户直接回车,使用默认值 + if [ -z "$s3_port" ]; then + s3_port="$default_port" + fi + echo "S3服务映射端口号设置为: $s3_port" + + # 提示用户输入各个容器的名称(步骤6) + default_master_name="seaweedfs-master" + read -p "请输入master容器名称 [$default_master_name]: " master_container_name + + # 如果用户直接回车,使用默认值 + if [ -z "$master_container_name" ]; then + master_container_name="$default_master_name" + fi + echo "master容器名称设置为: $master_container_name" + + default_volume_name="seaweedfs-volume" + read -p "请输入volume容器名称 [$default_volume_name]: " volume_container_name + + # 如果用户直接回车,使用默认值 + if [ -z "$volume_container_name" ]; then + volume_container_name="$default_volume_name" + fi + echo "volume容器名称设置为: $volume_container_name" + + default_filer_name="seaweedfs-filer" + read -p "请输入filer容器名称 [$default_filer_name]: " filer_container_name + + # 如果用户直接回车,使用默认值 + if [ -z "$filer_container_name" ]; then + filer_container_name="$default_filer_name" + fi + echo "filer容器名称设置为: $filer_container_name" + + default_s3_name="seaweedfs-s3" + read -p "请输入s3容器名称 [$default_s3_name]: " s3_container_name + + # 如果用户直接回车,使用默认值 + if [ -z "$s3_container_name" ]; then + s3_container_name="$default_s3_name" + fi + echo "s3容器名称设置为: $s3_container_name" + + # 创建.envrc文件 + echo "创建.envrc配置文件..." + cat > .envrc << EOF +# SeaweedFS配置环境变量 +export SEAWEEDFS_VERSION=$seaweedfs_version +export S3_PORT=$s3_port +export S3_ACCESS_KEY=$s3_access_key +export S3_SECRET_KEY=\$(openssl enc -aes-256-cbc -d -pbkdf2 -iter 10000 -in seaweedfs_password.enc) +export MASTER_CONTAINER_NAME=$master_container_name +export VOLUME_CONTAINER_NAME=$volume_container_name +export FILER_CONTAINER_NAME=$filer_container_name +export S3_CONTAINER_NAME=$s3_container_name +EOF + + # 设置.envrc文件权限 + chmod 600 .envrc + echo ".envrc文件创建成功,权限设置为600" + + # 检查docker-compose.yml文件是否存在 + check_docker_compose + + # 自动执行direnv allow并提供状态反馈 + if command -v direnv &> /dev/null; then + echo "" + echo "📝 初始化完成!自动配置环境变量..." + echo "正在执行 direnv allow..." + if direnv allow > /dev/null 2>&1; then + echo "✅ direnv allow 执行成功!环境变量已启用" + else + echo "❌ direnv allow 执行失败,请手动运行 'direnv allow' 来启用环境变量" + fi + else + echo "" + echo "初始化完成!建议安装direnv以获得更好的使用体验:" + echo " macOS: brew install direnv" + echo " Linux: apt-get install direnv 或 yum install direnv" + fi + + return 0 +} + +# 清理旧的容器(可选) +clean_old_containers() { + # 检查是否有旧的容器运行 + echo "检查并清理可能的旧容器..." + local containers=("seaweedfs-master" "seaweedfs-volume" "seaweedfs-filer" "seaweedfs-s3" "oss-master-1" "oss-volume-1" "oss-filer-1" "oss-s3-1") + + for container in "${containers[@]}"; do + if docker ps -a | grep -q "$container"; then + echo "停止并移除容器: $container" + docker stop "$container" > /dev/null 2>&1 || true + docker rm "$container" > /dev/null 2>&1 || true + fi + done + + # 不清理网络配置,保持与外部网络的兼容性 +} + +# 主函数 +main() { + echo "SeaweedFS环境初始化脚本" + echo "===================================" + + # 检查必要的命令 + check_commands + + # 检查文件是否存在 + if [ -f "seaweedfs_password.enc" ] && [ -f ".envrc" ]; then + echo "" + echo "检测到seaweedfs_password.enc和.envrc文件已存在" + read -p "是否重新初始化?这将覆盖现有配置!(y/n): " reinitialize + + if [ "$reinitialize" != "y" ]; then + echo "初始化取消" + exit 0 + fi + + # 备份现有文件 + backup_suffix="_bak_$(date +%Y%m%d%H%M%S)" + echo "备份现有文件..." + cp seaweedfs_password.enc "seaweedfs_password.enc$backup_suffix" 2>/dev/null + cp .envrc ".envrc$backup_suffix" 2>/dev/null + echo "备份完成" + fi + + # 创建目录结构 + create_directories + + # 初始化配置文件 + while ! initialize_files; do + echo "请重新输入配置信息..." + done + + # 清理旧的容器 + clean_old_containers + + echo "" + echo "===================================" + echo "初始化成功!" + echo "使用说明:" + echo "1. 使用 './service start' 启动服务" + echo "2. 使用 './service stop' 停止服务" + echo "3. 使用 './service status' 查看服务状态" + echo "4. 使用 './service restart' 重启服务" + echo "" + echo "S3服务访问地址将为: http://localhost:${s3_port:-8333}" +} + +# 执行主函数 +main \ No newline at end of file diff --git a/service b/service new file mode 100755 index 0000000..b4aa966 --- /dev/null +++ b/service @@ -0,0 +1,396 @@ +#!/bin/bash + +# SeaweedFS服务管理脚本 +# 用法: ./service start|stop|status|restart|help + +# 定义颜色输出 +echo_green() { echo -e "\033[32m$1\033[0m"; } +echo_yellow() { echo -e "\033[33m$1\033[0m"; } +echo_red() { echo -e "\033[31m$1\033[0m"; } +echo_blue() { echo -e "\033[34m$1\033[0m"; } + +# 日志函数 +log_info() { echo_blue "[INFO] $1"; } +log_success() { echo_green "[SUCCESS] $1"; } +log_warning() { echo_yellow "[WARNING] $1"; } +log_error() { echo_red "[ERROR] $1"; } + +# 获取脚本所在目录的绝对路径 +SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) + +# 切换工作目录到脚本所在目录 +cd "$SCRIPT_DIR" || { + log_error "无法切换到脚本目录" + exit 1 +} + +# 检查系统命令 +system_commands=("docker" "docker-compose" "openssl") +check_system_commands() { + for cmd in "${system_commands[@]}"; do + if ! command -v "$cmd" &> /dev/null; then + log_error "命令 $cmd 未安装,请先安装" + return 1 + fi + done + return 0 +} + +# 检查并加载环境变量 +load_env_variables() { + # 检查必要的命令 + if ! check_system_commands; then + return 1 + fi + + # 首先尝试加载.envrc中的环境变量 + if [ -f ".envrc" ]; then + log_info "加载.envrc中的环境变量..." + + # 检查是否安装了direnv + if command -v direnv &> /dev/null; then + log_info "使用direnv加载环境变量" + eval "$(direnv export bash)" + else + log_warning "direnv未安装,直接加载.envrc中的环境变量" + # 手动加载.envrc中的环境变量,排除包含$(...)的行 + while IFS= read -r line || [ -n "$line" ]; do + if [[ $line == export* && ! $line =~ \$\(.*\) ]]; then + eval "$line" + fi + done < .envrc + fi + else + log_error ".envrc文件不存在" + return 1 + fi + + # 特殊处理S3_SECRET_KEY,因为它包含解密命令 + if [ -z "$S3_SECRET_KEY" ] && [ -f "seaweedfs_password.enc" ]; then + log_info "解密S3_SECRET_KEY..." + # 直接执行解密命令 + export S3_SECRET_KEY=$(openssl enc -aes-256-cbc -d -pbkdf2 -iter 10000 -in seaweedfs_password.enc 2>/dev/null) + if [ $? -ne 0 ]; then + log_error "密码解密失败,请检查密码是否正确" + log_error "提示: 可能需要重新初始化密码文件" + return 1 + fi + fi + + # 定义默认环境变量(如果未设置) + export SEAWEEDFS_VERSION=${SEAWEEDFS_VERSION:-4.00} + export S3_PORT=${S3_PORT:-8333} + export S3_ACCESS_KEY=${S3_ACCESS_KEY:-seaweedfs} + export S3_SECRET_KEY=${S3_SECRET_KEY:-seaweedfs} + export MASTER_CONTAINER_NAME=${MASTER_CONTAINER_NAME:-seaweedfs-master} + export VOLUME_CONTAINER_NAME=${VOLUME_CONTAINER_NAME:-seaweedfs-volume} + export FILER_CONTAINER_NAME=${FILER_CONTAINER_NAME:-seaweedfs-filer} + export S3_CONTAINER_NAME=${S3_CONTAINER_NAME:-seaweedfs-s3} + + log_info "环境变量加载完成:" + log_info " - SeaweedFS版本: $SEAWEEDFS_VERSION" + log_info " - S3端口: $S3_PORT" + log_info " - 容器名称:" + log_info " * Master: $MASTER_CONTAINER_NAME" + log_info " * Volume: $VOLUME_CONTAINER_NAME" + log_info " * Filer: $FILER_CONTAINER_NAME" + log_info " * S3: $S3_CONTAINER_NAME" + + return 0 +} + +# 创建必要的目录 +create_required_directories() { + log_info "创建必要的数据目录..." + mkdir -p ./master_data ./volume_data ./filer_data + if [ $? -eq 0 ]; then + log_success "数据目录创建成功" + return 0 + else + log_error "数据目录创建失败" + return 1 + fi +} + +# 检查容器是否存在且运行中 +is_container_running() { + local container_name=$1 + docker ps --format "{{.Names}}" | grep -q "^$container_name$" + return $? +} + +# 清理旧容器(避免名称冲突) +clean_old_containers() { + local containers=("$MASTER_CONTAINER_NAME" "$VOLUME_CONTAINER_NAME" "$FILER_CONTAINER_NAME" "$S3_CONTAINER_NAME") + local removed_containers=0 + + log_info "检查并清理可能存在的旧容器..." + + for container in "${containers[@]}"; do + if docker ps -a --format "{{.Names}}" | grep -q "^$container$"; then + log_warning "发现旧容器: $container,正在清理..." + docker rm -f "$container" > /dev/null + if [ $? -eq 0 ]; then + log_success "已移除旧容器: $container" + removed_containers=$((removed_containers + 1)) + else + log_error "无法移除容器: $container" + fi + fi + done + + # 清理可能存在的旧网络 + local network_name="$(basename "$SCRIPT_DIR")_default" + if docker network ls --format "{{.Name}}" | grep -q "^$network_name$"; then + log_warning "发现旧网络: $network_name,正在清理..." + docker network rm "$network_name" > /dev/null + if [ $? -eq 0 ]; then + log_success "已移除旧网络: $network_name" + fi + fi + + if [ $removed_containers -gt 0 ]; then + log_success "已清理 $removed_containers 个旧容器" + else + log_info "没有需要清理的旧容器" + fi +} + +# 启动服务 +start_service() { + log_info "启动SeaweedFS服务..." + + # 加载环境变量 + if ! load_env_variables; then + log_error "环境变量加载失败,服务启动终止" + return 1 + fi + + # 创建必要的目录 + if ! create_required_directories; then + return 1 + fi + + # 检查docker-compose.yml是否存在 + if [ ! -f "docker-compose.yml" ]; then + log_error "docker-compose.yml文件不存在" + return 1 + fi + + # 清理旧容器,避免名称冲突 + clean_old_containers + + # 启动docker容器 + log_info "使用docker-compose启动服务..." + docker-compose up -d + + # 检查启动是否成功 + if [ $? -ne 0 ]; then + log_error "SeaweedFS服务启动失败" + return 1 + fi + + # 等待几秒钟让容器完全启动 + log_info "服务正在初始化,请稍候..." + sleep 3 + + # 再次检查状态以确保所有容器都已启动 + status_service + local status_result=$? + + if [ $status_result -eq 0 ]; then + log_success "SeaweedFS服务启动完成!" + log_success "S3服务访问地址: http://localhost:$S3_PORT" + return 0 + else + log_warning "服务可能未完全启动,请检查容器状态" + return 1 + fi +} + +# 停止服务 +stop_service() { + log_info "停止SeaweedFS服务..." + + # 加载环境变量(包括密码验证) + if ! load_env_variables; then + log_error "环境变量加载失败,服务停止终止" + return 1 + fi + + # 首先检查服务是否正在运行 + if ! docker-compose ps | grep -q "Up"; then + log_info "SeaweedFS服务已经停止或未运行" + return 0 + fi + + # 使用docker-compose down停止服务 + log_info "使用docker-compose停止所有服务..." + docker-compose down + + if [ $? -eq 0 ]; then + log_success "SeaweedFS服务已成功停止" + return 0 + else + log_warning "docker-compose down命令失败,尝试直接停止容器..." + + # 尝试逐个停止并删除容器 + local containers=("$S3_CONTAINER_NAME" "$FILER_CONTAINER_NAME" "$VOLUME_CONTAINER_NAME" "$MASTER_CONTAINER_NAME") + local stopped=0 + + for container in "${containers[@]}"; do + if is_container_running "$container"; then + log_info "直接停止容器: $container" + docker stop "$container" > /dev/null + if [ $? -eq 0 ]; then + docker rm "$container" > /dev/null + log_success "已停止并移除容器: $container" + stopped=$((stopped + 1)) + else + log_error "无法停止容器: $container" + fi + fi + done + + if [ $stopped -gt 0 ]; then + log_success "已成功停止 $stopped 个容器" + return 0 + else + log_error "无法停止任何容器,请检查Docker状态" + return 1 + fi + fi +} + +# 检查服务状态 +status_service() { + log_info "检查SeaweedFS服务状态..." + + # 加载环境变量 + if ! load_env_variables; then + log_error "环境变量加载失败,无法检查状态" + return 2 + fi + + # 定义容器数组 + local containers=("$MASTER_CONTAINER_NAME" "$VOLUME_CONTAINER_NAME" "$FILER_CONTAINER_NAME" "$S3_CONTAINER_NAME") + local container_names=("Master" "Volume" "Filer" "S3") + local running_containers=0 + local all_containers=${#containers[@]} + + log_info "详细状态检查:" + + # 检查每个容器的状态 + for i in "${!containers[@]}"; do + local container=${containers[$i]} + local name=${container_names[$i]} + + if is_container_running "$container"; then + log_success "✅ $name 容器 ($container) 正在运行" + running_containers=$((running_containers + 1)) + else + # 检查容器是否存在但已停止 + if docker ps -a --format "{{.Names}}" | grep -q "^$container$"; then + log_warning "⚠️ $name 容器 ($container) 已停止" + # 获取停止原因 + local exit_code=$(docker inspect --format='{{.State.ExitCode}}' "$container") + log_warning " 退出代码: $exit_code" + else + log_error "❌ $name 容器 ($container) 不存在" + fi + fi + done + + # 输出总体状态 + log_info "--------------------------------------------------" + + if [ $running_containers -eq $all_containers ]; then + log_success "✅ SeaweedFS服务完全正常运行" + log_success "S3服务访问地址: http://localhost:$S3_PORT" + return 0 + elif [ $running_containers -gt 0 ]; then + log_warning "⚠️ SeaweedFS服务部分运行 ($running_containers/$all_containers 容器运行中)" + return 1 + else + log_error "❌ SeaweedFS服务未运行" + return 2 + fi +} + +# 重启服务 +restart_service() { + log_info "重启SeaweedFS服务..." + + # 先停止服务 + stop_service + local stop_result=$? + + # 停止成功后,启动服务 + if [ $stop_result -eq 0 ]; then + log_info "正在启动SeaweedFS服务..." + start_service + return $? + else + log_error "服务停止失败,无法重启" + return 1 + fi +} + +# 显示帮助信息 +show_help() { + echo "" + echo_blue "📦 SeaweedFS服务管理脚本" + echo "" + echo "用法: ./service [command]" + echo "" + echo "命令:" + echo " start 启动SeaweedFS服务" + echo " stop 停止SeaweedFS服务" + echo " status 检查SeaweedFS服务状态" + echo " restart 重启SeaweedFS服务" + echo " help 显示此帮助信息" + echo "" + echo "示例:" + echo " ./service start # 启动所有SeaweedFS服务" + echo " ./service status # 检查服务运行状态" + echo " ./service restart # 重启所有服务" + echo "" +} + +# 检查命令参数 +if [ $# -eq 0 ]; then + log_error "请指定命令" + show_help + exit 1 +fi + +# 执行对应的命令 +case "$1" in + start) + start_service + exit $? + ;; + stop) + stop_service + exit $? + ;; + status) + status_service + exit $? + ;; + restart) + restart_service + exit $? + ;; + help|\ + -h|\ + --help) + show_help + exit 0 + ;; + *) + log_error "未知命令 '$1'" + show_help + exit 1 + ;; +esac \ No newline at end of file