# 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
```
