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