diff --git a/README.md b/README.md index e69de29..bdbda61 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,157 @@ +# English Bot - Metrics Dashboard + +Приложение для отслеживания переходов в Telegram бота и канал. + +## Структура проекта + +``` +eng-bot/ +├── backend/ # Django API + Dashboard +├── frontend/ # Nuxt.js фронтенд +├── docker-compose.yml +├── nginx.conf # Внутренний nginx (роутинг между сервисами) +└── nginx.external.example.conf # Пример внешнего nginx +``` + +## Быстрый старт + +```bash +# Сборка и запуск +docker compose up -d --build + +# Просмотр логов +docker compose logs -f + +# Остановка +docker compose down +``` + +## URL-адреса приложения + +### Локальная разработка (порт 3001) + +| URL | Описание | +|-----|----------| +| `http://localhost:3001/` | Главная страница (Nuxt фронтенд) | +| `http://localhost:3001/stats/` | Дашборд статистики (Django) | +| `http://localhost:3001/admin/` | Django Admin панель | + +### API Endpoints + +| Метод | URL | Описание | +|-------|-----|----------| +| `POST` | `/api/track/bot/` | Отслеживание перехода в бота | +| `POST` | `/api/track/channel/` | Отслеживание перехода в канал | + +### Примеры запросов + +```bash +# Трекинг перехода в бота +curl -X POST http://localhost:3001/api/track/bot/ + +# Трекинг перехода в канал +curl -X POST http://localhost:3001/api/track/channel/ +``` + +## Архитектура + +``` +┌─────────────┐ ┌─────────────┐ ┌─────────────┐ +│ Клиент │────▶│ Nginx │────▶│ Frontend │ +│ │ │ :3001 │ │ (Nuxt) │ +└─────────────┘ └──────┬──────┘ └─────────────┘ + │ + │ /api/*, /stats/, /admin/, /static/ + ▼ + ┌─────────────┐ + │ Backend │ + │ (Django) │ + └─────────────┘ +``` + +## Конфигурация + +### Переменные окружения + +**Backend:** +- `DEBUG` - режим отладки (по умолчанию `False` в docker) +- `DATA_DIR` - путь к данным/БД (по умолчанию `/app/data`) + +**Frontend:** +- `NUXT_PUBLIC_API_BASE` - базовый URL API (по умолчанию `http://localhost:3001`) + +### Порты + +| Сервис | Внутренний порт | Внешний порт | +|--------|-----------------|--------------| +| Nginx | 80 | 3001 | +| Frontend | 3000 | - | +| Backend | 8000 | - | + +## Продакшен + +### Внешний Nginx + +Для продакшена используйте `nginx.external.example.conf` как основу: + +```bash +# Скопировать конфиг +sudo cp nginx.external.example.conf /etc/nginx/sites-available/eng-bot.conf + +# Отредактировать домен +sudo nano /etc/nginx/sites-available/eng-bot.conf + +# Включить сайт +sudo ln -s /etc/nginx/sites-available/eng-bot.conf /etc/nginx/sites-enabled/ + +# Получить SSL сертификат +sudo certbot --nginx -d your-domain.com + +# Перезапустить nginx +sudo systemctl reload nginx +``` + +### Защита /stats/ + +Рекомендуется закрыть доступ к статистике. Варианты: + +1. **По IP** - раскомментируйте блок с `allow/deny` в nginx.external.example.conf +2. **Basic Auth** - раскомментируйте блок с `auth_basic` + +Создание пароля для Basic Auth: +```bash +sudo htpasswd -c /etc/nginx/.htpasswd admin +``` + +## Разработка + +### Локальный запуск без Docker + +**Backend:** +```bash +cd backend +python -m venv venv +source venv/bin/activate +pip install -r requirements.txt +python manage.py migrate +python manage.py runserver 8000 +``` + +**Frontend:** +```bash +cd frontend +npm install +npm run dev +``` + +## База данных + +SQLite база хранится в Docker volume `backend-data` по пути `/app/data/db.sqlite3`. + +```bash +# Бэкап БД +docker compose exec backend cat /app/data/db.sqlite3 > backup.sqlite3 + +# Создание суперпользователя Django +docker compose exec backend python manage.py createsuperuser +``` diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..61aa361 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,44 @@ +services: + backend: + build: + context: ./backend + dockerfile: Dockerfile + container_name: eng-bot-backend + volumes: + - backend-data:/app/data + expose: + - "8000" + environment: + - DEBUG=False + - DATA_DIR=/app/data + restart: unless-stopped + + frontend: + build: + context: ./frontend + dockerfile: Dockerfile + args: + - NUXT_PUBLIC_API_BASE=http://localhost:3001 + container_name: eng-bot-frontend + expose: + - "3000" + environment: + - NUXT_PUBLIC_API_BASE=http://localhost:3001 + depends_on: + - backend + restart: unless-stopped + + nginx: + image: nginx:alpine + container_name: eng-bot-nginx + ports: + - "3001:80" + volumes: + - ./nginx.conf:/etc/nginx/nginx.conf:ro + depends_on: + - frontend + - backend + restart: unless-stopped + +volumes: + backend-data: diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..ef434f7 --- /dev/null +++ b/nginx.conf @@ -0,0 +1,55 @@ +events { + worker_connections 1024; +} + +http { + upstream frontend { + server frontend:3000; + } + + upstream backend { + server backend:8000; + } + + server { + listen 80; + server_name localhost; + + # Backend API routes + location /api/ { + proxy_pass http://backend; + proxy_set_header Host $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 static files + location /static/ { + proxy_pass http://backend; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + } + + # Backend stats dashboard (root of backend) + location /stats/ { + rewrite ^/stats/(.*)$ /$1 break; + proxy_pass http://backend; + proxy_set_header Host $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; + } + + # Frontend (default) + location / { + proxy_pass http://frontend; + proxy_set_header Host $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 Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } + } +} diff --git a/nginx.external.example.conf b/nginx.external.example.conf new file mode 100644 index 0000000..4a4faec --- /dev/null +++ b/nginx.external.example.conf @@ -0,0 +1,81 @@ +# Пример конфигурации внешнего Nginx (reverse proxy) +# Для использования перед docker-compose стеком +# +# Скопируйте в /etc/nginx/sites-available/eng-bot.conf +# и создайте симлинк: ln -s /etc/nginx/sites-available/eng-bot.conf /etc/nginx/sites-enabled/ + +server { + listen 80; + server_name your-domain.com www.your-domain.com; + + # Редирект на HTTPS + return 301 https://$server_name$request_uri; +} + +server { + listen 443 ssl http2; + server_name your-domain.com www.your-domain.com; + + # SSL сертификаты (Let's Encrypt) + ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.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; + ssl_session_timeout 1d; + + # Gzip сжатие + gzip on; + gzip_vary on; + gzip_min_length 1024; + gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; + + # Логи + access_log /var/log/nginx/eng-bot.access.log; + error_log /var/log/nginx/eng-bot.error.log; + + # Проксирование на docker-compose стек (порт 3001) + location / { + proxy_pass http://127.0.0.1:3001; + proxy_http_version 1.1; + proxy_set_header Host $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 Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + # Таймауты + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + } + + # Опционально: закрыть доступ к статистике извне + # location /stats/ { + # allow 192.168.0.0/16; + # allow 10.0.0.0/8; + # deny all; + # + # proxy_pass http://127.0.0.1:3001; + # proxy_set_header Host $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; + # } + + # Опционально: Basic Auth для /stats/ + # location /stats/ { + # auth_basic "Statistics"; + # auth_basic_user_file /etc/nginx/.htpasswd; + # + # proxy_pass http://127.0.0.1:3001; + # proxy_set_header Host $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; + # } +}