nakama/S3_MINIO_SETUP.md

439 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 🔌 Подключение к существующему 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! 🚀