nakama/S3_MINIO_SETUP.md

439 lines
12 KiB
Markdown
Raw Normal View History

2025-11-20 22:07:37 +00:00
# 🔌 Подключение к существующему MinIO через S3 SDK
## ✅ Ваша ситуация
У вас уже запущен MinIO на сервере **103.80.87.247**:
- **Console (Web UI):** http://103.80.87.247:9901/
- **API (S3):** http://103.80.87.247:9000/ (обычно)
Мы используем **AWS S3 SDK** для подключения к MinIO (MinIO полностью совместим с S3 API).
---
## 🚀 Быстрая настройка
### Шаг 1: Установите зависимости
```bash
cd /Users/glpshchn/Desktop/nakama
npm install
```
Будут установлены:
- `@aws-sdk/client-s3` - S3 клиент
- `@aws-sdk/lib-storage` - Загрузка больших файлов
- `@aws-sdk/s3-request-presigner` - Presigned URLs
### Шаг 2: Получите Access Key и Secret Key
1. Откройте MinIO Console: http://103.80.87.247:9901/
2. Войдите с учетными данными
3. Перейдите: **Identity → Service Accounts** (или **Users**)
4. Создайте новый Service Account для приложения:
- Name: `nakama-app`
- Policy: `readwrite`
5. **Скопируйте Access Key и Secret Key** (покажутся только один раз!)
### Шаг 3: Обновите .env файл
```bash
nano /Users/glpshchn/Desktop/nakama/.env
```
Добавьте/обновите:
```env
# MinIO Configuration
MINIO_ENABLED=true
MINIO_ENDPOINT=103.80.87.247
MINIO_PORT=9000 # API порт (НЕ 9901!)
MINIO_USE_SSL=false
MINIO_ACCESS_KEY=YOUR_ACCESS_KEY_HERE # Из MinIO Console
MINIO_SECRET_KEY=YOUR_SECRET_KEY_HERE # Из MinIO Console
MINIO_BUCKET=nakama-media
MINIO_REGION=us-east-1
MINIO_PUBLIC_URL=http://103.80.87.247:9000
```
### Шаг 4: Создайте bucket в MinIO
В MinIO Console:
1. **Object Browser****Create Bucket**
2. Имя: `nakama-media`
3. Нажмите **Create Bucket**
Или через API:
```bash
curl -X PUT http://103.80.87.247:9000/nakama-media \
-H "Authorization: AWS4-HMAC-SHA256 ..."
```
### Шаг 5: Запустите приложение
```bash
docker-compose down
docker-compose build
docker-compose up -d
```
Проверьте логи:
```bash
docker-compose logs backend | grep -i minio
# Должны увидеть:
# ✅ S3 клиент для MinIO инициализирован
# Bucket: nakama-media
```
---
## 🔍 Проверка подключения
### Тест 1: Через API endpoint
```bash
# Проверьте статус MinIO (нужен токен модератора)
curl -X GET http://localhost:3000/api/minio/status \
-H "Authorization: Bearer YOUR_MODERATOR_TOKEN"
```
### Тест 2: Создайте пост с изображением
1. Откройте приложение
2. Создайте пост с изображением
3. Проверьте в MinIO Console: **Object Browser → nakama-media → posts/**
### Тест 3: Через AWS CLI
```bash
# Установите AWS CLI
# macOS:
brew install awscli
# Ubuntu:
sudo apt install awscli
# Настройте profile для MinIO
aws configure --profile minio
# AWS Access Key ID: ваш_access_key
# AWS Secret Access Key: ваш_secret_key
# Default region name: us-east-1
# Default output format: json
# Проверьте подключение
aws s3 ls s3://nakama-media \
--endpoint-url http://103.80.87.247:9000 \
--profile minio
# Загрузите тестовый файл
aws s3 cp test.jpg s3://nakama-media/test/ \
--endpoint-url http://103.80.87.247:9000 \
--profile minio
# Список файлов
aws s3 ls s3://nakama-media/posts/ \
--endpoint-url http://103.80.87.247:9000 \
--profile minio
```
---
## ⚙️ Конфигурация для разных сценариев
### Вариант 1: HTTP (без SSL)
```env
MINIO_ENABLED=true
MINIO_ENDPOINT=103.80.87.247
MINIO_PORT=9000
MINIO_USE_SSL=false
MINIO_ACCESS_KEY=your_access_key
MINIO_SECRET_KEY=your_secret_key
MINIO_BUCKET=nakama-media
MINIO_PUBLIC_URL=http://103.80.87.247:9000
```
### Вариант 2: HTTPS (с SSL)
```env
MINIO_ENABLED=true
MINIO_ENDPOINT=103.80.87.247
MINIO_PORT=9000
MINIO_USE_SSL=true
MINIO_ACCESS_KEY=your_access_key
MINIO_SECRET_KEY=your_secret_key
MINIO_BUCKET=nakama-media
MINIO_PUBLIC_URL=https://103.80.87.247:9000
```
### Вариант 3: Через домен + CDN
```env
MINIO_ENABLED=true
MINIO_ENDPOINT=minio.yourdomain.com
MINIO_PORT=443
MINIO_USE_SSL=true
MINIO_ACCESS_KEY=your_access_key
MINIO_SECRET_KEY=your_secret_key
MINIO_BUCKET=nakama-media
MINIO_PUBLIC_URL=https://cdn.yourdomain.com
```
---
## 🔐 Безопасность
### 1. Создайте отдельного пользователя для приложения
В MinIO Console:
**Identity → Users → Create User:**
- Username: `nakama-app`
- Password: `secure_password_123`
**Создайте Policy:**
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::nakama-media/*"
]
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::nakama-media"
]
}
]
}
```
**Назначьте Policy пользователю.**
**Создайте Service Account для пользователя** и используйте его credentials в .env.
### 2. Ограничьте доступ к API порту
На сервере MinIO:
```bash
# Разрешить доступ только с IP приложения
ufw allow from YOUR_APP_SERVER_IP to any port 9000
# Консоль можно ограничить вашим IP
ufw allow from YOUR_IP to any port 9901
```
### 3. Настройте HTTPS
```bash
# На сервере MinIO:
mkdir -p ~/.minio/certs
# Скопируйте SSL сертификаты
cp /path/to/cert.pem ~/.minio/certs/public.crt
cp /path/to/key.pem ~/.minio/certs/private.key
# Перезапустите MinIO
systemctl restart minio
```
---
## 🔧 Отличия S3 SDK от MinIO SDK
### MinIO SDK (старый):
```javascript
const Minio = require('minio');
const client = new Minio.Client({
endPoint: '103.80.87.247',
port: 9000,
useSSL: false,
accessKey: 'key',
secretKey: 'secret'
});
```
### AWS S3 SDK (новый, используем):
```javascript
const { S3Client } = require('@aws-sdk/client-s3');
const client = new S3Client({
endpoint: 'http://103.80.87.247:9000',
region: 'us-east-1',
credentials: {
accessKeyId: 'key',
secretAccessKey: 'secret'
},
forcePathStyle: true // Важно для MinIO!
});
```
**Преимущества S3 SDK:**
- ✅ Официальный AWS SDK (лучше поддержка)
- ✅ Работает с любым S3-совместимым хранилищем
- ✅ Больше функций и опций
- ✅ Лучшая типизация для TypeScript
- ✅ Модульная структура (меньше размер bundle)
---
## 📊 Структура хранения
```
MinIO Server (103.80.87.247:9000)
└── nakama-media/ ← Bucket
├── posts/ ← Посты пользователей
│ ├── 1700000000-123.jpg
│ ├── 1700000001-456.png
│ └── ...
├── avatars/ ← Аватары
│ └── ...
└── channel/ ← Публикации в канал
└── ...
```
---
## 🚨 Решение проблем
### Проблема: "Connection refused" на порту 9000
**Причина:** MinIO API не слушает на порту 9000
**Решение:**
```bash
# На сервере MinIO проверьте:
netstat -tulpn | grep 9000
# Если пусто, проверьте конфигурацию MinIO
systemctl status minio
# Проверьте переменные окружения
cat /etc/default/minio
```
### Проблема: "Access Denied"
**Причина:** Неверные credentials или недостаточно прав
**Решение:**
1. Проверьте Access Key и Secret Key в .env
2. Проверьте policy пользователя в MinIO Console
3. Убедитесь что bucket существует
### Проблема: "Bucket does not exist"
**Решение:**
```bash
# Создайте bucket через AWS CLI:
aws s3 mb s3://nakama-media \
--endpoint-url http://103.80.87.247:9000 \
--profile minio
# Или в MinIO Console:
# Object Browser → Create Bucket → nakama-media
```
### Проблема: "forcePathStyle" не работает
**Причина:** Старая версия MinIO или неправильный endpoint
**Решение:**
```env
# Убедитесь что endpoint БЕЗ протокола в config:
MINIO_ENDPOINT=103.80.87.247 # ✅ Правильно
MINIO_ENDPOINT=http://103.80.87.247 # ❌ Неправильно
```
### Проблема: CORS ошибки при доступе к файлам
**Решение:** Настройте CORS в MinIO Console
```bash
# Через mc (MinIO Client):
mc admin config set myminio api cors_allow_origin="*"
mc admin service restart myminio
```
---
## 📝 Пример использования в коде
### Загрузка файла:
```javascript
const { uploadFile } = require('./utils/minio');
// В route handler:
const fileUrl = await uploadFile(
req.file.buffer, // Buffer из multer
req.file.originalname,
req.file.mimetype,
'posts' // Папка
);
console.log('File URL:', fileUrl);
// http://103.80.87.247:9000/nakama-media/posts/1700000000-123.jpg
```
### Удаление файла:
```javascript
const { deleteFile } = require('./utils/minio');
await deleteFile('http://103.80.87.247:9000/nakama-media/posts/1700000000-123.jpg');
```
### Получение presigned URL:
```javascript
const { getPresignedUrl } = require('./utils/minio');
const url = await getPresignedUrl('posts/1700000000-123.jpg', 3600); // 1 час
```
---
## ✅ Checklist настройки
- [ ] MinIO работает на 103.80.87.247
- [ ] Console доступен на :9901
- [ ] API доступен на :9000
- [ ] Создан bucket `nakama-media`
- [ ] Созданы Access Key и Secret Key
- [ ] Обновлен .env с правильными credentials
- [ ] Установлены npm пакеты (`npm install`)
- [ ] Перезапущен Docker (`docker-compose up -d`)
- [ ] Проверены логи (`docker-compose logs backend`)
- [ ] Создан тестовый пост с изображением
- [ ] Файл появился в MinIO Console
---
## 🎯 Следующие шаги
1.**Проверьте подключение:** создайте пост с изображением
2. 🔒 **Настройте безопасность:** создайте отдельного пользователя
3. 🌐 **Настройте домен:** вместо IP используйте домен
4. 🔐 **Включите HTTPS:** для продакшена
5. 📊 **Настройте мониторинг:** следите за использованием
6. 💾 **Настройте бекапы:** регулярное резервное копирование
---
**Готово!** Теперь все файлы загружаются в ваш MinIO через S3 SDK! 🚀