2025-09-02 14:00:54 +03:00
|
|
|
# Setup & Configuration
|
|
|
|
|
|
|
|
|
|
## 🚀 Quick Start
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
# 1. Install Rust + Redis
|
|
|
|
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
|
|
|
|
redis-server # or docker run -p 6379:6379 redis:alpine
|
|
|
|
|
|
|
|
|
|
# 2. Clone & build
|
|
|
|
|
git clone https://github.com/your-org/quoter.git
|
|
|
|
|
cd quoter
|
|
|
|
|
cargo build
|
|
|
|
|
|
|
|
|
|
# 3. Configure
|
|
|
|
|
cp .env.example .env
|
|
|
|
|
# Edit .env with your keys
|
|
|
|
|
|
|
|
|
|
# 4. Run
|
|
|
|
|
cargo run
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## ⚙️ Environment Variables
|
|
|
|
|
|
|
|
|
|
### Required
|
|
|
|
|
```bash
|
|
|
|
|
REDIS_URL=redis://localhost:6379
|
|
|
|
|
STORJ_ACCESS_KEY=your-storj-key
|
|
|
|
|
STORJ_SECRET_KEY=your-storj-secret
|
2025-09-30 21:46:47 +03:00
|
|
|
JWT_SECRET_KEY=your-jwt-secret
|
2025-09-02 14:00:54 +03:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Optional
|
|
|
|
|
```bash
|
|
|
|
|
PORT=8080
|
|
|
|
|
RUST_LOG=info
|
2025-09-02 18:08:14 +03:00
|
|
|
STORJ_BUCKET_NAME=discours-io
|
2025-09-02 14:00:54 +03:00
|
|
|
MAX_FILE_SIZE=524288000 # 500MB
|
|
|
|
|
USER_QUOTA_LIMIT=5368709120 # 5GB
|
|
|
|
|
|
|
|
|
|
# CORS whitelist for file downloads (comma-separated, supports *.domain patterns)
|
|
|
|
|
CORS_DOWNLOAD_ORIGINS=https://discours.io,https://*.discours.io,https://testing.discours.io,https://testing3.discours.io
|
|
|
|
|
|
|
|
|
|
# Request source logging for CORS whitelist analysis (optional)
|
|
|
|
|
RUST_LOG=info # Enable to see 📥 Request source and 📊 ANALYTICS logs
|
|
|
|
|
|
|
|
|
|
# Request timeout configuration (optional, defaults to 300 seconds)
|
|
|
|
|
# Controls timeouts for S3, Redis, and other external operations
|
|
|
|
|
REQUEST_TIMEOUT_SECONDS=300
|
|
|
|
|
|
|
|
|
|
# Upload protection (optional, defaults to 10 uploads per minute per IP)
|
|
|
|
|
# Simple protection against upload abuse for user-facing endpoints
|
|
|
|
|
UPLOAD_LIMIT_PER_MINUTE=10
|
[0.6.1] - 2025-09-02
### 🚀 Изменено - Упрощение архитектуры
- **Генерация миниатюр**: Полностью удалена из Quoter, теперь управляется Vercel Edge API
- **Очистка legacy кода**: Удалены все функции генерации миниатюр и сложность
- **Документация**: Сокращена с 17 файлов до 7, следуя принципам KISS/DRY
- **Смена фокуса**: Quoter теперь сосредоточен на upload + storage, Vercel обрабатывает миниатюры
- **Логирование запросов**: Добавлена аналитика источников для оптимизации CORS whitelist
- **Реализация таймаутов**: Добавлены настраиваемые таймауты для S3, Redis и внешних операций
- **Упрощенная безопасность**: Удален сложный rate limiting, оставлена только необходимая защита upload
- **Vercel интеграция**: Добавлена поддержка Vercel Edge API с CORS и оптимизированными заголовками
- **Redis graceful fallback**: Приложение теперь работает без Redis с предупреждениями вместо паники
- **Умная логика ответов**: Автоматическое определение Vercel запросов и оптимизированные заголовки
- **Консолидация документации**: Объединены 4 Vercel документа в один comprehensive guide
### 📝 Обновлено
- Консолидирована документация в практическую структуру:
- Основной README.md с быстрым стартом
- docs/SETUP.md для конфигурации и развертывания
- Упрощенный features.md с фокусом на основную функциональность
- docs/vercel-frontend-migration.md - единый comprehensive guide для Vercel интеграции
- Добавлен акцент на Vercel по всему коду и документации
- Обновлены URL patterns в документации: quoter.discours.io → files.dscrs.site
### 🗑️ Удалено
- Избыточные файлы документации (api-reference, deployment, development, и т.д.)
- Дублирующийся контент в нескольких документах
- Излишне детальная документация для простого файлового прокси
- 4 отдельных Vercel документа: vercel-thumbnails.md, vercel-integration.md, hybrid-architecture.md, vercel-og-integration.md
💋 **Упрощение**: KISS принцип применен - убрали избыточность, оставили суть.
2025-09-02 14:39:54 +03:00
|
|
|
|
|
|
|
|
# Redis configuration (optional - app works without Redis)
|
|
|
|
|
# If Redis is unavailable, app runs in fallback mode with warnings
|
|
|
|
|
REDIS_URL=redis://localhost:6379
|
2025-09-02 14:00:54 +03:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 🐳 Docker
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
# docker-compose.yml
|
|
|
|
|
version: '3.8'
|
|
|
|
|
services:
|
|
|
|
|
redis:
|
|
|
|
|
image: redis:alpine
|
|
|
|
|
ports: ["6379:6379"]
|
|
|
|
|
|
|
|
|
|
quoter:
|
|
|
|
|
build: .
|
|
|
|
|
ports: ["8080:8080"]
|
|
|
|
|
environment:
|
|
|
|
|
REDIS_URL: redis://redis:6379
|
|
|
|
|
STORJ_ACCESS_KEY: ${STORJ_ACCESS_KEY}
|
|
|
|
|
STORJ_SECRET_KEY: ${STORJ_SECRET_KEY}
|
2025-09-30 21:46:47 +03:00
|
|
|
JWT_SECRET_KEY: ${JWT_SECRET_KEY}
|
2025-09-02 14:00:54 +03:00
|
|
|
depends_on: [redis]
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 🔒 Security
|
|
|
|
|
|
|
|
|
|
### Rate Limits (per IP)
|
|
|
|
|
- General: 100 req/min
|
|
|
|
|
- Upload: 10 req/5min
|
|
|
|
|
- Auth: 20 req/15min
|
|
|
|
|
|
|
|
|
|
### File Limits
|
|
|
|
|
- Max file: 500MB
|
|
|
|
|
- User quota: 5GB default
|
|
|
|
|
- Supported: JPG, PNG, GIF, WebP, HEIC, MP4, PDF
|
|
|
|
|
|
|
|
|
|
## 🔧 Production Setup
|
|
|
|
|
|
|
|
|
|
### Nginx Proxy
|
|
|
|
|
```nginx
|
|
|
|
|
server {
|
|
|
|
|
listen 80;
|
|
|
|
|
server_name files.example.com;
|
|
|
|
|
|
|
|
|
|
location / {
|
|
|
|
|
proxy_pass http://localhost:8080;
|
|
|
|
|
proxy_set_header X-Forwarded-For $remote_addr;
|
|
|
|
|
client_max_body_size 500M;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Systemd Service
|
|
|
|
|
```ini
|
|
|
|
|
# /etc/systemd/system/quoter.service
|
|
|
|
|
[Unit]
|
|
|
|
|
Description=Quoter File Service
|
|
|
|
|
After=network.target redis.service
|
|
|
|
|
|
|
|
|
|
[Service]
|
|
|
|
|
Type=simple
|
|
|
|
|
User=quoter
|
|
|
|
|
ExecStart=/opt/quoter/quoter
|
|
|
|
|
Restart=always
|
|
|
|
|
Environment=RUST_LOG=info
|
|
|
|
|
|
|
|
|
|
[Install]
|
|
|
|
|
WantedBy=multi-user.target
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 📊 Monitoring
|
|
|
|
|
|
|
|
|
|
### Health Check
|
|
|
|
|
```bash
|
|
|
|
|
curl http://localhost:8080/ # Should return "ok"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Redis Monitoring
|
|
|
|
|
```bash
|
|
|
|
|
redis-cli info memory
|
|
|
|
|
redis-cli --latency
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Logs
|
|
|
|
|
```bash
|
|
|
|
|
# View logs
|
|
|
|
|
journalctl -f -u quoter
|
|
|
|
|
|
|
|
|
|
# Log format
|
|
|
|
|
INFO Upload successful: user_123 uploaded file.jpg (2.5MB)
|
|
|
|
|
WARN Rate limit exceeded: IP 192.168.1.100
|
|
|
|
|
ERROR Failed to upload to S3: network timeout
|
|
|
|
|
|
|
|
|
|
# CORS analytics logs (with RUST_LOG=info)
|
|
|
|
|
INFO 📥 Request source: origin=https://new.discours.io, referer=https://new.discours.io/posts/123, ip=1.2.3.4
|
|
|
|
|
INFO 📊 ANALYTICS: path=image.jpg, size=2048b, origin=https://vercel.app, referer=none, ip=5.6.7.8
|
|
|
|
|
WARN ⚠️ CORS not whitelisted: https://unknown-domain.com
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Analyzing Request Sources
|
|
|
|
|
```bash
|
|
|
|
|
# Find most common origins for CORS whitelist tuning
|
|
|
|
|
grep "📥 Request source" /var/log/quoter.log | grep -o "origin=[^,]*" | sort | uniq -c | sort -rn
|
|
|
|
|
|
|
|
|
|
# Find Vercel requests
|
|
|
|
|
grep "vercel" /var/log/quoter.log | grep "📊 ANALYTICS"
|
|
|
|
|
|
|
|
|
|
# Find requests from unknown sources
|
|
|
|
|
grep "⚠️ CORS not whitelisted" /var/log/quoter.log
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 🔧 Troubleshooting
|
|
|
|
|
|
|
|
|
|
### Common Issues
|
|
|
|
|
|
|
|
|
|
**Redis connection failed**
|
|
|
|
|
```bash
|
|
|
|
|
redis-cli ping # Should return PONG
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**S3 upload failed**
|
|
|
|
|
```bash
|
|
|
|
|
# Test S3 credentials
|
|
|
|
|
aws s3 ls --endpoint-url=https://gateway.storjshare.io
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**High memory usage**
|
|
|
|
|
```bash
|
|
|
|
|
# Check Redis memory
|
|
|
|
|
redis-cli memory usage <key>
|
|
|
|
|
|
|
|
|
|
# Clear cache if needed
|
|
|
|
|
redis-cli flushdb
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Debug Mode
|
|
|
|
|
```bash
|
|
|
|
|
RUST_LOG=debug cargo run
|
|
|
|
|
```
|