Compare commits
No commits in common. "fb12c0626be07f053693bdb2354e7daf33b2b7b8" and "27e8f5944c5a8471c545b9f71d7df5ee7344372c" have entirely different histories.
fb12c0626b
...
27e8f5944c
|
|
@ -0,0 +1,236 @@
|
||||||
|
# 🔍 Отладка админского чата
|
||||||
|
|
||||||
|
## Проблема
|
||||||
|
|
||||||
|
Админский чат не подключается в системе модерации.
|
||||||
|
|
||||||
|
## Что проверить
|
||||||
|
|
||||||
|
### 1. Откройте DevTools в системе модерации
|
||||||
|
|
||||||
|
Нажмите F12 и откройте вкладку **Console**
|
||||||
|
|
||||||
|
### 2. Перейдите на вкладку "Чат"
|
||||||
|
|
||||||
|
Должны увидеть логи:
|
||||||
|
|
||||||
|
```
|
||||||
|
[Chat] Инициализация чата
|
||||||
|
[Chat] User данные: { username: "glpshchn00", telegramId: "...", hasUsername: true, hasTelegramId: true }
|
||||||
|
[Chat] Подключение к: http://localhost:3000/mod-chat
|
||||||
|
[Chat] ✅ WebSocket подключен, ID: abc123
|
||||||
|
[Chat] Отправка auth с данными: { username: "glpshchn00", telegramId: "..." }
|
||||||
|
```
|
||||||
|
|
||||||
|
**Затем должно быть:**
|
||||||
|
|
||||||
|
✅ **Успех:**
|
||||||
|
```
|
||||||
|
[Chat] ✅ Авторизация успешна!
|
||||||
|
```
|
||||||
|
|
||||||
|
❌ **Ошибка - нет прав:**
|
||||||
|
```
|
||||||
|
[Chat] ❌ Нет прав для доступа к чату
|
||||||
|
[Chat] user.username: glpshchn00
|
||||||
|
[Chat] user.telegramId: 123456789
|
||||||
|
[Chat] Вы должны быть в списке MODERATION_OWNER_USERNAMES
|
||||||
|
```
|
||||||
|
|
||||||
|
❌ **Ошибка подключения:**
|
||||||
|
```
|
||||||
|
[Chat] ❌ Ошибка подключения: timeout
|
||||||
|
```
|
||||||
|
|
||||||
|
## Решения
|
||||||
|
|
||||||
|
### Проблема: "Нет прав доступа"
|
||||||
|
|
||||||
|
**Причина:** Ваш username не в списке админов на сервере.
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
|
||||||
|
1. Откройте `.env` на сервере:
|
||||||
|
```bash
|
||||||
|
nano .env
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Проверьте/добавьте:
|
||||||
|
```env
|
||||||
|
MODERATION_OWNER_USERNAMES=glpshchn00
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Перезапустите backend:
|
||||||
|
```bash
|
||||||
|
docker-compose restart backend
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Проверьте логи:
|
||||||
|
```bash
|
||||||
|
docker-compose logs backend | grep "Mod chat"
|
||||||
|
```
|
||||||
|
|
||||||
|
Должно быть:
|
||||||
|
```
|
||||||
|
[INFO] Mod chat auth success { username: 'glpshchn00', isOwner: true }
|
||||||
|
```
|
||||||
|
|
||||||
|
### Проблема: "Ошибка подключения: timeout"
|
||||||
|
|
||||||
|
**Причина:** Backend недоступен или неправильный URL.
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
|
||||||
|
1. Проверьте что backend запущен:
|
||||||
|
```bash
|
||||||
|
docker-compose ps backend
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Проверьте `VITE_API_URL` в moderation frontend:
|
||||||
|
```bash
|
||||||
|
# В docker-compose.yml
|
||||||
|
environment:
|
||||||
|
- VITE_API_URL=http://localhost:3000 # Для локальной разработки
|
||||||
|
- VITE_API_URL=https://ваш-домен.com # Для production
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Проверьте CORS в backend `.env`:
|
||||||
|
```env
|
||||||
|
CORS_ORIGIN=http://localhost:5174,https://ваш-домен.com
|
||||||
|
```
|
||||||
|
|
||||||
|
### Проблема: user.username или user.telegramId пустые
|
||||||
|
|
||||||
|
**Причина:** Пользователь не авторизован.
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
|
||||||
|
1. Убедитесь что открыли через Telegram бота
|
||||||
|
2. Проверьте логи auth:
|
||||||
|
```
|
||||||
|
[Chat] user.username: undefined ← ПРОБЛЕМА!
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Попробуйте переоткрыть систему модерации из бота
|
||||||
|
|
||||||
|
### Проблема: WebSocket вообще не подключается
|
||||||
|
|
||||||
|
**Причина:** CORS блокирует WebSocket.
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
|
||||||
|
1. Проверьте browser console на ошибки CORS:
|
||||||
|
```
|
||||||
|
Access to XMLHttpRequest at 'http://...' from origin '...' has been blocked by CORS
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Добавьте origin в `.env`:
|
||||||
|
```env
|
||||||
|
CORS_ORIGIN=http://localhost:5173,http://localhost:5174,https://web.telegram.org
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Перезапустите:
|
||||||
|
```bash
|
||||||
|
docker-compose restart backend
|
||||||
|
```
|
||||||
|
|
||||||
|
## Backend логи
|
||||||
|
|
||||||
|
### Успешное подключение:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker-compose logs backend | tail -20
|
||||||
|
```
|
||||||
|
|
||||||
|
Должно быть:
|
||||||
|
```
|
||||||
|
✅ WebSocket подключен: abc123
|
||||||
|
[INFO] Mod chat auth success { username: 'glpshchn00', isOwner: true, isAdmin: false }
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ошибка авторизации:
|
||||||
|
|
||||||
|
```
|
||||||
|
[WARN] Mod chat auth failed: no username/telegramId
|
||||||
|
# или
|
||||||
|
[WARN] Mod chat access denied { username: '...', telegramId: '...' }
|
||||||
|
```
|
||||||
|
|
||||||
|
## Быстрая проверка
|
||||||
|
|
||||||
|
### 1. Backend работает?
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://localhost:3000/health
|
||||||
|
# Должен вернуть 200 OK
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. WebSocket работает?
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://localhost:3000/socket.io/
|
||||||
|
# Должен вернуть: {"code":0,"message":"Transport unknown"}
|
||||||
|
# Это нормально - значит WebSocket сервер работает
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Username в списке?
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Проверьте переменную
|
||||||
|
docker-compose exec backend printenv | grep MODERATION_OWNER
|
||||||
|
```
|
||||||
|
|
||||||
|
Должно быть:
|
||||||
|
```
|
||||||
|
MODERATION_OWNER_USERNAMES=glpshchn00
|
||||||
|
```
|
||||||
|
|
||||||
|
## Полная перезагрузка
|
||||||
|
|
||||||
|
Если ничего не помогло:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Остановите всё
|
||||||
|
docker-compose down
|
||||||
|
|
||||||
|
# 2. Проверьте .env
|
||||||
|
cat .env | grep -E "MODERATION|CORS"
|
||||||
|
|
||||||
|
# 3. Запустите заново
|
||||||
|
docker-compose up -d
|
||||||
|
|
||||||
|
# 4. Смотрите логи
|
||||||
|
docker-compose logs -f backend
|
||||||
|
|
||||||
|
# 5. Переоткройте систему модерации из бота
|
||||||
|
```
|
||||||
|
|
||||||
|
## Контрольный список
|
||||||
|
|
||||||
|
- [ ] Backend запущен (`docker-compose ps`)
|
||||||
|
- [ ] MODERATION_OWNER_USERNAMES содержит ваш username
|
||||||
|
- [ ] CORS_ORIGIN включает домен системы модерации
|
||||||
|
- [ ] User авторизован (есть username и telegramId)
|
||||||
|
- [ ] VITE_API_URL указывает на правильный backend
|
||||||
|
- [ ] Нет ошибок CORS в browser console
|
||||||
|
- [ ] WebSocket сервер инициализирован (логи backend)
|
||||||
|
- [ ] Firewall не блокирует WebSocket порты
|
||||||
|
|
||||||
|
## Если всё еще не работает
|
||||||
|
|
||||||
|
Отправьте в @NakamaReportbot:
|
||||||
|
|
||||||
|
1. Скриншот DevTools Console (вкладка Чат)
|
||||||
|
2. Логи backend:
|
||||||
|
```bash
|
||||||
|
docker-compose logs backend > backend-logs.txt
|
||||||
|
```
|
||||||
|
3. Переменные окружения (без секретов):
|
||||||
|
```bash
|
||||||
|
cat .env | grep -v SECRET | grep -v KEY | grep -v PASSWORD > env-safe.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**После исправления чат должен подключиться автоматически при открытии вкладки "Чат"!** ✅
|
||||||
|
|
||||||
|
|
@ -22,10 +22,6 @@ MODERATION_CHANNEL_USERNAME=@reichenbfurry
|
||||||
GELBOORU_API_KEY=your_gelbooru_api_key
|
GELBOORU_API_KEY=your_gelbooru_api_key
|
||||||
GELBOORU_USER_ID=your_gelbooru_user_id
|
GELBOORU_USER_ID=your_gelbooru_user_id
|
||||||
|
|
||||||
# e621 API (обязательно для поиска)
|
|
||||||
E621_USERNAME=your_e621_username
|
|
||||||
E621_API_KEY=your_e621_api_key
|
|
||||||
|
|
||||||
# Frontend URL
|
# Frontend URL
|
||||||
FRONTEND_URL=http://localhost:5173
|
FRONTEND_URL=http://localhost:5173
|
||||||
VITE_API_URL=http://localhost:3000/api
|
VITE_API_URL=http://localhost:3000/api
|
||||||
|
|
|
||||||
|
|
@ -1,323 +0,0 @@
|
||||||
# 🌐 Настройка Nginx для MinIO с доменом
|
|
||||||
|
|
||||||
## Обзор
|
|
||||||
|
|
||||||
Эта инструкция поможет настроить Nginx reverse proxy для MinIO с SSL сертификатами.
|
|
||||||
|
|
||||||
**Результат:**
|
|
||||||
- MinIO API: `https://minio.glpshchn.ru`
|
|
||||||
- MinIO Console: `https://admin.minio.glpshchn.ru`
|
|
||||||
|
|
||||||
## Предварительные требования
|
|
||||||
|
|
||||||
1. ✅ MinIO запущен на порту 9000 (API) и 9001 (Console)
|
|
||||||
2. ✅ DNS записи настроены:
|
|
||||||
```
|
|
||||||
minio.glpshchn.ru A 103.80.87.247
|
|
||||||
admin.minio.glpshchn.ru A 103.80.87.247
|
|
||||||
```
|
|
||||||
3. ✅ Порты 80 и 443 открыты в firewall
|
|
||||||
|
|
||||||
## Быстрая установка (автоматически)
|
|
||||||
|
|
||||||
### Шаг 1: Скопируйте файлы на сервер
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# На вашем компьютере
|
|
||||||
scp nginx-minio.conf setup-minio-nginx.sh root@103.80.87.247:/root/
|
|
||||||
|
|
||||||
# Подключитесь к серверу
|
|
||||||
ssh root@103.80.87.247
|
|
||||||
```
|
|
||||||
|
|
||||||
### Шаг 2: Отредактируйте email в скрипте
|
|
||||||
|
|
||||||
```bash
|
|
||||||
nano setup-minio-nginx.sh
|
|
||||||
|
|
||||||
# Измените строку:
|
|
||||||
EMAIL="your-email@example.com" # <- Ваш email для Let's Encrypt
|
|
||||||
```
|
|
||||||
|
|
||||||
### Шаг 3: Запустите скрипт
|
|
||||||
|
|
||||||
```bash
|
|
||||||
chmod +x setup-minio-nginx.sh
|
|
||||||
sudo ./setup-minio-nginx.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
Скрипт автоматически:
|
|
||||||
- ✅ Установит Nginx и Certbot
|
|
||||||
- ✅ Получит SSL сертификаты от Let's Encrypt
|
|
||||||
- ✅ Настроит Nginx конфигурацию
|
|
||||||
- ✅ Настроит автообновление сертификатов
|
|
||||||
|
|
||||||
## Ручная установка
|
|
||||||
|
|
||||||
### Шаг 1: Установите Nginx
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install -y nginx certbot python3-certbot-nginx
|
|
||||||
```
|
|
||||||
|
|
||||||
### Шаг 2: Получите SSL сертификаты
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Создайте директорию для certbot
|
|
||||||
sudo mkdir -p /var/www/certbot
|
|
||||||
|
|
||||||
# Временный конфиг для получения сертификатов
|
|
||||||
sudo tee /etc/nginx/sites-available/minio-temp > /dev/null << 'EOF'
|
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
server_name minio.glpshchn.ru admin.minio.glpshchn.ru;
|
|
||||||
|
|
||||||
location /.well-known/acme-challenge/ {
|
|
||||||
root /var/www/certbot;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Активируйте конфиг
|
|
||||||
sudo ln -sf /etc/nginx/sites-available/minio-temp /etc/nginx/sites-enabled/
|
|
||||||
sudo rm -f /etc/nginx/sites-enabled/default
|
|
||||||
sudo nginx -t && sudo systemctl reload nginx
|
|
||||||
|
|
||||||
# Получите сертификаты
|
|
||||||
sudo certbot certonly --webroot \
|
|
||||||
-w /var/www/certbot \
|
|
||||||
-d minio.glpshchn.ru \
|
|
||||||
-d admin.minio.glpshchn.ru \
|
|
||||||
--email your-email@example.com \
|
|
||||||
--agree-tos \
|
|
||||||
--non-interactive
|
|
||||||
```
|
|
||||||
|
|
||||||
### Шаг 3: Установите конфигурацию
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Скопируйте конфиг
|
|
||||||
sudo cp nginx-minio.conf /etc/nginx/sites-available/minio.glpshchn.ru
|
|
||||||
|
|
||||||
# Активируйте
|
|
||||||
sudo ln -sf /etc/nginx/sites-available/minio.glpshchn.ru /etc/nginx/sites-enabled/
|
|
||||||
sudo rm -f /etc/nginx/sites-enabled/minio-temp
|
|
||||||
|
|
||||||
# Проверьте и перезагрузите
|
|
||||||
sudo nginx -t
|
|
||||||
sudo systemctl reload nginx
|
|
||||||
```
|
|
||||||
|
|
||||||
### Шаг 4: Настройте автообновление SSL
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo systemctl enable certbot.timer
|
|
||||||
sudo systemctl start certbot.timer
|
|
||||||
```
|
|
||||||
|
|
||||||
## Проверка работы
|
|
||||||
|
|
||||||
### 1. Проверьте SSL
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl https://minio.glpshchn.ru/minio/health/live
|
|
||||||
# Должен вернуть: пустой ответ (это нормально)
|
|
||||||
|
|
||||||
# Проверьте сертификат
|
|
||||||
echo | openssl s_client -connect minio.glpshchn.ru:443 -servername minio.glpshchn.ru 2>/dev/null | openssl x509 -noout -dates
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Проверьте доступ к файлам
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Загрузите тестовый файл через mc
|
|
||||||
mc cp test.txt myminio/nakama-media/test.txt
|
|
||||||
|
|
||||||
# Проверьте доступность через HTTPS
|
|
||||||
curl -I https://minio.glpshchn.ru/nakama-media/test.txt
|
|
||||||
# Должен вернуть: HTTP/2 200
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Откройте Console
|
|
||||||
|
|
||||||
Откройте в браузере:
|
|
||||||
```
|
|
||||||
https://admin.minio.glpshchn.ru
|
|
||||||
```
|
|
||||||
|
|
||||||
Должен открыться веб-интерфейс MinIO.
|
|
||||||
|
|
||||||
## Обновите Nakama
|
|
||||||
|
|
||||||
### Шаг 1: Обновите .env
|
|
||||||
|
|
||||||
```bash
|
|
||||||
nano .env
|
|
||||||
|
|
||||||
# Измените MinIO настройки:
|
|
||||||
MINIO_ENABLED=true
|
|
||||||
MINIO_ENDPOINT=minio.glpshchn.ru # <- Теперь домен!
|
|
||||||
MINIO_PORT=443 # <- HTTPS порт
|
|
||||||
MINIO_USE_SSL=true # <- Включаем SSL
|
|
||||||
MINIO_ACCESS_KEY=ваш_ключ
|
|
||||||
MINIO_SECRET_KEY=ваш_секрет
|
|
||||||
MINIO_BUCKET=nakama-media
|
|
||||||
MINIO_PUBLIC_URL=https://minio.glpshchn.ru # <- Публичный URL
|
|
||||||
MINIO_PUBLIC_BUCKET=true
|
|
||||||
```
|
|
||||||
|
|
||||||
### Шаг 2: Обновите S3 клиент
|
|
||||||
|
|
||||||
В `backend/utils/minio.js` - уже настроено автоматически!
|
|
||||||
Код использует `config.minio.useSSL` для выбора протокола.
|
|
||||||
|
|
||||||
### Шаг 3: Перезапустите backend
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker-compose restart backend
|
|
||||||
|
|
||||||
# Проверьте логи
|
|
||||||
docker-compose logs backend | grep -i minio
|
|
||||||
```
|
|
||||||
|
|
||||||
Должно быть:
|
|
||||||
```
|
|
||||||
✅ MinIO успешно подключен
|
|
||||||
endpoint: minio.glpshchn.ru:443
|
|
||||||
ssl: true
|
|
||||||
```
|
|
||||||
|
|
||||||
## Устранение проблем
|
|
||||||
|
|
||||||
### Ошибка: "SSL certificate problem"
|
|
||||||
|
|
||||||
**Причина:** Сертификат не доверенный или истёк.
|
|
||||||
|
|
||||||
**Решение:**
|
|
||||||
```bash
|
|
||||||
# Обновите сертификаты
|
|
||||||
sudo certbot renew --force-renewal
|
|
||||||
sudo systemctl reload nginx
|
|
||||||
```
|
|
||||||
|
|
||||||
### Ошибка: "Connection refused"
|
|
||||||
|
|
||||||
**Причина:** MinIO не запущен или порты закрыты.
|
|
||||||
|
|
||||||
**Решение:**
|
|
||||||
```bash
|
|
||||||
# Проверьте MinIO
|
|
||||||
curl http://127.0.0.1:9000/minio/health/live
|
|
||||||
|
|
||||||
# Проверьте Nginx
|
|
||||||
sudo nginx -t
|
|
||||||
sudo systemctl status nginx
|
|
||||||
|
|
||||||
# Проверьте firewall
|
|
||||||
sudo ufw status
|
|
||||||
```
|
|
||||||
|
|
||||||
### Ошибка: "502 Bad Gateway"
|
|
||||||
|
|
||||||
**Причина:** Nginx не может подключиться к MinIO.
|
|
||||||
|
|
||||||
**Решение:**
|
|
||||||
```bash
|
|
||||||
# Проверьте что MinIO слушает на 127.0.0.1:9000
|
|
||||||
netstat -tulpn | grep 9000
|
|
||||||
|
|
||||||
# Проверьте логи Nginx
|
|
||||||
sudo tail -f /var/log/nginx/minio-error.log
|
|
||||||
|
|
||||||
# Проверьте логи MinIO
|
|
||||||
journalctl -u minio -f
|
|
||||||
```
|
|
||||||
|
|
||||||
### CORS ошибки в браузере
|
|
||||||
|
|
||||||
**Причина:** CORS заголовки не настроены.
|
|
||||||
|
|
||||||
**Решение:** Конфиг уже содержит все необходимые CORS заголовки.
|
|
||||||
Если проблема остаётся, проверьте что домен frontend добавлен.
|
|
||||||
|
|
||||||
## Мониторинг
|
|
||||||
|
|
||||||
### Проверка статуса
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Nginx
|
|
||||||
sudo systemctl status nginx
|
|
||||||
|
|
||||||
# Certbot timer
|
|
||||||
sudo systemctl status certbot.timer
|
|
||||||
|
|
||||||
# Логи доступа
|
|
||||||
sudo tail -f /var/log/nginx/minio-access.log
|
|
||||||
|
|
||||||
# Логи ошибок
|
|
||||||
sudo tail -f /var/log/nginx/minio-error.log
|
|
||||||
```
|
|
||||||
|
|
||||||
### Статистика использования
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Количество запросов за последний час
|
|
||||||
sudo grep "$(date '+%d/%b/%Y:%H')" /var/log/nginx/minio-access.log | wc -l
|
|
||||||
|
|
||||||
# Топ IP адресов
|
|
||||||
sudo awk '{print $1}' /var/log/nginx/minio-access.log | sort | uniq -c | sort -rn | head -10
|
|
||||||
```
|
|
||||||
|
|
||||||
## Автообновление SSL
|
|
||||||
|
|
||||||
Сертификаты обновляются автоматически через systemd timer.
|
|
||||||
|
|
||||||
Проверка:
|
|
||||||
```bash
|
|
||||||
# Статус таймера
|
|
||||||
sudo systemctl list-timers certbot.timer
|
|
||||||
|
|
||||||
# Тестовое обновление (dry-run)
|
|
||||||
sudo certbot renew --dry-run
|
|
||||||
|
|
||||||
# Ручное обновление (если нужно)
|
|
||||||
sudo certbot renew
|
|
||||||
sudo systemctl reload nginx
|
|
||||||
```
|
|
||||||
|
|
||||||
## Бонус: Оптимизация производительности
|
|
||||||
|
|
||||||
### Кеширование статических файлов
|
|
||||||
|
|
||||||
Добавьте в конфиг Nginx внутри `location /`:
|
|
||||||
|
|
||||||
```nginx
|
|
||||||
# Кеш для изображений
|
|
||||||
location ~* \.(jpg|jpeg|png|gif|webp)$ {
|
|
||||||
proxy_pass http://127.0.0.1:9000;
|
|
||||||
proxy_cache_valid 200 7d;
|
|
||||||
add_header X-Cache-Status $upstream_cache_status;
|
|
||||||
expires 7d;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Сжатие
|
|
||||||
|
|
||||||
```nginx
|
|
||||||
# В http блоке /etc/nginx/nginx.conf
|
|
||||||
gzip on;
|
|
||||||
gzip_vary on;
|
|
||||||
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
|
|
||||||
```
|
|
||||||
|
|
||||||
## Итоговые URLs
|
|
||||||
|
|
||||||
После настройки:
|
|
||||||
|
|
||||||
- **MinIO API:** `https://minio.glpshchn.ru`
|
|
||||||
- **MinIO Console:** `https://admin.minio.glpshchn.ru`
|
|
||||||
- **Пример файла:** `https://minio.glpshchn.ru/nakama-media/posts/example.jpg`
|
|
||||||
|
|
||||||
Теперь все изображения будут загружаться через HTTPS! 🎉
|
|
||||||
|
|
||||||
|
|
@ -36,10 +36,6 @@ module.exports = {
|
||||||
gelbooruApiKey: process.env.GELBOORU_API_KEY || '638e2433d451fc02e848811acdafdce08317073c01ed78e38139115c19fe04afa367f736726514ef1337565d4c05b3cbe2c81125c424301e90d29d1f7f4cceff',
|
gelbooruApiKey: process.env.GELBOORU_API_KEY || '638e2433d451fc02e848811acdafdce08317073c01ed78e38139115c19fe04afa367f736726514ef1337565d4c05b3cbe2c81125c424301e90d29d1f7f4cceff',
|
||||||
gelbooruUserId: process.env.GELBOORU_USER_ID || '1844464',
|
gelbooruUserId: process.env.GELBOORU_USER_ID || '1844464',
|
||||||
|
|
||||||
// e621 API
|
|
||||||
e621Username: process.env.E621_USERNAME || 'glpshchn00',
|
|
||||||
e621ApiKey: process.env.E621_API_KEY || 'cW2SYnKFJgbViqd6gpC3xu9t',
|
|
||||||
|
|
||||||
// Frontend URL
|
// Frontend URL
|
||||||
frontendUrl: process.env.FRONTEND_URL || 'http://localhost:5173',
|
frontendUrl: process.env.FRONTEND_URL || 'http://localhost:5173',
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -268,32 +268,15 @@ router.delete('/posts/:id', authenticateModeration, requireModerationAccess, asy
|
||||||
return res.status(404).json({ error: 'Пост не найден' });
|
return res.status(404).json({ error: 'Пост не найден' });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Удалить изображения из MinIO
|
// Удалить локальные изображения
|
||||||
try {
|
if (post.images && post.images.length) {
|
||||||
const { deleteFiles } = require('../utils/minio');
|
post.images.forEach((imagePath) => {
|
||||||
const filesToDelete = [];
|
if (!imagePath.startsWith('/uploads')) return;
|
||||||
|
const fullPath = path.join(__dirname, '..', imagePath);
|
||||||
if (post.images && post.images.length > 0) {
|
if (fs.existsSync(fullPath)) {
|
||||||
post.images.forEach(imageUrl => {
|
fs.unlink(fullPath, () => {});
|
||||||
// Извлекаем имя файла из URL
|
|
||||||
const match = imageUrl.match(/nakama-media\/(.+)$/);
|
|
||||||
if (match) {
|
|
||||||
filesToDelete.push(match[1]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (post.imageUrl) {
|
|
||||||
const match = post.imageUrl.match(/nakama-media\/(.+)$/);
|
|
||||||
if (match) {
|
|
||||||
filesToDelete.push(match[1]);
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
if (filesToDelete.length > 0) {
|
|
||||||
await deleteFiles(filesToDelete);
|
|
||||||
console.log(`✅ Удалено ${filesToDelete.length} файлов из MinIO (modApp)`);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('❌ Ошибка удаления файлов из MinIO:', error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await Post.deleteOne({ _id: post._id });
|
await Post.deleteOne({ _id: post._id });
|
||||||
|
|
@ -317,16 +300,10 @@ router.delete('/posts/:id/images/:index', authenticateModeration, requireModerat
|
||||||
post.imageUrl = post.images[0] || null;
|
post.imageUrl = post.images[0] || null;
|
||||||
await post.save();
|
await post.save();
|
||||||
|
|
||||||
// Удалить изображение из MinIO
|
if (removed && removed.startsWith('/uploads')) {
|
||||||
if (removed) {
|
const fullPath = path.join(__dirname, '..', removed);
|
||||||
try {
|
if (fs.existsSync(fullPath)) {
|
||||||
const match = removed.match(/nakama-media\/(.+)$/);
|
fs.unlink(fullPath, () => {});
|
||||||
if (match) {
|
|
||||||
await deleteFile(match[1]);
|
|
||||||
console.log(`✅ Удалено изображение из MinIO: ${match[1]}`);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('❌ Ошибка удаления изображения из MinIO:', error);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -313,33 +313,19 @@ router.delete('/:id', authenticate, async (req, res) => {
|
||||||
return res.status(403).json({ error: 'Нет прав на удаление' });
|
return res.status(403).json({ error: 'Нет прав на удаление' });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Удалить изображения из MinIO
|
// Удалить изображения если есть
|
||||||
try {
|
if (post.images && post.images.length > 0) {
|
||||||
const filesToDelete = [];
|
post.images.forEach(imagePath => {
|
||||||
|
const fullPath = path.join(__dirname, '..', imagePath);
|
||||||
if (post.images && post.images.length > 0) {
|
if (fs.existsSync(fullPath)) {
|
||||||
post.images.forEach(imageUrl => {
|
fs.unlinkSync(fullPath);
|
||||||
// Извлекаем имя файла из URL
|
|
||||||
// https://minio.glpshchn.ru/nakama-media/posts/123456.jpg -> posts/123456.jpg
|
|
||||||
const match = imageUrl.match(/nakama-media\/(.+)$/);
|
|
||||||
if (match) {
|
|
||||||
filesToDelete.push(match[1]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (post.imageUrl) {
|
|
||||||
const match = post.imageUrl.match(/nakama-media\/(.+)$/);
|
|
||||||
if (match) {
|
|
||||||
filesToDelete.push(match[1]);
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
} else if (post.imageUrl) {
|
||||||
|
const imagePath = path.join(__dirname, '..', post.imageUrl);
|
||||||
|
if (fs.existsSync(imagePath)) {
|
||||||
|
fs.unlinkSync(imagePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filesToDelete.length > 0) {
|
|
||||||
await deleteFiles(filesToDelete);
|
|
||||||
console.log(`✅ Удалено ${filesToDelete.length} файлов из MinIO`);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('❌ Ошибка удаления файлов из MinIO:', error);
|
|
||||||
// Продолжаем удаление поста даже если файлы не удалились
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await Post.findByIdAndDelete(req.params.id);
|
await Post.findByIdAndDelete(req.params.id);
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,7 @@ const axios = require('axios');
|
||||||
const { authenticate } = require('../middleware/auth');
|
const { authenticate } = require('../middleware/auth');
|
||||||
const config = require('../config');
|
const config = require('../config');
|
||||||
|
|
||||||
// e621 требует описательный User-Agent с контактами
|
const E621_USER_AGENT = 'NakamaSpace/1.0 (by Reichenbach on e621)';
|
||||||
const E621_USER_AGENT = 'NakamaApp/1.0 (by glpshchn00 on e621; Telegram: @glpshchn00)';
|
|
||||||
const CACHE_TTL_MS = 60 * 1000; // 1 минута
|
const CACHE_TTL_MS = 60 * 1000; // 1 минута
|
||||||
|
|
||||||
const searchCache = new Map();
|
const searchCache = new Map();
|
||||||
|
|
@ -80,21 +79,12 @@ router.get('/proxy/:encodedUrl', async (req, res) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Запрашиваем изображение
|
// Запрашиваем изображение
|
||||||
// Для e621 добавляем авторизацию
|
|
||||||
const headers = {
|
|
||||||
'User-Agent': E621_USER_AGENT,
|
|
||||||
'Referer': urlObj.origin
|
|
||||||
};
|
|
||||||
|
|
||||||
// Если это e621, добавляем авторизацию
|
|
||||||
if (urlObj.hostname.includes('e621.net')) {
|
|
||||||
const auth = Buffer.from(`${config.e621Username}:${config.e621ApiKey}`).toString('base64');
|
|
||||||
headers['Authorization'] = `Basic ${auth}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const response = await axios.get(originalUrl, {
|
const response = await axios.get(originalUrl, {
|
||||||
responseType: 'stream',
|
responseType: 'stream',
|
||||||
headers,
|
headers: {
|
||||||
|
'User-Agent': E621_USER_AGENT,
|
||||||
|
'Referer': urlObj.origin
|
||||||
|
},
|
||||||
timeout: 30000 // 30 секунд таймаут
|
timeout: 30000 // 30 секунд таймаут
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -133,9 +123,6 @@ router.get('/furry', authenticate, async (req, res) => {
|
||||||
// e621 API автоматически обрабатывает теги через пробел в параметре tags
|
// e621 API автоматически обрабатывает теги через пробел в параметре tags
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Базовая авторизация для e621 API
|
|
||||||
const auth = Buffer.from(`${config.e621Username}:${config.e621ApiKey}`).toString('base64');
|
|
||||||
|
|
||||||
const response = await axios.get('https://e621.net/posts.json', {
|
const response = await axios.get('https://e621.net/posts.json', {
|
||||||
params: {
|
params: {
|
||||||
tags: query.trim(), // Множественные теги через пробел
|
tags: query.trim(), // Множественные теги через пробел
|
||||||
|
|
@ -143,8 +130,7 @@ router.get('/furry', authenticate, async (req, res) => {
|
||||||
page: parseInt(page) || 1
|
page: parseInt(page) || 1
|
||||||
},
|
},
|
||||||
headers: {
|
headers: {
|
||||||
'User-Agent': E621_USER_AGENT,
|
'User-Agent': E621_USER_AGENT
|
||||||
'Authorization': `Basic ${auth}`
|
|
||||||
},
|
},
|
||||||
timeout: 30000,
|
timeout: 30000,
|
||||||
validateStatus: (status) => status < 500 // Не бросать ошибку для 429
|
validateStatus: (status) => status < 500 // Не бросать ошибку для 429
|
||||||
|
|
@ -289,9 +275,6 @@ router.get('/furry/tags', authenticate, async (req, res) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Базовая авторизация для e621 API
|
|
||||||
const auth = Buffer.from(`${config.e621Username}:${config.e621ApiKey}`).toString('base64');
|
|
||||||
|
|
||||||
const response = await axios.get('https://e621.net/tags.json', {
|
const response = await axios.get('https://e621.net/tags.json', {
|
||||||
params: {
|
params: {
|
||||||
'search[name_matches]': `${query}*`,
|
'search[name_matches]': `${query}*`,
|
||||||
|
|
@ -299,8 +282,7 @@ router.get('/furry/tags', authenticate, async (req, res) => {
|
||||||
limit: 10
|
limit: 10
|
||||||
},
|
},
|
||||||
headers: {
|
headers: {
|
||||||
'User-Agent': E621_USER_AGENT,
|
'User-Agent': E621_USER_AGENT
|
||||||
'Authorization': `Basic ${auth}`
|
|
||||||
},
|
},
|
||||||
timeout: 10000,
|
timeout: 10000,
|
||||||
validateStatus: (status) => status < 500 // Не бросать ошибку для 429
|
validateStatus: (status) => status < 500 // Не бросать ошибку для 429
|
||||||
|
|
|
||||||
156
nginx-minio.conf
156
nginx-minio.conf
|
|
@ -1,156 +0,0 @@
|
||||||
# Nginx конфигурация для MinIO
|
|
||||||
# Сохраните как: /etc/nginx/sites-available/minio.glpshchn.ru
|
|
||||||
|
|
||||||
# Перенаправление HTTP -> HTTPS
|
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
listen [::]:80;
|
|
||||||
server_name minio.glpshchn.ru;
|
|
||||||
|
|
||||||
# Certbot validation
|
|
||||||
location /.well-known/acme-challenge/ {
|
|
||||||
root /var/www/certbot;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Redirect all HTTP to HTTPS
|
|
||||||
location / {
|
|
||||||
return 301 https://$server_name$request_uri;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# MinIO API (основной доступ к файлам)
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
listen [::]:443 ssl http2;
|
|
||||||
server_name minio.glpshchn.ru;
|
|
||||||
|
|
||||||
# SSL сертификаты (Let's Encrypt)
|
|
||||||
ssl_certificate /etc/letsencrypt/live/minio.glpshchn.ru/fullchain.pem;
|
|
||||||
ssl_certificate_key /etc/letsencrypt/live/minio.glpshchn.ru/privkey.pem;
|
|
||||||
ssl_trusted_certificate /etc/letsencrypt/live/minio.glpshchn.ru/chain.pem;
|
|
||||||
|
|
||||||
# SSL настройки (современные и безопасные)
|
|
||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
|
||||||
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
|
|
||||||
ssl_prefer_server_ciphers off;
|
|
||||||
ssl_session_cache shared:SSL:10m;
|
|
||||||
ssl_session_timeout 10m;
|
|
||||||
ssl_stapling on;
|
|
||||||
ssl_stapling_verify on;
|
|
||||||
|
|
||||||
# Security headers
|
|
||||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
|
||||||
add_header X-Content-Type-Options "nosniff" always;
|
|
||||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
|
||||||
|
|
||||||
# Увеличенные лимиты для загрузки файлов
|
|
||||||
client_max_body_size 1000M;
|
|
||||||
client_body_timeout 300s;
|
|
||||||
client_header_timeout 300s;
|
|
||||||
proxy_connect_timeout 300s;
|
|
||||||
proxy_send_timeout 300s;
|
|
||||||
proxy_read_timeout 300s;
|
|
||||||
send_timeout 300s;
|
|
||||||
|
|
||||||
# Игнорировать заголовки для кеширования от upstream
|
|
||||||
ignore_invalid_headers off;
|
|
||||||
|
|
||||||
# CORS заголовки (для доступа из браузера)
|
|
||||||
add_header 'Access-Control-Allow-Origin' '*' always;
|
|
||||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS, HEAD' always;
|
|
||||||
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Content-Length, Accept-Encoding, X-Requested-With, Range, Content-Disposition, Content-MD5, X-Amz-Content-Sha256, X-Amz-Date, X-Amz-User-Agent' always;
|
|
||||||
add_header 'Access-Control-Expose-Headers' 'Content-Length, Content-Range, ETag' always;
|
|
||||||
add_header 'Access-Control-Max-Age' 1728000 always;
|
|
||||||
|
|
||||||
# Обработка preflight запросов
|
|
||||||
if ($request_method = 'OPTIONS') {
|
|
||||||
add_header 'Access-Control-Allow-Origin' '*';
|
|
||||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS, HEAD';
|
|
||||||
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Content-Length, Accept-Encoding, X-Requested-With, Range, Content-Disposition, Content-MD5, X-Amz-Content-Sha256, X-Amz-Date, X-Amz-User-Agent';
|
|
||||||
add_header 'Access-Control-Max-Age' 1728000;
|
|
||||||
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
|
||||||
add_header 'Content-Length' 0;
|
|
||||||
return 204;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Логи
|
|
||||||
access_log /var/log/nginx/minio-access.log;
|
|
||||||
error_log /var/log/nginx/minio-error.log;
|
|
||||||
|
|
||||||
# Проксирование к MinIO API
|
|
||||||
location / {
|
|
||||||
proxy_set_header Host $http_host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
proxy_set_header X-NginX-Proxy true;
|
|
||||||
|
|
||||||
# Для корректной работы S3 API
|
|
||||||
proxy_set_header Connection "";
|
|
||||||
chunked_transfer_encoding off;
|
|
||||||
|
|
||||||
# Disable buffering для больших файлов
|
|
||||||
proxy_buffering off;
|
|
||||||
proxy_request_buffering off;
|
|
||||||
|
|
||||||
# Backend MinIO (порт 9000)
|
|
||||||
proxy_pass http://127.0.0.1:9000;
|
|
||||||
|
|
||||||
# WebSocket поддержка (если используется)
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
}
|
|
||||||
|
|
||||||
# Health check endpoint
|
|
||||||
location /minio/health/live {
|
|
||||||
proxy_set_header Host $http_host;
|
|
||||||
proxy_pass http://127.0.0.1:9000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# MinIO Console (опционально, для веб-интерфейса)
|
|
||||||
# Доступ через admin.minio.glpshchn.ru
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
listen [::]:443 ssl http2;
|
|
||||||
server_name admin.minio.glpshchn.ru;
|
|
||||||
|
|
||||||
# SSL сертификаты
|
|
||||||
ssl_certificate /etc/letsencrypt/live/admin.minio.glpshchn.ru/fullchain.pem;
|
|
||||||
ssl_certificate_key /etc/letsencrypt/live/admin.minio.glpshchn.ru/privkey.pem;
|
|
||||||
ssl_trusted_certificate /etc/letsencrypt/live/admin.minio.glpshchn.ru/chain.pem;
|
|
||||||
|
|
||||||
# SSL настройки
|
|
||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
|
||||||
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
|
|
||||||
ssl_prefer_server_ciphers off;
|
|
||||||
ssl_session_cache shared:SSL:10m;
|
|
||||||
|
|
||||||
# Security headers
|
|
||||||
add_header Strict-Transport-Security "max-age=31536000" always;
|
|
||||||
|
|
||||||
# Увеличенные лимиты
|
|
||||||
client_max_body_size 1000M;
|
|
||||||
|
|
||||||
# Логи
|
|
||||||
access_log /var/log/nginx/minio-console-access.log;
|
|
||||||
error_log /var/log/nginx/minio-console-error.log;
|
|
||||||
|
|
||||||
# Проксирование к MinIO Console
|
|
||||||
location / {
|
|
||||||
proxy_set_header Host $http_host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
|
|
||||||
# Backend MinIO Console (порт 9001)
|
|
||||||
proxy_pass http://127.0.0.1:9001;
|
|
||||||
|
|
||||||
# WebSocket для real-time updates
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,159 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Скрипт для настройки Nginx + SSL для MinIO
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo "🔧 Настройка Nginx для MinIO"
|
|
||||||
echo "======================================"
|
|
||||||
|
|
||||||
# Проверка root прав
|
|
||||||
if [[ $EUID -ne 0 ]]; then
|
|
||||||
echo "❌ Этот скрипт должен быть запущен с правами root (sudo)"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Переменные
|
|
||||||
DOMAIN="minio.glpshchn.ru"
|
|
||||||
CONSOLE_DOMAIN="admin.minio.glpshchn.ru"
|
|
||||||
EMAIL="your-email@example.com" # Измените на ваш email для Let's Encrypt
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "Настройка для доменов:"
|
|
||||||
echo " API: https://$DOMAIN"
|
|
||||||
echo " Console: https://$CONSOLE_DOMAIN"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Установка Nginx (если не установлен)
|
|
||||||
if ! command -v nginx &> /dev/null; then
|
|
||||||
echo "📦 Установка Nginx..."
|
|
||||||
apt update
|
|
||||||
apt install -y nginx
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Установка Certbot (если не установлен)
|
|
||||||
if ! command -v certbot &> /dev/null; then
|
|
||||||
echo "📦 Установка Certbot..."
|
|
||||||
apt install -y certbot python3-certbot-nginx
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Создание директории для certbot
|
|
||||||
mkdir -p /var/www/certbot
|
|
||||||
|
|
||||||
# Временный конфиг для получения сертификатов
|
|
||||||
echo "📝 Создание временного конфига для получения SSL..."
|
|
||||||
|
|
||||||
cat > /etc/nginx/sites-available/minio-temp << 'EOF'
|
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
server_name minio.glpshchn.ru admin.minio.glpshchn.ru;
|
|
||||||
|
|
||||||
location /.well-known/acme-challenge/ {
|
|
||||||
root /var/www/certbot;
|
|
||||||
}
|
|
||||||
|
|
||||||
location / {
|
|
||||||
return 200 "MinIO setup in progress...";
|
|
||||||
add_header Content-Type text/plain;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Активация временного конфига
|
|
||||||
ln -sf /etc/nginx/sites-available/minio-temp /etc/nginx/sites-enabled/minio-temp
|
|
||||||
|
|
||||||
# Удаление дефолтного конфига
|
|
||||||
rm -f /etc/nginx/sites-enabled/default
|
|
||||||
|
|
||||||
# Проверка конфигурации
|
|
||||||
echo "🔍 Проверка конфигурации Nginx..."
|
|
||||||
nginx -t
|
|
||||||
|
|
||||||
# Перезагрузка Nginx
|
|
||||||
echo "🔄 Перезагрузка Nginx..."
|
|
||||||
systemctl reload nginx
|
|
||||||
|
|
||||||
# Получение SSL сертификатов
|
|
||||||
echo ""
|
|
||||||
echo "🔒 Получение SSL сертификатов от Let's Encrypt..."
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
certbot certonly --webroot \
|
|
||||||
-w /var/www/certbot \
|
|
||||||
-d $DOMAIN \
|
|
||||||
-d $CONSOLE_DOMAIN \
|
|
||||||
--email $EMAIL \
|
|
||||||
--agree-tos \
|
|
||||||
--non-interactive
|
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "❌ Ошибка получения SSL сертификата"
|
|
||||||
echo "Проверьте:"
|
|
||||||
echo " 1. DNS записи A для $DOMAIN и $CONSOLE_DOMAIN указывают на этот сервер"
|
|
||||||
echo " 2. Порт 80 открыт в firewall"
|
|
||||||
echo " 3. Домены доступны из интернета"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "✅ SSL сертификаты получены!"
|
|
||||||
|
|
||||||
# Копирование основного конфига
|
|
||||||
echo "📝 Установка основного конфига..."
|
|
||||||
cp nginx-minio.conf /etc/nginx/sites-available/minio.glpshchn.ru
|
|
||||||
|
|
||||||
# Активация конфига
|
|
||||||
ln -sf /etc/nginx/sites-available/minio.glpshchn.ru /etc/nginx/sites-enabled/minio.glpshchn.ru
|
|
||||||
|
|
||||||
# Удаление временного конфига
|
|
||||||
rm -f /etc/nginx/sites-enabled/minio-temp
|
|
||||||
|
|
||||||
# Проверка конфигурации
|
|
||||||
echo "🔍 Проверка финальной конфигурации..."
|
|
||||||
nginx -t
|
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "❌ Ошибка в конфигурации Nginx"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Перезагрузка Nginx
|
|
||||||
echo "🔄 Перезагрузка Nginx с новой конфигурацией..."
|
|
||||||
systemctl reload nginx
|
|
||||||
|
|
||||||
# Настройка автообновления сертификатов
|
|
||||||
echo "⏰ Настройка автообновления SSL сертификатов..."
|
|
||||||
systemctl enable certbot.timer
|
|
||||||
systemctl start certbot.timer
|
|
||||||
|
|
||||||
# Открытие портов в firewall (если используется ufw)
|
|
||||||
if command -v ufw &> /dev/null; then
|
|
||||||
echo "🔥 Настройка firewall..."
|
|
||||||
ufw allow 'Nginx Full'
|
|
||||||
ufw allow 443/tcp
|
|
||||||
ufw allow 80/tcp
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "======================================"
|
|
||||||
echo "✅ Настройка завершена!"
|
|
||||||
echo ""
|
|
||||||
echo "MinIO API доступен по адресу:"
|
|
||||||
echo " https://$DOMAIN"
|
|
||||||
echo ""
|
|
||||||
echo "MinIO Console доступен по адресу:"
|
|
||||||
echo " https://$CONSOLE_DOMAIN"
|
|
||||||
echo ""
|
|
||||||
echo "Проверка:"
|
|
||||||
echo " curl https://$DOMAIN/minio/health/live"
|
|
||||||
echo ""
|
|
||||||
echo "Обновите .env в Nakama:"
|
|
||||||
echo " MINIO_ENDPOINT=$DOMAIN"
|
|
||||||
echo " MINIO_PORT=443"
|
|
||||||
echo " MINIO_USE_SSL=true"
|
|
||||||
echo " MINIO_PUBLIC_URL=https://$DOMAIN"
|
|
||||||
echo ""
|
|
||||||
echo "Перезапустите backend:"
|
|
||||||
echo " docker-compose restart backend"
|
|
||||||
echo "======================================"
|
|
||||||
|
|
||||||
Loading…
Reference in New Issue