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! 🚀
|
|||
|
|
|