feat(infrastructure): add MinIO object storage configuration

- Add docker-compose.yml for MinIO with auto-initialization
- Add deploy.sh script with comprehensive management commands
- Add nginx reverse proxy configuration for S3 API and console
- Configure default buckets: avatars, documents, resources, backups
- Add CDN caching support for public resources

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
hailin 2025-12-07 21:12:57 -08:00
parent b36987fee1
commit ea6ede598d
6 changed files with 1256 additions and 0 deletions

View File

@ -0,0 +1,102 @@
# =============================================================================
# MinIO Object Storage - 环境配置
# =============================================================================
#
# 部署位置: 与 Kong, Nginx 同一服务器 (Server A: 192.168.1.100)
# 用途: 用户头像、文档、资源文件的对象存储
#
# 网络拓扑:
# ┌─────────────────────────────────────────────────────────────────────────────┐
# │ Server A (192.168.1.100) - Gateway & Storage │
# ├─────────────────────────────────────────────────────────────────────────────┤
# │ Nginx :80/443 - 反向代理 (SSL 终止) │
# │ Kong :8000 - API 网关 │
# │ MinIO API :9000 - S3 兼容 API │
# │ MinIO Console:9001 - Web 管理控制台 │
# └─────────────────────────────────────────────────────────────────────────────┘
#
# 设置步骤:
# 1. 复制配置: cp .env.example .env
# 2. 修改密码: 必须修改 MINIO_ROOT_PASSWORD
# 3. 创建数据目录: sudo mkdir -p /data/minio && sudo chown -R 1000:1000 /data/minio
# 4. 启动服务: ./deploy.sh up
#
# =============================================================================
# =============================================================================
# MinIO 认证配置
# =============================================================================
# 管理员用户名 (至少 3 个字符)
MINIO_ROOT_USER=admin
# 管理员密码 (至少 8 个字符)
# ⚠️ 安全警告: 生产环境必须修改此密码!
# 生成安全密码: openssl rand -base64 32
MINIO_ROOT_PASSWORD=change_me_to_secure_password
# =============================================================================
# MinIO 服务端口
# =============================================================================
# S3 API 端口 - 应用程序通过此端口上传下载文件
MINIO_API_PORT=9000
# Web 控制台端口 - 管理员通过此端口管理 MinIO
MINIO_CONSOLE_PORT=9001
# =============================================================================
# MinIO 服务器配置
# =============================================================================
# 区域设置 (用于 S3 兼容性)
MINIO_REGION=cn-east-1
# 控制台外部访问 URL (用于 Nginx 反向代理场景)
# 内网访问: http://192.168.1.100:9001
# 外网访问: https://minio.szaiai.com
MINIO_CONSOLE_URL=http://localhost:9001
# =============================================================================
# 数据存储配置
# =============================================================================
# 数据存储路径 (确保有足够的磁盘空间)
# 建议使用独立的数据盘
MINIO_DATA_PATH=/data/minio
# =============================================================================
# 默认存储桶配置
# =============================================================================
# 用户头像存储桶 (公开读取)
BUCKET_AVATARS=avatars
# 用户文档存储桶 (需要认证)
BUCKET_DOCUMENTS=documents
# 应用资源文件存储桶 (公开读取)
BUCKET_RESOURCES=resources
# 备份文件存储桶 (私有)
BUCKET_BACKUPS=backups
# =============================================================================
# 服务间通信配置 (供后端服务使用)
# =============================================================================
# MinIO 内部端点 (后端服务访问)
# 在同一服务器: http://localhost:9000
# 在不同服务器: http://192.168.1.100:9000
MINIO_ENDPOINT=http://localhost:9000
# 公开访问 URL (前端直接访问静态资源)
# 通过 Nginx 代理: https://cdn.szaiai.com
# 直接访问: http://192.168.1.100:9000
MINIO_PUBLIC_URL=http://localhost:9000
# =============================================================================
# 网络配置
# =============================================================================
# 本机 IP (供其他服务连接)
MINIO_HOST_IP=192.168.1.100
# =============================================================================
# 日志配置
# =============================================================================
# 日志级别: DEBUG, INFO, WARNING, ERROR
MINIO_LOG_LEVEL=INFO

View File

@ -0,0 +1,244 @@
# MinIO 对象存储服务
MinIO 是一个高性能的分布式对象存储系统,兼容 Amazon S3 API。本配置用于存储用户头像、文档、资源文件等。
## 架构
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ Server A (192.168.1.100) - Gateway & Storage │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────────┐ │
│ │ Nginx │────▶│ MinIO │────▶│ /data/minio (Volume) │ │
│ │ :80/:443 │ │ :9000/9001 │ │ │ │
│ └─────────────┘ └─────────────┘ └─────────────────────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ Kong │ │ Buckets: │ │
│ │ :8000 │ │ - avatars │ │
│ └─────────────┘ │ - documents│ │
│ │ - resources│ │
│ │ - backups │ │
│ └─────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
```
## 快速开始
### 1. 配置环境变量
```bash
cd backend/infrastructure/minio
cp .env.example .env
# 编辑 .env 文件,修改以下必要配置
vim .env
# 必须修改的配置:
# MINIO_ROOT_PASSWORD=your_secure_password
```
### 2. 创建数据目录
```bash
sudo mkdir -p /data/minio
sudo chown -R 1000:1000 /data/minio
```
### 3. 启动服务
```bash
./deploy.sh up
```
### 4. 验证服务
```bash
# 查看状态
./deploy.sh status
# 健康检查
./deploy.sh health
# 列出存储桶
./deploy.sh list-buckets
```
## 部署脚本命令
| 命令 | 说明 |
|------|------|
| `./deploy.sh up` | 启动 MinIO |
| `./deploy.sh down` | 停止 MinIO |
| `./deploy.sh restart` | 重启 MinIO |
| `./deploy.sh logs` | 查看日志 |
| `./deploy.sh logs -f` | 实时查看日志 |
| `./deploy.sh status` | 查看运行状态 |
| `./deploy.sh health` | 健康检查 |
| `./deploy.sh create-bucket <name>` | 创建存储桶 |
| `./deploy.sh list-buckets` | 列出所有存储桶 |
| `./deploy.sh info` | 查看服务器信息 |
| `./deploy.sh backup` | 备份配置 |
## 访问地址
| 服务 | 地址 | 说明 |
|------|------|------|
| S3 API | http://localhost:9000 | 应用程序访问 |
| Web Console | http://localhost:9001 | 管理界面 |
## 默认存储桶
| 存储桶 | 访问策略 | 用途 |
|--------|----------|------|
| `avatars` | 公开读取 | 用户头像 |
| `documents` | 私有 | 用户文档 |
| `resources` | 公开读取 | 应用资源 |
| `backups` | 私有 | 备份文件 |
## Nginx 配置
### 安装 Nginx 反向代理
```bash
cd nginx
sudo ./install.sh
# 配置 SSL
sudo ./install.sh --ssl
```
### 域名配置
| 域名 | 用途 |
|------|------|
| `minio.szaiai.com` | MinIO S3 API |
| `console.minio.szaiai.com` | MinIO 管理控制台 |
| `cdn.szaiai.com` | 静态资源 CDN |
## 后端服务集成
### NestJS 集成示例
```typescript
// minio.config.ts
import { registerAs } from '@nestjs/config';
export default registerAs('minio', () => ({
endPoint: process.env.MINIO_ENDPOINT || 'localhost',
port: parseInt(process.env.MINIO_PORT, 10) || 9000,
useSSL: process.env.MINIO_USE_SSL === 'true',
accessKey: process.env.MINIO_ACCESS_KEY,
secretKey: process.env.MINIO_SECRET_KEY,
buckets: {
avatars: process.env.MINIO_BUCKET_AVATARS || 'avatars',
documents: process.env.MINIO_BUCKET_DOCUMENTS || 'documents',
},
}));
```
```typescript
// minio.service.ts
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import * as Minio from 'minio';
@Injectable()
export class MinioService {
private client: Minio.Client;
constructor(private configService: ConfigService) {
this.client = new Minio.Client({
endPoint: this.configService.get('minio.endPoint'),
port: this.configService.get('minio.port'),
useSSL: this.configService.get('minio.useSSL'),
accessKey: this.configService.get('minio.accessKey'),
secretKey: this.configService.get('minio.secretKey'),
});
}
async uploadAvatar(userId: string, file: Buffer, contentType: string): Promise<string> {
const bucket = this.configService.get('minio.buckets.avatars');
const objectName = `${userId}/${Date.now()}.${this.getExtension(contentType)}`;
await this.client.putObject(bucket, objectName, file, {
'Content-Type': contentType,
});
return `${bucket}/${objectName}`;
}
getPublicUrl(objectPath: string): string {
const publicUrl = this.configService.get('minio.publicUrl');
return `${publicUrl}/${objectPath}`;
}
}
```
### 环境变量配置
在后端服务的 `.env` 中添加:
```env
# MinIO Configuration
MINIO_ENDPOINT=192.168.1.100
MINIO_PORT=9000
MINIO_USE_SSL=false
MINIO_ACCESS_KEY=admin
MINIO_SECRET_KEY=your_minio_password
MINIO_BUCKET_AVATARS=avatars
MINIO_BUCKET_DOCUMENTS=documents
MINIO_PUBLIC_URL=https://cdn.szaiai.com
```
## 安全建议
1. **修改默认密码**: 生产环境必须修改 `MINIO_ROOT_PASSWORD`
2. **网络隔离**: MinIO 端口应仅对内网开放
3. **访问控制**: 使用 IAM 策略控制存储桶访问
4. **SSL 加密**: 生产环境启用 HTTPS
5. **定期备份**: 配置数据备份策略
## 监控
MinIO 提供 Prometheus 格式的指标:
```
http://localhost:9000/minio/v2/metrics/cluster
```
可在 Grafana 中添加 MinIO Dashboard (ID: 13502)。
## 故障排除
### MinIO 无法启动
```bash
# 检查日志
./deploy.sh logs
# 检查数据目录权限
ls -la /data/minio
```
### 无法连接
```bash
# 检查端口
netstat -tlnp | grep 9000
# 检查防火墙
sudo ufw status
```
### 上传失败
```bash
# 检查存储桶是否存在
./deploy.sh list-buckets
# 检查磁盘空间
df -h /data/minio
```

View File

@ -0,0 +1,367 @@
#!/bin/bash
# =============================================================================
# MinIO Object Storage - 部署脚本
# =============================================================================
#
# 用法:
# ./deploy.sh up 启动 MinIO
# ./deploy.sh down 停止 MinIO
# ./deploy.sh restart 重启 MinIO
# ./deploy.sh logs 查看日志
# ./deploy.sh status 查看状态
# ./deploy.sh health 健康检查
# ./deploy.sh create-bucket <name> 创建存储桶
# ./deploy.sh list-buckets 列出所有存储桶
# ./deploy.sh info 查看服务器信息
# ./deploy.sh backup 备份配置
#
# 示例:
# ./deploy.sh up # 启动 MinIO
# ./deploy.sh create-bucket uploads # 创建 uploads 存储桶
# ./deploy.sh logs -f # 实时查看日志
#
# =============================================================================
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
# 颜色定义
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
# 配置
COMPOSE_FILE="docker-compose.yml"
ENV_FILE=".env"
ENV_EXAMPLE=".env.example"
# =============================================================================
# 工具函数
# =============================================================================
log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
log_step() {
echo -e "${CYAN}[STEP]${NC} $1"
}
# 检查 .env 文件
check_env() {
if [ ! -f "$ENV_FILE" ]; then
if [ -f "$ENV_EXAMPLE" ]; then
log_info "创建 .env 文件..."
cp "$ENV_EXAMPLE" "$ENV_FILE"
log_warning "请检查 .env 文件并配置必要的环境变量"
log_warning "特别注意: MINIO_ROOT_PASSWORD 必须修改为安全密码"
else
log_error ".env.example 文件不存在"
exit 1
fi
fi
# 加载环境变量
if [ -f "$ENV_FILE" ]; then
export $(grep -v '^#' "$ENV_FILE" | xargs)
fi
}
# 检查数据目录
check_data_dir() {
local data_path="${MINIO_DATA_PATH:-/data/minio}"
if [ ! -d "$data_path" ]; then
log_info "创建数据目录: $data_path"
sudo mkdir -p "$data_path"
sudo chown -R 1000:1000 "$data_path"
log_success "数据目录已创建"
fi
}
# 获取 MinIO 连接信息
get_minio_endpoint() {
echo "http://localhost:${MINIO_API_PORT:-9000}"
}
# 配置 mc 客户端
setup_mc() {
local endpoint=$(get_minio_endpoint)
local user="${MINIO_ROOT_USER:-admin}"
local password="${MINIO_ROOT_PASSWORD:-minio_secret_password}"
if command -v mc &> /dev/null; then
mc alias set rwa "$endpoint" "$user" "$password" --api S3v4 > /dev/null 2>&1
return 0
else
# 使用 docker 中的 mc
docker exec rwa-minio mc alias set local http://localhost:9000 "$user" "$password" --api S3v4 > /dev/null 2>&1
return 0
fi
}
# =============================================================================
# 命令实现
# =============================================================================
cmd_up() {
check_env
check_data_dir
log_info "启动 MinIO 对象存储..."
docker compose -f "$COMPOSE_FILE" up -d
log_info "等待服务启动..."
sleep 5
log_success "MinIO 已启动!"
echo ""
cmd_status
}
cmd_down() {
log_info "停止 MinIO..."
docker compose -f "$COMPOSE_FILE" down
log_success "MinIO 已停止"
}
cmd_restart() {
log_info "重启 MinIO..."
docker compose -f "$COMPOSE_FILE" restart minio
log_success "MinIO 已重启"
}
cmd_logs() {
docker compose -f "$COMPOSE_FILE" logs "$@" minio
}
cmd_status() {
echo ""
echo "=========================================="
echo " MinIO Object Storage 状态"
echo "=========================================="
echo ""
docker compose -f "$COMPOSE_FILE" ps --format "table {{.Name}}\t{{.Status}}\t{{.Ports}}"
echo ""
echo "=========================================="
echo " 访问地址"
echo "=========================================="
echo ""
echo " S3 API: http://localhost:${MINIO_API_PORT:-9000}"
echo " Console: http://localhost:${MINIO_CONSOLE_PORT:-9001}"
echo ""
echo " 默认凭证:"
echo " 用户名: ${MINIO_ROOT_USER:-admin}"
echo " 密码: (见 .env 文件)"
echo ""
}
cmd_health() {
echo ""
echo "=========================================="
echo " MinIO 健康检查"
echo "=========================================="
echo ""
local endpoint=$(get_minio_endpoint)
# 检查 API 端点
if curl -s "${endpoint}/minio/health/live" > /dev/null 2>&1; then
echo -e " API Health: ${GREEN}✓ Live${NC}"
else
echo -e " API Health: ${RED}✗ Not responding${NC}"
fi
# 检查就绪状态
if curl -s "${endpoint}/minio/health/ready" > /dev/null 2>&1; then
echo -e " Ready Status: ${GREEN}✓ Ready${NC}"
else
echo -e " Ready Status: ${RED}✗ Not ready${NC}"
fi
# 检查集群状态
if curl -s "${endpoint}/minio/health/cluster" > /dev/null 2>&1; then
echo -e " Cluster: ${GREEN}✓ Healthy${NC}"
else
echo -e " Cluster: ${YELLOW}○ Standalone mode${NC}"
fi
echo ""
}
cmd_create_bucket() {
local bucket_name="$1"
if [ -z "$bucket_name" ]; then
log_error "请提供存储桶名称"
echo "用法: $0 create-bucket <bucket-name>"
exit 1
fi
check_env
setup_mc
log_info "创建存储桶: $bucket_name"
if command -v mc &> /dev/null; then
mc mb --ignore-existing "rwa/$bucket_name"
else
docker exec rwa-minio mc mb --ignore-existing "local/$bucket_name"
fi
log_success "存储桶 '$bucket_name' 已创建"
}
cmd_list_buckets() {
check_env
setup_mc
echo ""
echo "=========================================="
echo " MinIO 存储桶列表"
echo "=========================================="
echo ""
if command -v mc &> /dev/null; then
mc ls rwa
else
docker exec rwa-minio mc ls local
fi
echo ""
}
cmd_info() {
check_env
setup_mc
echo ""
echo "=========================================="
echo " MinIO 服务器信息"
echo "=========================================="
echo ""
if command -v mc &> /dev/null; then
mc admin info rwa
else
docker exec rwa-minio mc admin info local
fi
echo ""
}
cmd_backup() {
check_env
local backup_dir="${SCRIPT_DIR}/backups"
local timestamp=$(date +"%Y%m%d_%H%M%S")
local backup_file="${backup_dir}/minio_config_${timestamp}.tar.gz"
mkdir -p "$backup_dir"
log_info "备份 MinIO 配置..."
# 备份 .env 和 docker-compose 配置
tar -czf "$backup_file" \
-C "$SCRIPT_DIR" \
.env docker-compose.yml 2>/dev/null || true
log_success "配置已备份到: $backup_file"
}
cmd_help() {
echo ""
echo "MinIO Object Storage 部署工具"
echo ""
echo "用法: $0 <命令> [参数...]"
echo ""
echo "命令:"
echo " up 启动 MinIO"
echo " down 停止 MinIO"
echo " restart 重启 MinIO"
echo " logs [options] 查看日志 (支持 -f 参数)"
echo " status 查看运行状态"
echo " health 健康检查"
echo " create-bucket 创建存储桶"
echo " list-buckets 列出所有存储桶"
echo " info 查看服务器信息"
echo " backup 备份配置"
echo " help 显示帮助"
echo ""
echo "示例:"
echo " $0 up # 启动 MinIO"
echo " $0 logs -f # 实时查看日志"
echo " $0 create-bucket uploads # 创建 uploads 存储桶"
echo " $0 list-buckets # 列出所有存储桶"
echo ""
echo "环境变量 (可在 .env 中配置):"
echo " MINIO_ROOT_USER 管理员用户名 (默认: admin)"
echo " MINIO_ROOT_PASSWORD 管理员密码"
echo " MINIO_API_PORT S3 API 端口 (默认: 9000)"
echo " MINIO_CONSOLE_PORT Web 控制台端口 (默认: 9001)"
echo " MINIO_DATA_PATH 数据存储路径 (默认: /data/minio)"
echo ""
}
# =============================================================================
# 主入口
# =============================================================================
case "${1:-help}" in
up)
cmd_up
;;
down)
cmd_down
;;
restart)
cmd_restart
;;
logs)
shift
cmd_logs "$@"
;;
status)
cmd_status
;;
health)
cmd_health
;;
create-bucket)
shift
cmd_create_bucket "$@"
;;
list-buckets)
cmd_list_buckets
;;
info)
cmd_info
;;
backup)
cmd_backup
;;
help|--help|-h)
cmd_help
;;
*)
log_error "未知命令: $1"
cmd_help
exit 1
;;
esac

View File

@ -0,0 +1,124 @@
# =============================================================================
# MinIO Object Storage - Docker Compose
# =============================================================================
#
# MinIO 是一个高性能的分布式对象存储系统,兼容 Amazon S3 API
#
# 用途:
# - 用户头像存储
# - 用户文档存储
# - 应用资源文件存储
# - 备份文件存储
#
# 使用方法:
# ./deploy.sh up # 启动 MinIO
# ./deploy.sh down # 停止 MinIO
# ./deploy.sh status # 查看状态
# ./deploy.sh logs # 查看日志
# ./deploy.sh create-bucket <name> # 创建存储桶
#
# 访问地址:
# API: http://localhost:9000
# Console: http://localhost:9001
#
# =============================================================================
services:
# ===========================================================================
# MinIO Object Storage
# ===========================================================================
minio:
image: docker.io/minio/minio:RELEASE.2024-11-07T00-52-20Z
container_name: rwa-minio
command: server /data --console-address ":9001"
environment:
# 管理员凭证
MINIO_ROOT_USER: ${MINIO_ROOT_USER:-admin}
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-minio_secret_password}
# 服务器配置
MINIO_BROWSER: "on"
MINIO_BROWSER_REDIRECT_URL: ${MINIO_CONSOLE_URL:-http://localhost:9001}
# 区域设置
MINIO_REGION: ${MINIO_REGION:-cn-east-1}
# 性能优化
MINIO_API_REQUESTS_DEADLINE: 10s
MINIO_API_REQUESTS_MAX: 10000
ports:
- "${MINIO_API_PORT:-9000}:9000" # S3 API
- "${MINIO_CONSOLE_PORT:-9001}:9001" # Web Console
volumes:
- minio_data:/data
healthcheck:
test: ["CMD", "mc", "ready", "local"]
interval: 30s
timeout: 10s
retries: 5
start_period: 30s
restart: unless-stopped
networks:
- rwa-minio
# ===========================================================================
# MinIO Client (mc) - 初始化配置
# ===========================================================================
# 用于创建默认存储桶和配置访问策略
# ===========================================================================
minio-init:
image: docker.io/minio/mc:RELEASE.2024-11-05T11-29-45Z
container_name: rwa-minio-init
depends_on:
minio:
condition: service_healthy
environment:
MINIO_ROOT_USER: ${MINIO_ROOT_USER:-admin}
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-minio_secret_password}
# 存储桶配置
BUCKET_AVATARS: ${BUCKET_AVATARS:-avatars}
BUCKET_DOCUMENTS: ${BUCKET_DOCUMENTS:-documents}
BUCKET_RESOURCES: ${BUCKET_RESOURCES:-resources}
BUCKET_BACKUPS: ${BUCKET_BACKUPS:-backups}
entrypoint: >
/bin/sh -c "
echo 'Waiting for MinIO to be ready...';
sleep 5;
echo 'Configuring MinIO client...';
mc alias set rwa http://minio:9000 $${MINIO_ROOT_USER} $${MINIO_ROOT_PASSWORD};
echo 'Creating buckets...';
mc mb --ignore-existing rwa/$${BUCKET_AVATARS};
mc mb --ignore-existing rwa/$${BUCKET_DOCUMENTS};
mc mb --ignore-existing rwa/$${BUCKET_RESOURCES};
mc mb --ignore-existing rwa/$${BUCKET_BACKUPS};
echo 'Setting bucket policies...';
mc anonymous set download rwa/$${BUCKET_AVATARS};
mc anonymous set download rwa/$${BUCKET_RESOURCES};
echo 'Setting lifecycle rules for avatars (keep versions for 30 days)...';
mc ilm rule add --noncurrent-expire-days 30 rwa/$${BUCKET_AVATARS} || true;
echo 'MinIO initialization complete!';
mc admin info rwa;
"
networks:
- rwa-minio
# =============================================================================
# Volumes - 持久化存储
# =============================================================================
volumes:
minio_data:
driver: local
driver_opts:
type: none
o: bind
device: ${MINIO_DATA_PATH:-/data/minio}
# =============================================================================
# Networks
# =============================================================================
networks:
rwa-minio:
driver: bridge
name: rwa-minio

View File

@ -0,0 +1,190 @@
#!/bin/bash
# =============================================================================
# MinIO Nginx 配置安装脚本
# =============================================================================
#
# 功能:
# - 安装 MinIO Nginx 反向代理配置
# - 配置 SSL 证书 (可选)
# - 创建缓存目录
#
# 用法:
# ./install.sh # 安装配置
# ./install.sh --ssl # 安装配置并配置 SSL
# ./install.sh --uninstall # 卸载配置
#
# =============================================================================
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
NGINX_AVAILABLE="/etc/nginx/sites-available"
NGINX_ENABLED="/etc/nginx/sites-enabled"
CONFIG_FILE="minio.szaiai.com.conf"
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 检查 root 权限
check_root() {
if [ "$EUID" -ne 0 ]; then
log_error "请使用 root 权限运行此脚本"
echo "用法: sudo $0"
exit 1
fi
}
# 安装配置
install_config() {
check_root
log_info "安装 MinIO Nginx 配置..."
# 检查 Nginx 是否安装
if ! command -v nginx &> /dev/null; then
log_error "Nginx 未安装,请先安装 Nginx"
exit 1
fi
# 创建缓存目录
log_info "创建缓存目录..."
mkdir -p /var/cache/nginx/minio
chown -R www-data:www-data /var/cache/nginx/minio
# 复制配置文件
log_info "复制配置文件..."
cp "$SCRIPT_DIR/$CONFIG_FILE" "$NGINX_AVAILABLE/"
# 创建符号链接
if [ -L "$NGINX_ENABLED/$CONFIG_FILE" ]; then
log_warning "配置已存在,正在更新..."
rm "$NGINX_ENABLED/$CONFIG_FILE"
fi
ln -s "$NGINX_AVAILABLE/$CONFIG_FILE" "$NGINX_ENABLED/"
# 测试配置
log_info "测试 Nginx 配置..."
if nginx -t; then
log_success "配置测试通过"
else
log_error "配置测试失败,请检查配置文件"
exit 1
fi
# 重新加载 Nginx
log_info "重新加载 Nginx..."
systemctl reload nginx
log_success "MinIO Nginx 配置安装完成!"
echo ""
echo "下一步:"
echo " 1. 确保 DNS 已配置指向此服务器"
echo " 2. 运行 ./install.sh --ssl 配置 SSL 证书"
echo ""
}
# 配置 SSL
setup_ssl() {
check_root
log_info "配置 SSL 证书..."
# 检查 certbot
if ! command -v certbot &> /dev/null; then
log_info "安装 certbot..."
apt-get update
apt-get install -y certbot python3-certbot-nginx
fi
log_info "获取 SSL 证书..."
certbot --nginx \
-d minio.szaiai.com \
-d console.minio.szaiai.com \
-d cdn.szaiai.com \
--non-interactive \
--agree-tos \
--email admin@szaiai.com \
--redirect
log_success "SSL 证书配置完成!"
}
# 卸载配置
uninstall_config() {
check_root
log_info "卸载 MinIO Nginx 配置..."
# 删除符号链接
if [ -L "$NGINX_ENABLED/$CONFIG_FILE" ]; then
rm "$NGINX_ENABLED/$CONFIG_FILE"
log_info "已删除启用的配置"
fi
# 删除配置文件
if [ -f "$NGINX_AVAILABLE/$CONFIG_FILE" ]; then
rm "$NGINX_AVAILABLE/$CONFIG_FILE"
log_info "已删除配置文件"
fi
# 重新加载 Nginx
systemctl reload nginx
log_success "MinIO Nginx 配置已卸载"
}
# 显示帮助
show_help() {
echo ""
echo "MinIO Nginx 配置安装脚本"
echo ""
echo "用法: $0 [选项]"
echo ""
echo "选项:"
echo " (无参数) 安装 Nginx 配置"
echo " --ssl 配置 SSL 证书 (需要先安装配置)"
echo " --uninstall 卸载配置"
echo " --help 显示帮助"
echo ""
}
# 主入口
case "${1:-}" in
--ssl)
setup_ssl
;;
--uninstall)
uninstall_config
;;
--help|-h)
show_help
;;
"")
install_config
;;
*)
log_error "未知选项: $1"
show_help
exit 1
;;
esac

View File

@ -0,0 +1,229 @@
# =============================================================================
# MinIO Nginx 配置
# =============================================================================
#
# 功能:
# - MinIO API 反向代理 (S3 兼容)
# - MinIO Console 反向代理
# - SSL/TLS 终止
# - 静态资源 CDN 缓存
#
# 安装:
# sudo cp minio.szaiai.com.conf /etc/nginx/sites-available/
# sudo ln -s /etc/nginx/sites-available/minio.szaiai.com.conf /etc/nginx/sites-enabled/
# sudo nginx -t && sudo systemctl reload nginx
#
# SSL 证书 (使用 certbot):
# sudo certbot --nginx -d minio.szaiai.com -d cdn.szaiai.com
#
# =============================================================================
# 上游服务器定义
upstream minio_api {
server 127.0.0.1:9000;
keepalive 32;
}
upstream minio_console {
server 127.0.0.1:9001;
keepalive 32;
}
# =============================================================================
# MinIO API (S3 兼容) - minio.szaiai.com
# =============================================================================
server {
listen 80;
listen [::]:80;
server_name minio.szaiai.com;
# 强制 HTTPS
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name minio.szaiai.com;
# SSL 配置 (由 certbot 管理)
ssl_certificate /etc/letsencrypt/live/minio.szaiai.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/minio.szaiai.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# 日志
access_log /var/log/nginx/minio.szaiai.com.access.log;
error_log /var/log/nginx/minio.szaiai.com.error.log;
# 客户端配置
client_max_body_size 100M;
client_body_buffer_size 128k;
client_body_timeout 300s;
# 代理缓冲配置
proxy_buffering off;
proxy_request_buffering off;
# MinIO API 代理
location / {
proxy_pass http://minio_api;
proxy_http_version 1.1;
# 保持连接
proxy_set_header Connection "";
# 必要的头部
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# S3 特定头部
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
# 超时配置
proxy_connect_timeout 60s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
# WebSocket 支持 (用于控制台实时日志)
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
# =============================================================================
# MinIO Console - console.minio.szaiai.com
# =============================================================================
server {
listen 80;
listen [::]:80;
server_name console.minio.szaiai.com;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name console.minio.szaiai.com;
# SSL 配置
ssl_certificate /etc/letsencrypt/live/minio.szaiai.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/minio.szaiai.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# 日志
access_log /var/log/nginx/console.minio.access.log;
error_log /var/log/nginx/console.minio.error.log;
# MinIO Console 代理
location / {
proxy_pass http://minio_console;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket 支持 (Console 实时功能)
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# 超时配置
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}
# =============================================================================
# CDN 静态资源 - cdn.szaiai.com
# =============================================================================
# 用于公开访问的静态资源 (头像、资源文件等)
# =============================================================================
server {
listen 80;
listen [::]:80;
server_name cdn.szaiai.com;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name cdn.szaiai.com;
# SSL 配置
ssl_certificate /etc/letsencrypt/live/cdn.szaiai.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cdn.szaiai.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# 日志
access_log /var/log/nginx/cdn.szaiai.com.access.log;
error_log /var/log/nginx/cdn.szaiai.com.error.log;
# 缓存配置
proxy_cache_path /var/cache/nginx/minio levels=1:2 keys_zone=minio_cache:100m max_size=10g inactive=7d use_temp_path=off;
# 公开存储桶 - avatars
location /avatars/ {
proxy_pass http://minio_api/avatars/;
proxy_http_version 1.1;
proxy_set_header Connection "";
# 缓存配置
proxy_cache minio_cache;
proxy_cache_valid 200 7d;
proxy_cache_valid 404 1m;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_lock on;
# 缓存头部
add_header X-Cache-Status $upstream_cache_status;
add_header Cache-Control "public, max-age=604800";
# CORS 配置
add_header Access-Control-Allow-Origin "*";
add_header Access-Control-Allow-Methods "GET, HEAD, OPTIONS";
}
# 公开存储桶 - resources
location /resources/ {
proxy_pass http://minio_api/resources/;
proxy_http_version 1.1;
proxy_set_header Connection "";
# 缓存配置
proxy_cache minio_cache;
proxy_cache_valid 200 7d;
proxy_cache_valid 404 1m;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_lock on;
# 缓存头部
add_header X-Cache-Status $upstream_cache_status;
add_header Cache-Control "public, max-age=604800";
# CORS 配置
add_header Access-Control-Allow-Origin "*";
add_header Access-Control-Allow-Methods "GET, HEAD, OPTIONS";
}
# 默认拒绝其他路径
location / {
return 403;
}
}