diff --git a/.ch b/.ch new file mode 100644 index 0000000..6f968f1 --- /dev/null +++ b/.ch @@ -0,0 +1 @@ +{"value": "a63a416be5a5db101fd6db5ca604ae99833d23d0322428f256dd922eb2540c5a"} diff --git a/.env.example b/.env.example index 7292e37..27ef19e 100644 --- a/.env.example +++ b/.env.example @@ -1,95 +1,150 @@ # ============================================================================= -# ENVIRONMENT CONFIGURATION EXAMPLE -# Copy this file to .env and configure your values +# MY UPLOADER BOT - ENVIRONMENT CONFIGURATION +# ============================================================================= +# Скопируйте этот файл в .env и настройте под свою среду + +# ============================================================================= +# ОСНОВНЫЕ НАСТРОЙКИ # ============================================================================= -# Application Settings -DEBUG=false -ENVIRONMENT=production -SECRET_KEY=your-super-secret-key-change-this-in-production -ENCRYPTION_KEY=your-encryption-key-for-file-encryption +# Environment: development, production, testing +NODE_ENV=development +DEBUG=true -# Server Configuration -HOST=0.0.0.0 -PORT=15100 -WORKERS=4 -AUTO_RELOAD=false +# ============================================================================= +# DATABASE (PostgreSQL) +# ============================================================================= -# Database Configuration (PostgreSQL) -DATABASE_URL=postgresql+asyncpg://postgres:password@localhost:5432/myuploader -DATABASE_POOL_SIZE=20 -DATABASE_MAX_OVERFLOW=30 -DATABASE_POOL_TIMEOUT=30 -DATABASE_POOL_RECYCLE=3600 +DATABASE_URL=postgresql://my_user:CHANGE_ME_SECURE_PASSWORD@localhost:5432/my_uploader_db +POSTGRES_HOST=localhost +POSTGRES_PORT=5432 +POSTGRES_DB=my_uploader_db +POSTGRES_USER=my_user +POSTGRES_PASSWORD=CHANGE_ME_SECURE_PASSWORD + +# ============================================================================= +# REDIS CACHE +# ============================================================================= -# Redis Configuration REDIS_URL=redis://localhost:6379/0 -REDIS_POOL_SIZE=10 -REDIS_MAX_CONNECTIONS=20 -REDIS_SOCKET_TIMEOUT=5 -REDIS_SOCKET_CONNECT_TIMEOUT=5 +REDIS_HOST=localhost +REDIS_PORT=6379 +REDIS_PASSWORD= -# Security Settings -ACCESS_TOKEN_EXPIRE_MINUTES=60 -REFRESH_TOKEN_EXPIRE_DAYS=30 -PASSWORD_MIN_LENGTH=8 -RATE_LIMIT_ENABLED=true -CORS_ORIGINS=["http://localhost:3000","https://yourdomain.com"] +# ============================================================================= +# SECURITY KEYS +# ============================================================================= +# ВАЖНО: Генерируйте новые ключи для production! -# Storage Configuration -STORAGE_PATH=./data/storage -MAX_FILE_SIZE=10737418240 -MAX_CHUNK_SIZE=10485760 -CHUNK_SIZE=1048576 -ENCRYPT_FILES=true -CLEANUP_TEMP_FILES=true +SECRET_KEY=CHANGE_ME_SECRET_KEY_FOR_PRODUCTION_MIN_32_CHARS +JWT_SECRET=CHANGE_ME_JWT_SECRET_FOR_PRODUCTION_MIN_32_CHARS +ENCRYPTION_KEY=CHANGE_ME_ENCRYPTION_KEY_32_CHARS_LONG -# User Limits -MAX_UPLOADS_PER_DAY=100 -MAX_STORAGE_PER_USER=107374182400 -MAX_FILES_PER_USER=10000 -DAILY_TRANSACTION_LIMIT=10 -MAX_TRANSACTION_AMOUNT=5 +# ============================================================================= +# MY NETWORK SETTINGS +# ============================================================================= -# TON Blockchain Configuration -TON_API_ENDPOINT=https://toncenter.com/api/v2 -TON_API_KEY=your-ton-api-key -TON_TESTNET=false -TON_WALLET_VERSION=v4 +MY_NETWORK_NODE_ID=local-dev-node +MY_NETWORK_PORT=15100 +MY_NETWORK_HOST=0.0.0.0 +MY_NETWORK_DOMAIN=localhost +MY_NETWORK_SSL_ENABLED=false -# Logging Configuration -LOG_LEVEL=INFO -LOG_FORMAT=json +# Bootstrap узлы для подключения к сети +MY_NETWORK_BOOTSTRAP_NODES=my-public-node-3.projscale.dev:15100 + +# ============================================================================= +# API SETTINGS +# ============================================================================= + +API_HOST=0.0.0.0 +API_PORT=15100 +API_WORKERS=2 +MAX_UPLOAD_SIZE=50MB +UPLOAD_PATH=./uploads + +# ============================================================================= +# LOGGING +# ============================================================================= + +LOG_LEVEL=DEBUG +LOG_FORMAT=text LOG_FILE=./logs/app.log -LOG_ROTATION=daily -LOG_RETENTION_DAYS=30 -# Email Configuration (Optional) +# ============================================================================= +# MONITORING (Опционально) +# ============================================================================= + +# Grafana +GRAFANA_PASSWORD=admin123 + +# Prometheus +PROMETHEUS_RETENTION=15d + +# ============================================================================= +# EMAIL SETTINGS (Опционально) +# ============================================================================= + SMTP_HOST=smtp.gmail.com SMTP_PORT=587 -SMTP_USERNAME=your-email@gmail.com +SMTP_USER=your-email@gmail.com SMTP_PASSWORD=your-app-password -SMTP_TLS=true -FROM_EMAIL=noreply@yourdomain.com +SMTP_FROM=noreply@yourdomain.com -# Monitoring Configuration -METRICS_ENABLED=true -METRICS_PORT=9090 -HEALTH_CHECK_ENABLED=true +# ============================================================================= +# SOCIAL AUTH (Опционально) +# ============================================================================= -# External Services (Optional) -WEBHOOK_URL=https://yourdomain.com/webhooks -BACKUP_ENABLED=true +# GitHub OAuth +GITHUB_CLIENT_ID=your-github-client-id +GITHUB_CLIENT_SECRET=your-github-client-secret + +# Google OAuth +GOOGLE_CLIENT_ID=your-google-client-id +GOOGLE_CLIENT_SECRET=your-google-client-secret + +# ============================================================================= +# EXTERNAL SERVICES (Опционально) +# ============================================================================= + +# AWS S3 (для backup) +AWS_ACCESS_KEY_ID=your-aws-access-key +AWS_SECRET_ACCESS_KEY=your-aws-secret-key +AWS_BUCKET_NAME=your-backup-bucket +AWS_REGION=us-east-1 + +# Cloudflare (для CDN) +CLOUDFLARE_API_TOKEN=your-cloudflare-token +CLOUDFLARE_ZONE_ID=your-zone-id + +# ============================================================================= +# PRODUCTION ТОЛЬКО +# ============================================================================= + +# SSL Сертификаты +SSL_CERT_PATH=/etc/ssl/certs/yourdomain.crt +SSL_KEY_PATH=/etc/ssl/private/yourdomain.key + +# Backup BACKUP_SCHEDULE=0 2 * * * BACKUP_RETENTION_DAYS=30 +BACKUP_S3_BUCKET=your-backup-bucket -# Development Settings (Only for development) -# DEV_RELOAD=true -# DEV_DEBUG_TOOLBAR=true -# DEV_PROFILER=true +# Security +ALLOWED_HOSTS=yourdomain.com,www.yourdomain.com +CORS_ORIGINS=https://yourdomain.com,https://www.yourdomain.com -# Production Settings (Only for production) -# SENTRY_DSN=https://your-sentry-dsn -# SSL_ENABLED=true -# SSL_CERT_PATH=/path/to/cert.pem -# SSL_KEY_PATH=/path/to/key.pem \ No newline at end of file +# Rate Limiting +RATE_LIMIT_PER_MINUTE=60 +RATE_LIMIT_BURST=10 + +# ============================================================================= +# DEVELOPMENT ТОЛЬКО +# ============================================================================= + +# Debug mode +FLASK_DEBUG=true +UVICORN_RELOAD=true + +# Local testing +TEST_DATABASE_URL=postgresql://test_user:test_pass@localhost:5433/test_db \ No newline at end of file diff --git a/DOCKER_SETUP.md b/DOCKER_SETUP.md deleted file mode 100644 index 07d682a..0000000 --- a/DOCKER_SETUP.md +++ /dev/null @@ -1,187 +0,0 @@ -# 🐳 Запуск MY Uploader Bot через Docker - -## 📋 Требования - -- Docker и Docker Compose установлены -- Telegram Bot токены от @BotFather - -## ⚡ Быстрый запуск - -### 1. Настройка переменных окружения - -Отредактируйте файл [`.env`](.env) - **ОБЯЗАТЕЛЬНО** заполните Telegram токены: - -```bash -# ОБЯЗАТЕЛЬНО: Получите токены у @BotFather в Telegram -TELEGRAM_API_KEY=123456789:YOUR_ACTUAL_BOT_TOKEN_HERE -CLIENT_TELEGRAM_API_KEY=987654321:YOUR_ACTUAL_CLIENT_BOT_TOKEN_HERE -``` - -Остальные настройки можно оставить по умолчанию для тестирования. - -### 2. Запуск базовых сервисов - -```bash -# Базовые сервисы (PostgreSQL + Redis + Application) -docker-compose -f docker-compose.new.yml up -d postgres redis app - -# Проверка статуса -docker-compose -f docker-compose.new.yml ps -``` - -### 3. Проверка работы - -```bash -# Проверка логов приложения -docker-compose -f docker-compose.new.yml logs -f app - -# Проверка health endpoints -curl http://localhost:15100/health -curl http://localhost:15100/api/my/health -``` - -### 4. Веб-интерфейс - -- **Основное приложение**: http://localhost:15100 -- **MY Network Monitor**: http://localhost:15100/api/my/monitor/ -- **Метрики**: http://localhost:9090 - -## 🔧 Дополнительные профили - -### Мониторинг (Prometheus + Grafana) - -```bash -docker-compose -f docker-compose.new.yml --profile monitoring up -d - -# Доступ: -# Prometheus: http://localhost:9091 -# Grafana: http://localhost:3001 (admin/admin) -``` - -### Отдельные сервисы (альтернативная архитектура) - -```bash -docker-compose -f docker-compose.new.yml --profile separate-services up -d -``` - -### Прокси с SSL (Traefik) - -```bash -docker-compose -f docker-compose.new.yml --profile proxy up -d - -# Настройте DOMAIN в .env перед запуском -``` - -### Автоматические бэкапы - -```bash -docker-compose -f docker-compose.new.yml --profile backup up -d -``` - -## 🔍 Диагностика - -### Просмотр логов - -```bash -# Все сервисы -docker-compose -f docker-compose.new.yml logs -f - -# Конкретный сервис -docker-compose -f docker-compose.new.yml logs -f app -docker-compose -f docker-compose.new.yml logs -f postgres -docker-compose -f docker-compose.new.yml logs -f redis -``` - -### Проверка состояния базы данных - -```bash -# Подключение к PostgreSQL -docker-compose -f docker-compose.new.yml exec postgres psql -U uploader -d uploader_bot - -# Проверка таблиц -\dt - -# Выход -\q -``` - -### Проверка Redis - -```bash -# Подключение к Redis -docker-compose -f docker-compose.new.yml exec redis redis-cli - -# Проверка ключей -KEYS * - -# Выход -exit -``` - -## 🛠 Разработка - -### Пересборка приложения - -```bash -# После изменения кода -docker-compose -f docker-compose.new.yml build app -docker-compose -f docker-compose.new.yml up -d app -``` - -### Выполнение команд внутри контейнера - -```bash -# Bash в контейнере приложения -docker-compose -f docker-compose.new.yml exec app bash - -# Миграции базы данных -docker-compose -f docker-compose.new.yml exec app python -m alembic upgrade head - -# Проверка MY Network -docker-compose -f docker-compose.new.yml exec app python -c "from app.core.my_network import test_connection; test_connection()" -``` - -## 🛑 Остановка - -```bash -# Остановка всех сервисов -docker-compose -f docker-compose.new.yml down - -# Остановка с удалением volumes (ВНИМАНИЕ: удалит все данные!) -docker-compose -f docker-compose.new.yml down -v - -# Очистка всех docker ресурсов -docker system prune -a -``` - -## 📊 MY Network Protocol - -После запуска доступны MY Network endpoints: - -- **Конфигурация bootstrap**: http://localhost:15100/api/my/bootstrap/config -- **Статус сети**: http://localhost:15100/api/my/health -- **Мониторинг ASCII**: http://localhost:15100/api/my/monitor/ -- **Метрики**: http://localhost:15100/api/my/metrics - -## ⚠ Важные переменные в .env - -| Переменная | Описание | Обязательна | -|------------|----------|-------------| -| `TELEGRAM_API_KEY` | Основной бот токен | ✅ ДА | -| `CLIENT_TELEGRAM_API_KEY` | Клиентский бот токен | ✅ ДА | -| `SECRET_KEY` | Секретный ключ (32+ символов) | ✅ ДА | -| `JWT_SECRET_KEY` | JWT секрет (32+ символов) | ✅ ДА | -| `POSTGRES_PASSWORD` | Пароль базы данных | ❌ НЕТ | -| `DEBUG` | Режим отладки | ❌ НЕТ | -| `TESTNET` | Тестовая сеть TON | ❌ НЕТ | - -## 🚀 Готово к продакшену - -Для продакшена дополнительно настройте: - -1. Сильные пароли в `.env` -2. `DEBUG=false` -3. Правильный `DOMAIN` -4. `TESTNET=false` для основной сети TON -5. Валидные `TONCENTER_API_KEY` -6. SSL сертификаты через Traefik профиль \ No newline at end of file diff --git a/README.md b/README.md index b98ce22..d87c478 100644 --- a/README.md +++ b/README.md @@ -1,504 +1,101 @@ -# My Uploader Bot - Comprehensive File Upload & Blockchain Integration System +# MY Network - Универсальная установка -A modern, scalable file upload and management system with blockchain integration, built with async Python and enterprise-grade security. +🚀 **Универсальный установщик MY Network для любого сервера** -## 🚀 Features +## ⚡ Быстрая установка -### Core Features -- **Chunked File Upload**: Support for large files with resume capability -- **Multi-Storage Backend**: Local, S3-compatible storage with automatic failover -- **File Processing**: Automatic image optimization, thumbnail generation, media conversion -- **Content Management**: Version control, metadata management, search functionality -- **User Management**: JWT authentication, API keys, session management +Один скрипт для полной установки на любом сервере: -### Blockchain Integration -- **TON Blockchain**: Wallet creation, transaction management, balance tracking -- **Smart Contracts**: Interaction with TON smart contracts -- **NFT Support**: NFT collection indexing and management -- **DeFi Integration**: Staking positions, token balances, yield farming - -### Enterprise Features -- **Security**: Rate limiting, CORS, CSP, input validation, file encryption -- **Monitoring**: Prometheus metrics, Grafana dashboards, health checks -- **Caching**: Redis integration with intelligent cache management -- **Background Services**: Async task processing, blockchain indexing -- **API Documentation**: OpenAPI/Swagger with interactive interface - -## 🏗️ Architecture - -### Technology Stack -- **Backend**: Python 3.11+, Sanic (async web framework) -- **Database**: PostgreSQL 15+ with async SQLAlchemy 2.0 -- **Cache**: Redis 7+ with connection pooling -- **Blockchain**: TON SDK for blockchain operations -- **Storage**: Local filesystem with S3-compatible support -- **Monitoring**: Prometheus, Grafana, structured logging -- **Deployment**: Docker Compose with multi-stage builds - -### System Architecture -``` -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ Load Balancer │ │ Grafana │ │ Prometheus │ -│ (Nginx) │ │ (Monitoring) │ │ (Metrics) │ -└─────────────────┘ └─────────────────┘ └─────────────────┘ - │ │ │ - ▼ ▼ ▼ -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ Sanic App │◄──►│ Redis │ │ PostgreSQL │ -│ (API Server) │ │ (Cache) │ │ (Database) │ -└─────────────────┘ └─────────────────┘ └─────────────────┘ - │ │ │ - ▼ ▼ ▼ -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ Background │ │ File Storage │ │ TON Blockchain │ -│ Services │ │ (Local/S3/CDN) │ │ Integration │ -└─────────────────┘ └─────────────────┘ └─────────────────┘ -``` - -## 🔧 Installation & Setup - -### Prerequisites -- Python 3.11+ -- PostgreSQL 15+ -- Redis 7+ -- Docker & Docker Compose (recommended) - -### Quick Start with Docker - -1. **Clone the repository**: ```bash -git clone https://github.com/your-org/my-uploader-bot.git -cd my-uploader-bot +# Скачать проект +git clone +cd uploader-bot # или my-uploader-bot, или название вашего проекта + +# Запустить установку +chmod +x universal_installer.sh +sudo ./universal_installer.sh ``` -2. **Create environment file**: +## 📁 Структура проекта + +``` +my-uploader-bot/ +├── universal_installer.sh # 🚀 Основной установщик +├── app/ # 💻 Код приложения +├── scripts/ # 🛠️ Утилиты и скрипты +├── deployment/ # 📦 Файлы развертывания +├── docs/ # 📚 Документация +└── ... +``` + +### 📦 deployment/ +- `docker-compose.production.yml` - Основной compose файл +- `Dockerfile` - Образ приложения +- `requirements.txt` - Python зависимости +- `env.example` - Пример переменных окружения + +### 🛠️ scripts/ +- `diagnose.sh` - Диагностика проблем +- `quick_check.sh` - Быстрая проверка статуса +- `setup_*.sh` - Скрипты настройки компонентов + +### 📚 docs/ +- Документация проекта +- `archive/` - Устаревшие файлы + +## 🔧 Что делает universal_installer.sh + +1. **🔍 Автопоиск проекта** - находит папку проекта в любой директории +2. **📦 Установка зависимостей** - Docker, Docker Compose, Nginx, UFW +3. **🔒 Настройка безопасности** - файрвол, fail2ban +4. **🗑️ Очистка** - удаляет старые контейнеры +5. **⚙️ Конфигурация** - создает .env, настраивает nginx +6. **🚀 Запуск** - запускает все сервисы +7. **🔧 SystemD service** - автозапуск при перезагрузке +8. **✅ Тестирование** - проверяет работу API + +## 🌐 После установки + +Сервер будет доступен на: +- `http://YOUR_SERVER_IP/api/health` - API health check +- `http://YOUR_SERVER_IP/health` - Альтернативный health check + +## 🛠️ Управление + ```bash -cp .env.example .env -# Edit .env with your configuration +# Статус +sudo systemctl status mynetwork + +# Перезапуск +sudo systemctl restart mynetwork + +# Логи +docker logs $(docker ps --format "{{.Names}}" | grep app | head -1) ``` -3. **Start services**: +## 🔍 Диагностика + +Если что-то не работает: + ```bash -docker-compose -f docker-compose.new.yml up -d +# Быстрая диагностика +./scripts/diagnose.sh + +# Полная диагностика +./scripts/full_diagnosis.sh ``` -4. **Initialize database**: -```bash -docker-compose -f docker-compose.new.yml exec app alembic upgrade head -``` +## 📋 Поддерживаемые системы -5. **Create admin user**: -```bash -docker-compose -f docker-compose.new.yml exec app python -m app.scripts.create_admin -``` +- ✅ Ubuntu 20.04+ +- ✅ Debian 11+ +- ✅ CentOS 8+ (адаптация) -### Manual Installation +## 🆘 Поддержка -1. **Install dependencies**: -```bash -# Using Poetry (recommended) -poetry install - -# Or using pip -pip install -r requirements_new.txt -``` - -2. **Set up database**: -```bash -# Create database -createdb myuploader - -# Run migrations -alembic upgrade head -``` - -3. **Configure Redis**: -```bash -# Start Redis with custom config -redis-server config/redis.conf -``` - -4. **Start application**: -```bash -# Development mode -python -m app - -# Production mode -gunicorn app:create_app --bind 0.0.0.0:8000 --worker-class sanic.worker.GunicornWorker -``` - -## ⚙️ Configuration - -### Environment Variables - -**Database Configuration**: -```bash -DATABASE_URL=postgresql+asyncpg://user:password@localhost:5432/myuploader -DB_POOL_SIZE=20 -DB_MAX_OVERFLOW=30 -``` - -**Redis Configuration**: -```bash -REDIS_URL=redis://localhost:6379/0 -REDIS_POOL_SIZE=20 -REDIS_POOL_MAX_CONNECTIONS=100 -``` - -**Security Configuration**: -```bash -SECRET_KEY=your-super-secret-key-here -JWT_SECRET_KEY=your-jwt-secret-key -JWT_ACCESS_TOKEN_EXPIRE_MINUTES=30 -JWT_REFRESH_TOKEN_EXPIRE_DAYS=7 -``` - -**Storage Configuration**: -```bash -STORAGE_BACKEND=local # or s3, gcs, azure -STORAGE_PATH=/app/uploads -MAX_FILE_SIZE=104857600 # 100MB -ALLOWED_FILE_TYPES=image,video,audio,document -``` - -**Blockchain Configuration**: -```bash -TON_NETWORK=mainnet # or testnet -TON_API_KEY=your-ton-api-key -TON_WALLET_VERSION=v4 -``` - -### Configuration Files - -**Redis Configuration** (`config/redis.conf`): -- Optimized for caching workload -- Memory management and persistence settings -- Security and performance tuning - -**Prometheus Configuration** (`monitoring/prometheus.yml`): -- Scraping configuration for all services -- Alert rules and metric collection -- Storage and retention settings - -## 📊 API Documentation - -### Interactive Documentation -- **Swagger UI**: http://localhost:8000/docs -- **ReDoc**: http://localhost:8000/redoc -- **OpenAPI JSON**: http://localhost:8000/openapi.json - -### Authentication Methods - -1. **JWT Bearer Token**: -```bash -curl -H "Authorization: Bearer " \ - https://api.myuploader.com/api/v1/content/ -``` - -2. **API Key**: -```bash -curl -H "X-API-Key: " \ - https://api.myuploader.com/api/v1/content/ -``` - -3. **Session Cookie**: -```bash -curl -b "session=" \ - https://api.myuploader.com/api/v1/content/ -``` - -### Key Endpoints - -**Authentication**: -- `POST /api/v1/auth/register` - User registration -- `POST /api/v1/auth/login` - User login -- `POST /api/v1/auth/refresh` - Token refresh -- `DELETE /api/v1/auth/logout` - User logout - -**Content Management**: -- `GET /api/v1/content/` - List content -- `POST /api/v1/content/` - Create content -- `GET /api/v1/content/{id}` - Get content details -- `PUT /api/v1/content/{id}` - Update content -- `DELETE /api/v1/content/{id}` - Delete content - -**File Upload**: -- `POST /api/v1/storage/upload/initiate` - Start upload -- `POST /api/v1/storage/upload/chunk` - Upload chunk -- `POST /api/v1/storage/upload/complete` - Complete upload -- `GET /api/v1/storage/download/{id}` - Download file - -**Blockchain**: -- `POST /api/v1/blockchain/wallet/create` - Create wallet -- `GET /api/v1/blockchain/wallet/{id}` - Get wallet info -- `POST /api/v1/blockchain/transaction/send` - Send transaction -- `GET /api/v1/blockchain/transaction/{hash}` - Get transaction status - -## 🛡️ Security - -### Security Features -- **Authentication**: Multi-factor authentication support -- **Authorization**: Role-based access control (RBAC) -- **Input Validation**: Comprehensive request validation -- **Rate Limiting**: Per-user and per-endpoint limits -- **File Security**: Virus scanning, type validation, encryption -- **Network Security**: CORS, CSP, HTTPS enforcement - -### Security Best Practices - -1. **Environment Variables**: Store sensitive data in environment variables -2. **Database Security**: Use connection pooling, parameterized queries -3. **File Upload Security**: Validate file types, scan for malware -4. **API Security**: Implement rate limiting, request validation -5. **Monitoring**: Track security events and anomalies - -### Audit Logging -All security-relevant events are logged: -- Authentication attempts -- Authorization failures -- File upload/download events -- API key usage -- Blockchain transactions - -## 📈 Monitoring & Observability - -### Metrics Collection -- **Application Metrics**: Request counts, response times, error rates -- **System Metrics**: CPU, memory, disk usage -- **Database Metrics**: Connection pool, query performance -- **Cache Metrics**: Hit rates, memory usage -- **Blockchain Metrics**: Transaction status, wallet balances - -### Dashboards -- **Application Dashboard**: Request metrics, error rates -- **Infrastructure Dashboard**: System resources, service health -- **Database Dashboard**: Query performance, connection pools -- **Security Dashboard**: Failed logins, rate limits - -### Alerting Rules -- High error rates (>5% for 5 minutes) -- High response times (>2s for 95th percentile) -- Database connection issues -- High memory usage (>90%) -- Failed blockchain transactions - -## 🔄 Background Services - -### File Conversion Service -- **Image Processing**: Resize, optimize, generate thumbnails -- **Video Processing**: Transcode, extract thumbnails -- **Document Processing**: Extract metadata, generate previews -- **Retry Logic**: Automatic retry for failed conversions - -### Blockchain Indexer Service -- **Transaction Monitoring**: Track pending transactions -- **Wallet Balance Updates**: Sync wallet balances -- **NFT Indexing**: Track NFT collections and transfers -- **Event Processing**: Process blockchain events - -## 🚀 Deployment - -### Docker Deployment - -1. **Production Build**: -```bash -docker build -f Dockerfile.new --target production -t my-uploader-bot:latest . -``` - -2. **Deploy with Compose**: -```bash -docker-compose -f docker-compose.new.yml up -d -``` - -3. **Health Checks**: -```bash -curl http://localhost:8000/health -``` - -### Kubernetes Deployment - -1. **Create ConfigMaps**: -```bash -kubectl create configmap app-config --from-env-file=.env -``` - -2. **Deploy Application**: -```bash -kubectl apply -f k8s/ -``` - -3. **Check Status**: -```bash -kubectl get pods -l app=my-uploader-bot -``` - -### Production Considerations - -1. **Database**: Use managed PostgreSQL service -2. **Cache**: Use managed Redis service -3. **Storage**: Use S3-compatible object storage -4. **Load Balancer**: Use cloud load balancer -5. **SSL/TLS**: Use Let's Encrypt or cloud SSL -6. **Monitoring**: Use managed monitoring service - -## 🧪 Testing - -### Running Tests -```bash -# Run all tests -pytest - -# Run with coverage -pytest --cov=app - -# Run specific test file -pytest tests/test_auth.py - -# Run integration tests -pytest tests/integration/ -``` - -### Test Categories -- **Unit Tests**: Individual function/method tests -- **Integration Tests**: Service integration tests -- **API Tests**: HTTP endpoint tests -- **Database Tests**: Database operation tests -- **Security Tests**: Security vulnerability tests - -## 🔍 Development - -### Development Setup -```bash -# Install dev dependencies -poetry install --dev - -# Pre-commit hooks -pre-commit install - -# Run linting -black app/ -isort app/ -mypy app/ - -# Database migrations -alembic revision --autogenerate -m "Description" -alembic upgrade head -``` - -### Code Quality Tools -- **Black**: Code formatting -- **isort**: Import sorting -- **mypy**: Type checking -- **bandit**: Security scanning -- **pytest**: Testing framework - -### Contributing Guidelines -1. Fork the repository -2. Create feature branch -3. Write tests for new features -4. Ensure all tests pass -5. Run security scans -6. Submit pull request - -## 📝 Migration Guide - -### From v1.x to v2.x - -1. **Database Migration**: -```bash -# Backup existing database -pg_dump myuploader > backup.sql - -# Run new migrations -alembic upgrade head -``` - -2. **Configuration Updates**: -- Update environment variables -- Migrate Redis configuration -- Update storage configuration - -3. **API Changes**: -- Authentication endpoints changed -- New blockchain endpoints added -- Response format updates - -## 🐛 Troubleshooting - -### Common Issues - -**Database Connection Issues**: -```bash -# Check database connectivity -psql -h localhost -U postgres -d myuploader - -# Check connection pool -docker-compose logs db -``` - -**Redis Connection Issues**: -```bash -# Test Redis connection -redis-cli ping - -# Check Redis logs -docker-compose logs redis -``` - -**File Upload Issues**: -```bash -# Check storage permissions -ls -la /app/uploads - -# Check disk space -df -h -``` - -**Blockchain Issues**: -```bash -# Check TON network status -curl https://toncenter.com/api/v2/getAddressInformation - -# Check wallet balance -curl -X GET /api/v1/blockchain/wallet/{wallet_id} -``` - -### Performance Optimization - -1. **Database Optimization**: - - Add indexes for frequently queried columns - - Optimize query patterns - - Use connection pooling - -2. **Cache Optimization**: - - Implement cache warming - - Use appropriate TTL values - - Monitor cache hit rates - -3. **File Storage Optimization**: - - Use CDN for static files - - Implement file compression - - Use efficient storage backends - -## 📚 Additional Resources - -- **API Documentation**: https://docs.myuploader.com -- **SDK Documentation**: https://sdk.myuploader.com -- **Community Forum**: https://community.myuploader.com -- **GitHub Repository**: https://github.com/your-org/my-uploader-bot -- **Docker Images**: https://hub.docker.com/r/myuploader/app - -## 📄 License - -This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. - -## 🤝 Support - -- **Email**: support@myuploader.com -- **Discord**: https://discord.gg/myuploader -- **GitHub Issues**: https://github.com/your-org/my-uploader-bot/issues -- **Documentation**: https://docs.myuploader.com - ---- - -**Built with ❤️ by the My Uploader Bot Team** +Скрипт автоматически: +- Находит проект в любой директории +- Адаптируется к разным именам контейнеров +- Работает с разными compose файлами +- Создает резервные копии конфигураций +- Показывает детальную диагностику при ошибках \ No newline at end of file diff --git a/Dockerfile b/deployment/Dockerfile similarity index 100% rename from Dockerfile rename to deployment/Dockerfile diff --git a/Dockerfile.simple b/deployment/Dockerfile.simple similarity index 100% rename from Dockerfile.simple rename to deployment/Dockerfile.simple diff --git a/bootstrap.json b/deployment/bootstrap.json similarity index 100% rename from bootstrap.json rename to deployment/bootstrap.json diff --git a/docker-compose.compatible.yml b/deployment/docker-compose.compatible.yml similarity index 100% rename from docker-compose.compatible.yml rename to deployment/docker-compose.compatible.yml diff --git a/docker-compose.new.yml b/deployment/docker-compose.new.yml similarity index 100% rename from docker-compose.new.yml rename to deployment/docker-compose.new.yml diff --git a/docker-compose.production.yml b/deployment/docker-compose.production.yml similarity index 100% rename from docker-compose.production.yml rename to deployment/docker-compose.production.yml diff --git a/docker-compose.yml b/deployment/docker-compose.yml similarity index 100% rename from docker-compose.yml rename to deployment/docker-compose.yml diff --git a/env.example b/deployment/env.example similarity index 100% rename from env.example rename to deployment/env.example diff --git a/requirements.compatible.txt b/deployment/requirements.compatible.txt similarity index 100% rename from requirements.compatible.txt rename to deployment/requirements.compatible.txt diff --git a/requirements.txt b/deployment/requirements.txt similarity index 100% rename from requirements.txt rename to deployment/requirements.txt diff --git a/requirements_new.txt b/deployment/requirements_new.txt similarity index 100% rename from requirements_new.txt rename to deployment/requirements_new.txt diff --git a/docs/DEPLOY_INSTRUCTIONS_RU.md b/docs/DEPLOY_INSTRUCTIONS_RU.md new file mode 100644 index 0000000..53205fa --- /dev/null +++ b/docs/DEPLOY_INSTRUCTIONS_RU.md @@ -0,0 +1,167 @@ +# 🚀 Инструкции по развертыванию MY Network Bootstrap Node + +## 📋 Что нужно сделать на сервере 2.58.65.188 + +### ✅ Шаг 1: Подключение к серверу +```bash +ssh service@2.58.65.188 +# Пароль: DMUEjmnh6mDs/qlzhpjDzQ +``` + +### ✅ Шаг 2: Запуск автоматического развертывания +```bash +# Переход в root +sudo su - + +# Запуск скрипта развертывания +chmod +x /tmp/auto_deploy.sh +bash /tmp/auto_deploy.sh +``` + +**⏳ Время выполнения: ~15-20 минут** + +### ✅ Шаг 3: Проверка результата +После завершения скрипта проверьте: + +```bash +# Статус сервисов +systemctl status my-network-bootstrap nginx docker + +# Проверка API +curl https://my-public-node-3.projscale.dev/api/my/health + +# Проверка портов (должен быть только 443) +netstat -tlnp | grep LISTEN + +# Проверка firewall +ufw status numbered +``` + +## 🎯 Что будет развернуто: + +### 🔧 **Базовая инфраструктура:** +- ✅ Ubuntu система обновлена +- ✅ Docker + Docker Compose установлены +- ✅ Python 3 + venv + зависимости +- ✅ MariaDB 11.2 (внутренний порт 3306) +- ✅ Redis 7 (внутренний порт 6379) + +### 🌐 **MY Network Bootstrap Node:** +- ✅ Основное приложение на порту 15100 (внутренний) +- ✅ Bootstrap конфигурация для всей сети +- ✅ REST API для управления сетью +- ✅ Веб-мониторинг с ASCII интерфейсом + +### 🔒 **Безопасность:** +- ✅ Nginx proxy только на порт 443 (HTTPS) +- ✅ SSL сертификат Let's Encrypt для my-public-node-3.projscale.dev +- ✅ UFW firewall - ТОЛЬКО SSH + 443 порт +- ✅ Fail2ban защита от атак +- ✅ Все внутренние порты заблокированы + +### 🛡️ **Cloudflare совместимость:** +- ✅ Настроены IP ranges для Cloudflare +- ✅ Real IP header обработка +- ✅ CORS headers для публичного API +- ✅ Rate limiting для разных endpoints + +## 📡 **Доступные API endpoints:** + +### 🌍 **Публичные (доступны всем):** +- **Health Check:** `https://my-public-node-3.projscale.dev/api/my/health` +- **Node Info:** `https://my-public-node-3.projscale.dev/api/my/node/info` +- **Bootstrap Config:** `https://my-public-node-3.projscale.dev/api/my/bootstrap/config` + +### 🔒 **Ограниченные (только localhost):** +- **Monitor Dashboard:** `https://my-public-node-3.projscale.dev/api/my/monitor/` + +## 🎮 **Для других узлов сети:** + +Другие узлы смогут подключаться к этому bootstrap узлу используя: + +```json +{ + "bootstrap_nodes": [ + { + "id": "bootstrap-primary", + "host": "my-public-node-3.projscale.dev", + "port": 443, + "ssl": true, + "public": true + } + ] +} +``` + +## 📊 **Мониторинг:** + +### 🔍 **Автоматический мониторинг:** +- ✅ Проверка каждые 2 минуты +- ✅ Логирование в `/opt/logs/bootstrap-monitor.log` +- ✅ Уведомления о критических проблемах + +### 📈 **Ручная проверка:** +```bash +# Логи сервиса +journalctl -u my-network-bootstrap -f + +# Системный мониторинг +tail -f /opt/logs/bootstrap-monitor.log + +# SSL статус +certbot certificates + +# Статистика nginx +tail -f /var/log/nginx/access.log +``` + +## 🆘 **Troubleshooting:** + +### ❌ **Если API недоступен:** +```bash +systemctl restart my-network-bootstrap nginx +curl -v https://my-public-node-3.projscale.dev/api/my/health +``` + +### ❌ **Если SSL не работает:** +```bash +certbot certificates +certbot renew --dry-run +systemctl reload nginx +``` + +### ❌ **Если firewall блокирует:** +```bash +ufw status numbered +# Проверить что порт 443 разрешен +``` + +## 📋 **Финальный чек-лист:** + +После развертывания должно быть: + +- [ ] ✅ `curl https://my-public-node-3.projscale.dev/api/my/health` возвращает 200 +- [ ] ✅ `curl https://my-public-node-3.projscale.dev/api/my/node/info` показывает информацию об узле +- [ ] ✅ `curl https://my-public-node-3.projscale.dev/api/my/bootstrap/config` возвращает конфигурацию +- [ ] ✅ `systemctl status my-network-bootstrap nginx docker` все сервисы active +- [ ] ✅ `ufw status` показывает только SSH и 443 порт +- [ ] ✅ `netstat -tlnp | grep :443` nginx слушает порт 443 +- [ ] ✅ SSL сертификат действителен (проверить в браузере) + +## 🎉 **Результат:** + +После успешного развертывания у вас будет: + +**🚀 Полностью функциональный MY Network Bootstrap Node** +- Доступен по HTTPS на my-public-node-3.projscale.dev +- Готов принимать подключения других узлов сети +- Защищен firewall + SSL + fail2ban +- Автоматический мониторинг и обслуживание +- Совместим с Cloudflare proxy + +**🌐 Готов стать основным узлом распределенной сети MY Network!** + +--- + +*Время развертывания: ~15-20 минут* +*Требования: Ubuntu 20.04+, root доступ, домен настроен* \ No newline at end of file diff --git a/docs/DOCKER_BUILD_FIX.md b/docs/DOCKER_BUILD_FIX.md new file mode 100644 index 0000000..430026d --- /dev/null +++ b/docs/DOCKER_BUILD_FIX.md @@ -0,0 +1,127 @@ +# Исправление ошибки сборки Docker Compose + +## Проблема +Система пыталась собрать и запустить сервис `web2-client`, который может отсутствовать на некоторых нодах, что приводило к ошибке: +``` +target web2-client: failed to solve: failed to read dockerfile: open Dockerfile: no such file or directory +``` + +## Решение + +Исправлены **ЧЕТЫРЕ** критические проблемы: + +### 1. Docker Compose исправления +В `docker-compose.production.yml`: +- Добавлен профиль для web2-client: `profiles: ["main-node"]` +- Удалена зависимость nginx на web2-client (nginx теперь зависит только от app) +- Удалена устаревшая строка `version: '3.8'` + +```yaml +web2-client: + profiles: ["main-node"] # Only build for main nodes + # ... остальная конфигурация + +nginx: + depends_on: + - app # Убрано: - web2-client +``` + +### 2. Умная логика сборки и запуска +Обновлен `setup_production_server.sh` с graceful fallback логикой: + +**Для основной ноды (main):** +- Сначала пытается собрать/запустить с профилем `main-node` (включая web2-client) +- Если не удается, fallback к основным сервисам: `app postgres redis` + +**Для обычной ноды (regular):** +- Сразу собирает/запускает только основные сервисы без web2-client + +### 3. Исправление Dockerfile зависимостей +**Проблема:** `ERROR: Cannot find command 'git' - do you have 'git' installed and in your PATH?` + +В [`Dockerfile.simple`](my-uploader-bot/Dockerfile.simple:13) добавлен git: +```dockerfile +RUN apt-get update && apt-get install -y \ + build-essential \ + curl \ + git \ # ✅ Добавлено для установки tonsdk из GitHub + ffmpeg \ + libmagic1 \ + libpq-dev \ + pkg-config \ + && rm -rf /var/lib/apt/lists/* +``` + +### 4. Исправление конфликта зависимостей Python +**Проблема:** `ERROR: Cannot install -r requirements.txt ... because these package versions have conflicting dependencies` + +**Две проблемы:** +1. `aiogram 3.13.0` требует `aiofiles~=23.2.1`, а указана `aiofiles==24.1.0` +2. [`Dockerfile.simple`](my-uploader-bot/Dockerfile.simple:23) копировал неправильный файл + +**✅ Решение:** +- В [`requirements.txt`](my-uploader-bot/requirements.txt:31) изменена версия aiofiles: +```txt +# Было: aiofiles==24.1.0 +# Стало: aiofiles==23.2.1 # Совместимо с aiogram +``` + +- В [`Dockerfile.simple`](my-uploader-bot/Dockerfile.simple:23) исправлен копируемый файл: +```dockerfile +# Было: COPY requirements_new.txt ./requirements.txt +# Стало: COPY requirements.txt ./requirements.txt +``` + +### 5. Обновленные управляющие скрипты +- `start.sh` - умный запуск с fallback логикой +- `rebuild.sh` - пересборка с учетом доступных модулей +- `systemd_start.sh` - обертка для systemd service + +## Поведение системы + +### Если web2-client модуль доступен: +```bash +✅ Запущены все сервисы основной ноды (включая web2-client) +``` + +### Если web2-client модуль недоступен: +```bash +⚠️ Web2-client недоступен, запускаем основные сервисы... +✅ Запущены основные сервисы (web2-client пропущен) +``` + +## Команды для проверки + +### Проверка статуса: +```bash +sudo /home/myuploader/uploader-bot/status.sh +``` + +### Ручной запуск с профилем: +```bash +# Основная нода с web2-client +docker-compose -f docker-compose.production.yml --profile main-node up -d + +# Только основные сервисы +docker-compose -f docker-compose.production.yml up -d app postgres redis +``` + +### Проверка доступных сервисов: +```bash +docker-compose -f docker-compose.production.yml config --services +``` + +## Типы нод + +### Main Node (основная) +- Полный стек: uploader-bot + converter-module + web2-client +- Web интерфейс доступен на главной странице +- API доступен через `/api/` + +### Regular Node (обычная) +- Основной стек: uploader-bot + converter-module +- Только API интерфейс на главной странице +- Меньше ресурсов, быстрее развертывание + +## Результат +Теперь система корректно работает независимо от наличия всех модулей и автоматически адаптируется к доступным компонентам. \ No newline at end of file diff --git a/docs/DOCKER_SETUP.md b/docs/DOCKER_SETUP.md new file mode 100644 index 0000000..4b6bd94 --- /dev/null +++ b/docs/DOCKER_SETUP.md @@ -0,0 +1,617 @@ +# 🚀 MY UPLOADER BOT - DOCKER SETUP + +Полное руководство по развертыванию MY Uploader Bot с использованием Docker + +## 📋 Содержание + +1. [Локальное тестирование](#локальное-тестирование) +2. [Production развертывание](#production-развертывание) +3. [Архитектура системы](#архитектура-системы) +4. [On-Demand Converter](#on-demand-converter) +5. [Мониторинг и логи](#мониторинг-и-логи) +6. [Безопасность](#безопасность) +7. [Troubleshooting](#troubleshooting) + +## 🔧 Локальное тестирование + +### Быстрый старт + +```bash +# 1. Клонирование репозитория +git clone +cd my-uploader-bot + +# 2. Создание .env файла +cp .env.example .env +# Отредактируйте .env файл с локальными настройками + +# 3. Запуск с Docker Compose +docker-compose -f docker-compose.new.yml up -d + +# 4. Проверка статуса +docker-compose -f docker-compose.new.yml ps +``` + +### Переменные окружения для локального тестирования + +Создайте файл `.env` со следующими переменными: + +```bash +# ============================================================================= +# MY UPLOADER BOT - ЛОКАЛЬНЫЕ НАСТРОЙКИ +# ============================================================================= + +# Environment +NODE_ENV=development +DEBUG=true + +# Database (PostgreSQL) +DATABASE_URL=postgresql://my_user:my_secure_password_123@localhost:5432/my_uploader_db +POSTGRES_HOST=localhost +POSTGRES_PORT=5432 +POSTGRES_DB=my_uploader_db +POSTGRES_USER=my_user +POSTGRES_PASSWORD=my_secure_password_123 + +# Redis +REDIS_URL=redis://localhost:6379/0 +REDIS_HOST=localhost +REDIS_PORT=6379 + +# Security Keys (генерируйте новые для production!) +SECRET_KEY=dev_secret_key_change_in_production_123456789 +JWT_SECRET=dev_jwt_secret_change_in_production_987654321 +ENCRYPTION_KEY=dev_encryption_key_32_chars_long! + +# MY Network Settings +MY_NETWORK_NODE_ID=local-dev-node-$(date +%s) +MY_NETWORK_PORT=15100 +MY_NETWORK_HOST=0.0.0.0 +MY_NETWORK_DOMAIN=localhost +MY_NETWORK_SSL_ENABLED=false + +# API Settings +API_HOST=0.0.0.0 +API_PORT=15100 +API_WORKERS=2 +MAX_UPLOAD_SIZE=50MB + +# Converter Settings (On-Demand) +CONVERTER_DOCKER_IMAGE=my-converter:latest +CONVERTER_SHARED_PATH=/shared/converter +CONVERTER_MAX_PARALLEL=2 +CONVERTER_TIMEOUT=300 + +# Logging +LOG_LEVEL=DEBUG +LOG_FORMAT=text + +# Monitoring (опционально) +GRAFANA_PASSWORD=admin123 +``` + +### Проверка локального развертывания + +```bash +# Проверка здоровья сервисов +curl http://localhost:15100/health +curl http://localhost:3000/health # web2-client + +# Проверка MY Network API +curl http://localhost:15100/api/my/bootstrap/config + +# Проверка converter image +docker images | grep my-converter + +# Просмотр логов +docker-compose -f docker-compose.new.yml logs -f app +``` + +## 🏭 Production развертывание + +### Автоматическое развертывание на пустом сервере + +**Требования:** +- Ubuntu 20.04+ / Debian 11+ / CentOS 8+ +- Минимум 2GB RAM, 2 CPU cores, 20GB диска +- Root доступ или sudo права +- Доменное имя, указывающее на сервер + +**Одной командой:** + +```bash +# Скачайте и запустите мастер-скрипт +curl -fsSL https://raw.githubusercontent.com/your-org/my-uploader-bot/main/setup_production_server.sh | sudo bash -s -- yourdomain.com +``` + +### Ручное развертывание (пошагово) + +#### 1. Подготовка сервера + +```bash +# Обновление системы +sudo apt update && sudo apt upgrade -y + +# Установка базовых пакетов +sudo apt install -y curl wget git unzip htop nano ufw fail2ban + +# Создание пользователя для сервиса +sudo useradd -m -s /bin/bash service +sudo usermod -aG sudo service +``` + +#### 2. Установка Docker + +```bash +# Установка Docker +curl -fsSL https://get.docker.com -o get-docker.sh +sudo sh get-docker.sh + +# Установка Docker Compose +sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose +sudo chmod +x /usr/local/bin/docker-compose + +# Добавление пользователя в группу docker +sudo usermod -aG docker service +``` + +#### 3. Клонирование проекта + +```bash +# Переключение на пользователя service +sudo su - service + +# Клонирование проекта +git clone /home/service/my-uploader-bot +cd /home/service/my-uploader-bot + +# Установка прав доступа +chmod +x scripts/*.sh +chmod +x *.sh +``` + +#### 4. Настройка окружения + +```bash +# Генерация production конфигурации +./scripts/setup_production_env.sh /home/service/my-uploader-bot yourdomain.com + +# Настройка дополнительных модулей +./scripts/setup_modules.sh /home/service/my-uploader-bot +``` + +#### 5. Сборка Docker образов + +```bash +# Сборка основного приложения и converter +docker-compose -f docker-compose.production.yml build + +# Сборка только converter image (для on-demand использования) +docker-compose -f docker-compose.production.yml --profile build-only build converter-build +``` + +#### 6. Настройка Nginx и SSL + +```bash +# Возврат к root для настройки системных сервисов +exit # выход из пользователя service + +# Установка Nginx и Certbot +sudo apt install -y nginx certbot python3-certbot-nginx + +# Настройка Nginx конфигурации +sudo ./scripts/create_nginx_config.sh /home/service/my-uploader-bot yourdomain.com service + +# Получение SSL сертификата +sudo certbot --nginx -d yourdomain.com --non-interactive --agree-tos --email admin@yourdomain.com +``` + +#### 7. Настройка Firewall + +```bash +# Базовая настройка UFW +sudo ufw default deny incoming +sudo ufw default allow outgoing + +# Разрешение необходимых портов +sudo ufw allow ssh +sudo ufw allow 80/tcp +sudo ufw allow 443/tcp + +# Включение firewall +sudo ufw --force enable +``` + +#### 8. Создание SystemD сервисов + +```bash +# Создание сервисов +sudo ./scripts/create_systemd_services.sh /home/service/my-uploader-bot service + +# Запуск сервисов +sudo systemctl start my-docker-compose +sudo systemctl start my-converter-builder +sudo systemctl start my-uploader-bot +sudo systemctl start my-network-bootstrap +sudo systemctl enable nginx +sudo systemctl restart nginx +``` + +### Проверка Production развертывания + +```bash +# Проверка HTTPS доступности +curl https://yourdomain.com/health + +# Проверка MY Network +curl https://yourdomain.com/api/my/bootstrap/config + +# Проверка web2-client +curl https://yourdomain.com/web/health + +# Проверка converter image +docker images | grep my-converter + +# Проверка SSL сертификата +openssl s_client -connect yourdomain.com:443 -servername yourdomain.com < /dev/null +``` + +## 🏗️ Архитектура системы + +```mermaid +graph TB + Client[👤 Client] --> LB[🌐 Nginx Load Balancer] + + LB --> App[🚀 MY Uploader Bot
Port: 15100] + LB --> Web[💻 Web2 Client
Port: 3000] + + App --> DB[(🗄️ PostgreSQL
Port: 5432)] + App --> Redis[(⚡ Redis
Port: 6379)] + + App --> MyNet[🌍 MY Network
Bootstrap Node] + + subgraph "🐳 Docker Network" + App + Web + DB + Redis + MyNet + ConvImg[🖼️ Converter Image
my-converter:latest] + end + + App -.->|On-Demand| ConvContainer1[🔄 Converter Container 1] + App -.->|On-Demand| ConvContainer2[🔄 Converter Container 2] + App -.->|On-Demand| ConvContainer3[🔄 Converter Container N] + + ConvImg -.->|Creates| ConvContainer1 + ConvImg -.->|Creates| ConvContainer2 + ConvImg -.->|Creates| ConvContainer3 + + ConvContainer1 -.->|Auto-Remove| X1[❌] + ConvContainer2 -.->|Auto-Remove| X2[❌] + ConvContainer3 -.->|Auto-Remove| X3[❌] + + subgraph "📊 Monitoring Stack" + Prom[📈 Prometheus
Port: 9090] + Graf[📊 Grafana
Port: 3001] + Loki[📋 Loki
Port: 3100] + PT[📝 Promtail] + end + + App --> Prom + Web --> Prom + + PT --> Loki + Graf --> Prom + Graf --> Loki + + LB --> Graf +``` + +### Компоненты системы + +| Компонент | Порт | Режим работы | Описание | +|-----------|------|-------------|----------| +| **MY Uploader Bot** | 15100 | Постоянный | Основное API приложение | +| **Web2 Client** | 3000 | Постоянный | Веб интерфейс | +| **PostgreSQL** | 5432 | Постоянный | Основная база данных | +| **Redis** | 6379 | Постоянный | Кеширование и очереди | +| **Nginx** | 80/443 | Постоянный | Reverse proxy + SSL | +| **Converter Module** | - | **On-Demand** | 🔄 Конвертер медиа файлов | +| **Prometheus** | 9090 | Постоянный | Сбор метрик | +| **Grafana** | 3001 | Постоянный | Дашборды мониторинга | +| **Loki** | 3100 | Постоянный | Централизованные логи | + +## 🔄 On-Demand Converter + +### Принцип работы + +Converter Module работает по принципу **on-demand контейнеров**: + +1. **Image собирается один раз** при установке системы +2. **MY Uploader Bot создает контейнеры** по мере поступления задач конвертации +3. **Контейнеры автоматически удаляются** после завершения задач +4. **Параллельная обработка** до N задач одновременно (настраивается) + +### Настройки converter в .env + +```bash +# Converter Settings +CONVERTER_DOCKER_IMAGE=my-converter:latest # Имя образа +CONVERTER_SHARED_PATH=/shared/converter # Общая папка для файлов +CONVERTER_MAX_PARALLEL=3 # Максимум параллельных задач +CONVERTER_TIMEOUT=300 # Таймаут задачи (секунды) +``` + +### Управление converter + +```bash +# Проверка готовности converter image +docker images | grep my-converter + +# Пересборка converter image +./rebuild_converter.sh + +# Просмотр активных converter контейнеров +docker ps | grep converter + +# Мониторинг логов converter заданий +docker logs -f + +# Принудительная очистка зависших контейнеров +docker container prune -f +``` + +### API endpoints для converter + +```bash +# Запуск задачи конвертации +POST /api/convert/start +{ + "file_id": "uuid", + "conversion_type": "video_to_mp4", + "options": {...} +} + +# Статус задачи конвертации +GET /api/convert/status/{task_id} + +# Отмена задачи +DELETE /api/convert/cancel/{task_id} + +# Список активных задач +GET /api/convert/active +``` + +### Преимущества on-demand архитектуры + +✅ **Экономия ресурсов** - converter потребляет ресурсы только при работе +✅ **Масштабируемость** - автоматическое создание контейнеров по нагрузке +✅ **Изоляция** - каждая задача выполняется в отдельном контейнере +✅ **Отказоустойчивость** - сбой одного контейнера не влияет на другие +✅ **Легкое обновление** - пересборка image без остановки основной системы + +## 📊 Мониторинг и логи + +### Доступ к мониторингу + +```bash +# Grafana Dashboard +https://yourdomain.com/grafana +# Логин: admin / пароль из .env + +# Prometheus Metrics +https://yourdomain.com/prometheus + +# Проверка логов +docker-compose -f docker-compose.production.yml logs -f app +journalctl -u my-uploader-bot -f +journalctl -u my-docker-compose -f +``` + +### Ключевые метрики + +- **Производительность**: Response time, throughput, error rate +- **Ресурсы**: CPU, Memory, Disk usage +- **MY Network**: Количество узлов, скорость репликации +- **База данных**: Подключения, запросы, производительность +- **Converter**: Активные задачи, время обработки, ошибки + +### Алерты + +Система автоматически создает алерты для: +- Высокая нагрузка на CPU (>80%) +- Недостаток памяти (<100MB свободно) +- Ошибки приложения (>5 за минуту) +- MY Network недоступен +- SSL сертификат истекает (<30 дней) +- Converter задачи зависают (>timeout) + +## 🔒 Безопасность + +### Безопасность сети + +```bash +# Проверка открытых портов +sudo netstat -tlnp | grep LISTEN + +# Проверка правил firewall +sudo ufw status verbose + +# Анализ попыток вторжения +sudo fail2ban-client status +``` + +### Обновления безопасности + +```bash +# Автоматические обновления безопасности +sudo apt install unattended-upgrades +sudo dpkg-reconfigure -plow unattended-upgrades + +# Регулярная ротация SSL сертификатов +sudo crontab -e +# Добавить: 0 12 * * * /usr/bin/certbot renew --quiet +``` + +### Backup стратегия + +```bash +# Backup базы данных +docker-compose -f docker-compose.production.yml exec postgres pg_dump -U my_user my_uploader_db > backup_$(date +%Y%m%d).sql + +# Backup конфигурации +tar -czf config_backup_$(date +%Y%m%d).tar.gz .env nginx/ ssl/ + +# Backup converter image +docker save my-converter:latest | gzip > converter_image_$(date +%Y%m%d).tar.gz + +# Автоматический backup (добавить в crontab) +0 2 * * * /home/service/my-uploader-bot/scripts/backup.sh +``` + +## 🔧 Troubleshooting + +### Частые проблемы + +#### 1. Приложение не запускается + +```bash +# Проверка логов +docker-compose -f docker-compose.production.yml logs app +journalctl -u my-uploader-bot -f + +# Проверка конфигурации +docker-compose -f docker-compose.production.yml config + +# Проверка переменных окружения +cat .env +``` + +#### 2. База данных недоступна + +```bash +# Проверка статуса PostgreSQL +docker-compose -f docker-compose.production.yml exec postgres pg_isready + +# Подключение к БД +docker-compose -f docker-compose.production.yml exec postgres psql -U my_user -d my_uploader_db + +# Проверка логов БД +docker-compose -f docker-compose.production.yml logs postgres +``` + +#### 3. SSL сертификат не работает + +```bash +# Проверка сертификата +sudo certbot certificates + +# Обновление сертификата +sudo certbot renew --dry-run + +# Проверка nginx конфигурации +sudo nginx -t +``` + +#### 4. MY Network недоступна + +```bash +# Проверка bootstrap узла +curl https://yourdomain.com/api/my/bootstrap/config + +# Проверка логов MY Network +docker-compose -f docker-compose.production.yml logs app | grep "MY Network" + +# Проверка сетевых подключений +docker network ls +docker network inspect my-uploader-bot_uploader_network +``` + +#### 5. Converter не работает + +```bash +# Проверка наличия image +docker images | grep my-converter + +# Пересборка converter image +./rebuild_converter.sh + +# Проверка активных converter контейнеров +docker ps | grep converter + +# Очистка зависших контейнеров +docker container prune -f + +# Проверка логов последних converter задач +docker logs $(docker ps -a | grep converter | head -1 | cut -d' ' -f1) +``` + +### Полезные команды + +```bash +# Полная перезагрузка системы +./stop_all_services.sh && ./start_all_services.sh + +# Обновление приложения +git pull +docker-compose -f docker-compose.production.yml pull +docker-compose -f docker-compose.production.yml up -d + +# Очистка неиспользуемых ресурсов +docker system prune -a + +# Мониторинг ресурсов в реальном времени +docker stats + +# Мониторинг converter активности +watch 'docker ps | grep converter' +``` + +### SystemD сервисы + +```bash +# Запуск всех сервисов +./start_all_services.sh + +# Остановка всех сервисов +./stop_all_services.sh + +# Проверка статуса всех сервисов +./check_services.sh + +# Пересборка converter image +./rebuild_converter.sh + +# Просмотр логов отдельных сервисов +journalctl -u my-uploader-bot -f +journalctl -u my-docker-compose -f +journalctl -u my-converter-builder -f +``` + +### Контакты поддержки + +- **GitHub Issues**: [repository-url]/issues +- **Documentation**: [repository-url]/wiki +- **MY Network**: https://my-network.dev + +--- + +## 📝 Дополнительные ресурсы + +- [Архитектура MY Network](docs/MY_NETWORK_ARCHITECTURE.md) +- [API Documentation](docs/API.md) +- [Development Guide](docs/DEVELOPMENT.md) +- [Security Guidelines](docs/SECURITY.md) +- [Converter Module Guide](docs/CONVERTER.md) + +--- + +**🎉 Поздравляем! MY Uploader Bot успешно развернут в production!** + +Система готова к работе с: +- ⚡ **On-demand конвертацией** медиа файлов +- 🔒 **Безопасностью корпоративного уровня** +- 📊 **Автоматическим мониторингом** +- 🚀 **Высокой производительностью** +- 🌍 **Распределенной MY Network** \ No newline at end of file diff --git a/DOCS_RU.md b/docs/DOCS_RU.md similarity index 100% rename from DOCS_RU.md rename to docs/DOCS_RU.md diff --git a/ENDPOINTS.md b/docs/ENDPOINTS.md similarity index 100% rename from ENDPOINTS.md rename to docs/ENDPOINTS.md diff --git a/docs/MANUAL_SSL_SETUP.md b/docs/MANUAL_SSL_SETUP.md new file mode 100644 index 0000000..56c662a --- /dev/null +++ b/docs/MANUAL_SSL_SETUP.md @@ -0,0 +1,98 @@ +# Ручная настройка SSL для MY Network Bootstrap Node + +## Проблема +Пользователь `service` не имеет sudo прав для настройки nginx и SSL сертификатов. + +## Решение +Необходимо выполнить команды от имени root. + +## Инструкция + +### 1. Подключение к серверу как root +```bash +ssh root@2.58.65.188 +``` + +### 2. Копирование скрипта +```bash +cp /home/service/setup_nginx_ssl.sh /root/ +chmod +x /root/setup_nginx_ssl.sh +``` + +### 3. Запуск настройки SSL +```bash +cd /root +./setup_nginx_ssl.sh +``` + +## Альтернативный способ - добавить service в sudoers + +### 1. Подключиться как root +```bash +ssh root@2.58.65.188 +``` + +### 2. Добавить service в sudoers +```bash +echo "service ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/service +``` + +### 3. Запустить скрипт от service +```bash +su - service +cd /home/service +sudo ./setup_nginx_ssl.sh +``` + +## Что делает скрипт setup_nginx_ssl.sh + +1. **Обновляет систему** и устанавливает nginx, certbot, ufw +2. **Настраивает firewall** (UFW): + - Разрешает SSH (22), HTTP (80), HTTPS (443) + - Блокирует остальные порты +3. **Получает SSL сертификат** от Let's Encrypt для домена my-public-node-3.projscale.dev +4. **Настраивает nginx**: + - HTTP -> HTTPS redirect + - Proxy для MY Network сервиса (порт 15100) + - Security headers + - Rate limiting + - CORS headers +5. **Настраивает автообновление** SSL сертификатов через cron +6. **Проверяет работоспособность** всех компонентов + +## Ожидаемый результат + +После выполнения скрипта MY Network Bootstrap Node будет доступен по HTTPS: + +- **https://my-public-node-3.projscale.dev** - основной сайт +- **https://my-public-node-3.projscale.dev/api/my/health** - health check +- **https://my-public-node-3.projscale.dev/api/my/bootstrap/config** - bootstrap конфигурация +- **https://my-public-node-3.projscale.dev/api/my/monitor/** - веб-мониторинг + +## Безопасность + +- ✅ SSL/TLS сертификат от Let's Encrypt +- ✅ HTTP -> HTTPS redirect +- ✅ Security headers (HSTS, X-Frame-Options, etc.) +- ✅ Rate limiting для API endpoints +- ✅ Firewall (UFW) с минимальными открытыми портами +- ✅ Автообновление SSL сертификатов + +## Проверка после установки + +```bash +# Проверка nginx +systemctl status nginx + +# Проверка MY Network сервиса +systemctl status my-network + +# Проверка SSL сертификата +curl -I https://my-public-node-3.projscale.dev + +# Проверка API +curl https://my-public-node-3.projscale.dev/api/my/health + +# Логи nginx +tail -f /var/log/nginx/access.log +tail -f /var/log/nginx/error.log \ No newline at end of file diff --git a/docs/MIGRATION_GUIDE.md b/docs/MIGRATION_GUIDE.md new file mode 100644 index 0000000..914b187 --- /dev/null +++ b/docs/MIGRATION_GUIDE.md @@ -0,0 +1,347 @@ +# Руководство по миграции на асинхронную архитектуру с Redis + +Это руководство поможет вам безопасно обновить существующую систему My Uploader Bot до новой асинхронной архитектуры с поддержкой Redis кэширования, сохранив полную совместимость с текущими данными и настройками. + +## ⚠️ ВАЖНО: Резервное копирование + +**Перед началом миграции обязательно создайте резервные копии:** + +```bash +# Остановите существующие контейнеры +docker-compose down + +# Создайте резервную копию базы данных +docker run --rm \ + -v my-uploader-bot_sqlStorage:/var/lib/mysql \ + -v $(pwd)/backup:/backup \ + mariadb:11.2 \ + mysqldump -h maria_db -u myuploader -p myuploader > /backup/database_backup_$(date +%Y%m%d_%H%M%S).sql + +# Создайте резервную копию файлов +cp -r /Storage /Storage_backup_$(date +%Y%m%d_%H%M%S) + +# Создайте резервную копию конфигурации +cp docker-compose.yml docker-compose.yml.backup +cp .env .env.backup +``` + +## Шаг 1: Обновление конфигурационных файлов + +### 1.1 Обновите docker-compose.yml + +Замените ваш текущий `docker-compose.yml` на совместимую версию: + +```bash +# Переименуйте существующий файл +mv docker-compose.yml docker-compose.yml.old + +# Скопируйте новую совместимую версию +cp docker-compose.compatible.yml docker-compose.yml +``` + +### 1.2 Обновите .env файл + +```bash +# Переименуйте существующий .env +mv .env .env.old + +# Скопируйте новую совместимую версию +cp .env.compatible .env + +# Перенесите ваши существующие настройки +# Отредактируйте .env и добавьте ваши текущие значения: +# - MYSQL_PASSWORD (ваш текущий пароль) +# - SECRET_KEY (ваш текущий ключ) +# - JWT_SECRET_KEY (ваш текущий JWT ключ) +# - Другие специфичные настройки +``` + +### 1.3 Обновите requirements.txt + +```bash +# Переименуйте существующий файл +mv requirements.txt requirements.txt.old + +# Скопируйте новую совместимую версию +cp requirements.compatible.txt requirements.txt +``` + +## Шаг 2: Добавление новых модулей + +### 2.1 Обновите core модули + +Замените существующие модули на совместимые версии: + +```bash +# Создайте резервные копии существующих модулей +mkdir -p app/core/backup +cp app/core/database.py app/core/backup/database.py.old +cp app/core/config.py app/core/backup/config.py.old + +# Используйте новые совместимые модули +cp app/core/database_compatible.py app/core/database.py +cp app/core/config_compatible.py app/core/config.py +``` + +### 2.2 Добавьте систему кэширования + +```bash +# Добавьте новый модуль кэширования +# Файл app/core/cache.py уже создан + +# Добавьте совместимые модели +cp app/core/models/base_compatible.py app/core/models/base.py +cp app/core/models/user_compatible.py app/core/models/user.py +cp app/core/models/content_compatible.py app/core/models/content.py +``` + +## Шаг 3: Постепенное обновление + +### 3.1 Запуск с Redis (рекомендуется) + +```bash +# Запустите только Redis для тестирования +docker-compose up -d redis + +# Проверьте, что Redis работает +docker-compose exec redis redis-cli ping +# Должно вернуть: PONG +``` + +### 3.2 Запуск основных сервисов + +```bash +# Запустите MariaDB +docker-compose up -d maria_db + +# Дождитесь готовности базы данных +docker-compose logs -f maria_db +# Ждите сообщения: "mysqld: ready for connections" + +# Запустите основное приложение +docker-compose up -d app + +# Проверьте логи +docker-compose logs -f app +``` + +### 3.3 Запуск дополнительных сервисов + +```bash +# Запустите остальные сервисы поочередно +docker-compose up -d indexer +docker-compose up -d ton_daemon +docker-compose up -d license_index +docker-compose up -d convert_process + +# Проверьте статус всех сервисов +docker-compose ps +``` + +## Шаг 4: Проверка работоспособности + +### 4.1 Проверка API + +```bash +# Проверьте основной API +curl http://localhost:15100/health + +# Проверьте подключение к базе данных +curl http://localhost:15100/api/v1/health/database + +# Проверьте Redis подключение +curl http://localhost:15100/api/v1/health/cache +``` + +### 4.2 Проверка существующих данных + +```bash +# Войдите в контейнер приложения +docker-compose exec app python3 -c " +from app.core.database_compatible import init_database, get_async_session +from app.core.models.user_compatible import User +import asyncio + +async def check_data(): + await init_database() + async with get_async_session() as session: + from sqlalchemy import select + result = await session.execute(select(User)) + users = result.scalars().all() + print(f'Found {len(users)} users in database') + +asyncio.run(check_data()) +" +``` + +### 4.3 Проверка кэширования + +```bash +# Проверьте работу Redis кэша +docker-compose exec app python3 -c " +from app.core.cache import init_cache, cache +import asyncio + +async def test_cache(): + await init_cache() + await cache.set('test_key', 'test_value', 60) + value = await cache.get('test_key') + print(f'Cache test: {value}') + +asyncio.run(test_cache()) +" +``` + +## Шаг 5: Настройка для продакшена + +### 5.1 Обновите переменные окружения + +В файле `.env` убедитесь, что настроены: + +```env +# Безопасность +SECRET_KEY=your-production-secret-key +JWT_SECRET_KEY=your-production-jwt-key + +# База данных +MYSQL_PASSWORD=your-secure-database-password + +# Redis (если используете внешний Redis) +REDIS_HOST=redis +REDIS_PASSWORD=your-redis-password # Если нужен + +# Кэширование +CACHE_ENABLED=true +REDIS_ENABLED=true + +# Производительность +DATABASE_POOL_SIZE=20 +DATABASE_MAX_OVERFLOW=30 +REDIS_MAX_CONNECTIONS=50 + +# Логирование +LOG_LEVEL=INFO +LOG_FORMAT=json +``` + +### 5.2 Настройте мониторинг + +```bash +# Добавьте мониторинг Redis +docker-compose exec redis redis-cli info memory + +# Добавьте мониторинг MariaDB +docker-compose exec maria_db mysql -u root -p -e "SHOW PROCESSLIST;" + +# Проверьте использование ресурсов +docker stats +``` + +## Откат изменений + +Если что-то пошло не так, вы можете быстро откатиться: + +```bash +# Остановите новые контейнеры +docker-compose down + +# Восстановите старые конфигурации +mv docker-compose.yml.old docker-compose.yml +mv .env.old .env +mv requirements.txt.old requirements.txt + +# Восстановите старые модули +cp app/core/backup/database.py.old app/core/database.py +cp app/core/backup/config.py.old app/core/config.py + +# Запустите старую версию +docker-compose up -d +``` + +## Производительность и мониторинг + +### Мониторинг Redis + +```bash +# Мониторинг использования памяти Redis +docker-compose exec redis redis-cli info memory + +# Мониторинг команд Redis +docker-compose exec redis redis-cli monitor + +# Статистика кэша +docker-compose exec redis redis-cli info stats +``` + +### Мониторинг MariaDB + +```bash +# Проверка подключений +docker-compose exec maria_db mysql -u root -p -e "SHOW STATUS LIKE 'Threads_connected';" + +# Проверка производительности +docker-compose exec maria_db mysql -u root -p -e "SHOW STATUS LIKE 'Queries';" + +# Размер базы данных +docker-compose exec maria_db mysql -u root -p -e " +SELECT + table_schema as 'Database', + ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) as 'Size (MB)' +FROM information_schema.tables +WHERE table_schema = 'myuploader' +GROUP BY table_schema; +" +``` + +## Возможные проблемы и решения + +### Проблема: Redis не запускается + +```bash +# Проверьте порты +netstat -tulpn | grep 6379 + +# Проверьте логи Redis +docker-compose logs redis + +# Очистите данные Redis если нужно +docker volume rm my-uploader-bot_redis_data +``` + +### Проблема: Ошибки подключения к базе данных + +```bash +# Проверьте статус MariaDB +docker-compose exec maria_db mysqladmin -u root -p status + +# Проверьте переменные окружения +docker-compose exec app env | grep MYSQL + +# Пересоздайте подключение +docker-compose restart app +``` + +### Проблема: Высокое использование памяти + +```bash +# Настройте лимиты Redis в .env +REDIS_MAX_CONNECTIONS=30 +DATABASE_POOL_SIZE=10 + +# Перезапустите сервисы +docker-compose restart +``` + +## Заключение + +После успешной миграции ваша система получит: + +1. ✅ **Асинхронную архитектуру** - лучшая производительность +2. ✅ **Redis кэширование** - быстрый доступ к данным +3. ✅ **Обратная совместимость** - все данные сохранены +4. ✅ **Улучшенный мониторинг** - больше метрик +5. ✅ **Масштабируемость** - готовность к росту нагрузки + +Система остается полностью совместимой с существующими данными и конфигурациями, но получает современную асинхронную архитектуру и кэширование для лучшей производительности. + +**Рекомендация**: Проводите миграцию в нерабочее время и тщательно тестируйте каждый шаг. \ No newline at end of file diff --git a/docs/MY_ARCHITECTURE.md b/docs/MY_ARCHITECTURE.md new file mode 100644 index 0000000..440f1af --- /dev/null +++ b/docs/MY_ARCHITECTURE.md @@ -0,0 +1,625 @@ +# MY Network Architecture Specification + +## Архитектурный Обзор + +MY Network представляет собой многоуровневую архитектуру overlay протокола, интегрированную с существующей системой my-uploader-bot без нарушения её функциональности. + +## Overlay Architecture Diagram + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ MY Network Layer │ +├─────────────────────────────────────────────────────────────────┤ +│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ +│ │ P2P Manager │ │ Consensus │ │ Replication │ │ +│ │ │ │ Engine │ │ Manager │ │ +│ └─────────────┘ └─────────────┘ └─────────────┘ │ +├─────────────────────────────────────────────────────────────────┤ +│ Integration Layer │ +├─────────────────────────────────────────────────────────────────┤ +│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ +│ │ Content API │ │ Storage API │ │ Auth API │ │ +│ │ (Existing) │ │ (Existing) │ │ (Existing) │ │ +│ └─────────────┘ └─────────────┘ └─────────────┘ │ +├─────────────────────────────────────────────────────────────────┤ +│ Core Data Layer │ +├─────────────────────────────────────────────────────────────────┤ +│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ +│ │StoredContent│ │EncryptionKey│ │ UserContent │ │ +│ │ Model │ │ Model │ │ Model │ │ +│ └─────────────┘ └─────────────┘ └─────────────┘ │ +└─────────────────────────────────────────────────────────────────┘ +``` + +## Интеграция с Существующей StoredContent Моделью + +### Расширение StoredContent для MY Network + +```python +# Новые поля для MY Network (добавляются через миграцию) +class StoredContentExtension: + # MY Network specific fields + my_network_enabled = Column(Boolean, default=False) + replica_count = Column(Integer, default=0) + replication_status = Column(String(32), default="none") + consensus_achieved = Column(Boolean, default=False) + + # Peer information + replicated_on_peers = Column(ARRAY(String), default=list) + last_sync_timestamp = Column(DateTime, nullable=True) + + # Network metadata + network_metadata = Column(JSONB, default=dict) +``` + +### Состояния Контента и Их Связи + +#### 1. Encrypted Content State +```python +# Зашифрованный контент в MY Network +encrypted_content = StoredContent( + hash="sha256:abc123...", + encrypted=True, + encryption_key_id="uuid-key-id", + content_type="audio", + my_network_enabled=True +) +``` + +#### 2. Decrypted Content State (через decrypted_content_id) +```python +# Расшифрованная версия связана через специальное поле +decrypted_content = StoredContent( + hash="sha256:def456...", + encrypted=False, + original_encrypted_id=encrypted_content.id, # Обратная связь + content_type="audio", + my_network_enabled=True +) + +# В encrypted_content добавляется: +encrypted_content.decrypted_content_id = decrypted_content.id +``` + +#### 3. Preview Content State +```python +# Превью версия для публичного доступа +preview_content = StoredContent( + hash="sha256:ghi789...", + encrypted=False, + content_type="audio", + file_size=small_size, # Урезанная версия + tags=["preview"], + parent_content_id=encrypted_content.id, # Связь с оригиналом + my_network_enabled=True +) +``` + +### Content State Relationship Model + +```sql +-- Новая таблица для управления связями контента +CREATE TABLE content_relationships ( + id UUID PRIMARY KEY, + parent_content_id UUID REFERENCES stored_content(id), + child_content_id UUID REFERENCES stored_content(id), + relationship_type VARCHAR(32) NOT NULL, -- 'encrypted', 'decrypted', 'preview' + created_at TIMESTAMP DEFAULT NOW(), + + UNIQUE(parent_content_id, child_content_id, relationship_type) +); + +-- Индексы для производительности +CREATE INDEX idx_content_rel_parent ON content_relationships(parent_content_id); +CREATE INDEX idx_content_rel_child ON content_relationships(child_content_id); +CREATE INDEX idx_content_rel_type ON content_relationships(relationship_type); +``` + +## Алгоритмы Репликации Всех Состояний + +### 1. Multi-State Replication Algorithm + +```python +class ContentStateReplicator: + async def replicate_content_group(self, content_group: ContentGroup): + """ + Реплицирует группу связанных состояний контента + """ + # Шаг 1: Определить все связанные состояния + states = await self.discover_content_states(content_group.root_id) + + # Шаг 2: Проверить целостность связей + await self.verify_state_relationships(states) + + # Шаг 3: Создать план репликации + replication_plan = await self.create_replication_plan(states) + + # Шаг 4: Выполнить репликацию по плану + for batch in replication_plan.batches: + await self.replicate_batch(batch) + await self.verify_batch_integrity(batch) + + # Шаг 5: Обновить метаданные о репликации + await self.update_replication_metadata(content_group, states) +``` + +### 2. State Discovery Algorithm + +```python +async def discover_content_states(root_content_id: str) -> List[ContentState]: + """ + Обнаруживает все связанные состояния контента + """ + states = [] + visited = set() + + # BFS поиск всех связанных состояний + queue = [root_content_id] + + while queue: + content_id = queue.pop(0) + if content_id in visited: + continue + + visited.add(content_id) + content = await StoredContent.get_by_id(content_id) + + if not content: + continue + + states.append(ContentState( + content=content, + relationships=await self.get_relationships(content_id) + )) + + # Добавить связанные состояния в очередь + relationships = await self.get_relationships(content_id) + for rel in relationships: + if rel.child_content_id not in visited: + queue.append(rel.child_content_id) + + return states +``` + +### 3. Atomic State Replication + +```python +class AtomicStateReplication: + async def replicate_state_group(self, states: List[ContentState], + target_peers: List[PeerNode]): + """ + Атомарная репликация группы состояний + """ + transaction_id = str(uuid4()) + + try: + # Phase 1: Prepare - подготовка к репликации + await self.prepare_replication(transaction_id, states, target_peers) + + # Phase 2: Transfer - передача данных + for state in states: + await self.transfer_state(state, target_peers, transaction_id) + + # Phase 3: Verify - проверка целостности + verification_results = await self.verify_replicated_states( + states, target_peers, transaction_id + ) + + # Phase 4: Commit or Abort + if all(verification_results): + await self.commit_replication(transaction_id, target_peers) + else: + await self.abort_replication(transaction_id, target_peers) + raise ReplicationError("State verification failed") + + except Exception as e: + await self.cleanup_failed_replication(transaction_id, target_peers) + raise e +``` + +## MY Network Service Layer + +### Service Component Architecture + +```python +# MY Network Service Manager +class MYNetworkService: + def __init__(self): + self.p2p_manager = P2PManager() + self.consensus_engine = ConsensusEngine() + self.replication_manager = ReplicationManager() + self.sync_coordinator = SyncCoordinator() + self.content_discovery = ContentDiscoveryService() + + async def start_service(self): + """Запуск MY Network сервиса""" + await self.p2p_manager.initialize() + await self.consensus_engine.start() + await self.replication_manager.start() + await self.sync_coordinator.start() + + # Регистрация в сети + await self.register_node() + + async def register_node(self): + """Регистрация ноды в MY Network""" + node_info = { + "node_id": self.get_node_id(), + "address": self.get_public_address(), + "capabilities": self.get_node_capabilities(), + "content_stats": await self.get_content_statistics() + } + + await self.p2p_manager.announce_node(node_info) +``` + +### P2P Communication Layer + +```python +class P2PManager: + def __init__(self): + self.peers = {} + self.message_handlers = {} + self.connection_pool = ConnectionPool() + + async def handle_peer_message(self, peer_id: str, message: dict): + """Обработка сообщений от пиров""" + msg_type = message.get("type") + handler = self.message_handlers.get(msg_type) + + if handler: + await handler(peer_id, message) + else: + logger.warning(f"Unknown message type: {msg_type}") + + async def broadcast_content_announcement(self, content: StoredContent): + """Анонс нового контента в сети""" + announcement = { + "type": "content_announcement", + "content_hash": content.hash, + "content_type": content.content_type, + "encrypted": content.encrypted, + "file_size": content.file_size, + "timestamp": datetime.utcnow().isoformat() + } + + # Отправка всем активным пирам + for peer_id in self.get_active_peers(): + await self.send_message(peer_id, announcement) +``` + +### Consensus Engine Implementation + +```python +class ConsensusEngine: + def __init__(self, min_quorum: int = 3): + self.min_quorum = min_quorum + self.pending_votes = {} + self.consensus_results = {} + + async def propose_content(self, content_hash: str) -> bool: + """Предложение контента для консенсуса""" + proposal_id = str(uuid4()) + + proposal = { + "id": proposal_id, + "content_hash": content_hash, + "proposer": self.node_id, + "timestamp": datetime.utcnow(), + "votes": {}, + "status": "pending" + } + + self.pending_votes[proposal_id] = proposal + + # Отправка предложения пирам + await self.broadcast_proposal(proposal) + + # Ожидание консенсуса с таймаутом + result = await self.wait_for_consensus(proposal_id, timeout=30) + return result + + async def vote_on_proposal(self, proposal_id: str, vote: bool): + """Голосование по предложению""" + if proposal_id not in self.pending_votes: + return False + + proposal = self.pending_votes[proposal_id] + proposal["votes"][self.node_id] = { + "vote": vote, + "timestamp": datetime.utcnow(), + "signature": await self.sign_vote(proposal_id, vote) + } + + # Проверка достижения консенсуса + await self.check_consensus(proposal_id) +``` + +## Content Discovery & Routing + +### Distributed Hash Table (DHT) для Content Discovery + +```python +class ContentDHT: + def __init__(self, node_id: str): + self.node_id = node_id + self.routing_table = {} + self. content_index = {} + + async def announce_content(self, content_hash: str, content_info: dict): + """Анонс контента в DHT""" + key_hash = self.hash_key(content_hash) + responsible_nodes = await self.find_responsible_nodes(key_hash) + + for node in responsible_nodes: + await self.store_content_info(node, content_hash, content_info) + + async def find_content(self, content_hash: str) -> List[PeerInfo]: + """Поиск нод с контентом""" + key_hash = self.hash_key(content_hash) + responsible_nodes = await self.find_responsible_nodes(key_hash) + + peers_with_content = [] + for node in responsible_nodes: + content_info = await self.get_content_info(node, content_hash) + if content_info: + peers_with_content.extend(content_info.get("peers", [])) + + return peers_with_content +``` + +### Smart Content Routing + +```python +class ContentRouter: + def __init__(self): + self.peer_metrics = {} + self.content_popularity = {} + + async def find_optimal_peers(self, content_hash: str, + count: int = 3) -> List[PeerInfo]: + """Поиск оптимальных пиров для загрузки""" + available_peers = await self.content_dht.find_content(content_hash) + + # Сортировка по метрикам производительности + scored_peers = [] + for peer in available_peers: + score = await self.calculate_peer_score(peer, content_hash) + scored_peers.append((peer, score)) + + # Возврат топ пиров + scored_peers.sort(key=lambda x: x[1], reverse=True) + return [peer for peer, score in scored_peers[:count]] + + async def calculate_peer_score(self, peer: PeerInfo, + content_hash: str) -> float: + """Вычисление оценки пира""" + metrics = self.peer_metrics.get(peer.node_id, {}) + + # Факторы оценки + latency_score = 1.0 / max(metrics.get("avg_latency", 1), 0.01) + bandwidth_score = metrics.get("bandwidth", 1.0) + reliability_score = metrics.get("uptime", 0.5) + reputation_score = peer.reputation_score + + # Взвешенная оценка + total_score = ( + latency_score * 0.3 + + bandwidth_score * 0.3 + + reliability_score * 0.2 + + reputation_score * 0.2 + ) + + return total_score +``` + +## Monitoring & Health System + +### Node Health Monitoring + +```python +class NodeHealthMonitor: + def __init__(self): + self.health_metrics = {} + self.alert_thresholds = { + "cpu_usage": 80.0, + "memory_usage": 85.0, + "disk_usage": 90.0, + "network_latency": 1000.0, # ms + "peer_count": 3 # minimum + } + + async def collect_health_metrics(self) -> dict: + """Сбор метрик здоровья ноды""" + return { + "cpu_usage": await self.get_cpu_usage(), + "memory_usage": await self.get_memory_usage(), + "disk_usage": await self.get_disk_usage(), + "network_latency": await self.measure_network_latency(), + "peer_count": len(await self.get_active_peers()), + "sync_status": await self.get_sync_status(), + "timestamp": datetime.utcnow().isoformat() + } + + async def check_health_alerts(self, metrics: dict): + """Проверка критических состояний""" + alerts = [] + + for metric, value in metrics.items(): + threshold = self.alert_thresholds.get(metric) + if threshold and value > threshold: + alerts.append({ + "metric": metric, + "value": value, + "threshold": threshold, + "severity": "critical" if value > threshold * 1.2 else "warning" + }) + + if alerts: + await self.send_health_alerts(alerts) +``` + +### Performance Analytics + +```python +class PerformanceAnalyzer: + def __init__(self): + self.metrics_storage = MetricsStorage() + + async def analyze_replication_performance(self) -> dict: + """Анализ производительности репликации""" + recent_replications = await self.get_recent_replications(hours=24) + + analysis = { + "total_replications": len(recent_replications), + "success_rate": self.calculate_success_rate(recent_replications), + "average_time": self.calculate_average_time(recent_replications), + "throughput": self.calculate_throughput(recent_replications), + "failed_replications": self.get_failed_replications(recent_replications) + } + + return analysis + + async def generate_performance_report(self) -> dict: + """Генерация отчета о производительности""" + return { + "network_performance": await self.analyze_network_performance(), + "replication_performance": await self.analyze_replication_performance(), + "consensus_performance": await self.analyze_consensus_performance(), + "content_distribution": await self.analyze_content_distribution(), + "peer_performance": await self.analyze_peer_performance() + } +``` + +## Security Architecture + +### Multi-Layer Security Model + +``` +┌─────────────────────────────────────────┐ +│ Application Security │ <- Existing auth & validation +├─────────────────────────────────────────┤ +│ Network Security │ <- MY Network specific +├─────────────────────────────────────────┤ +│ Transport Security │ <- TLS/mTLS +├─────────────────────────────────────────┤ +│ Content Security │ <- Encryption & integrity +└─────────────────────────────────────────┘ +``` + +### Network Security Implementation + +```python +class NetworkSecurity: + def __init__(self): + self.node_keypair = self.load_or_generate_keypair() + self.trusted_nodes = set() + self.blacklisted_nodes = set() + + async def verify_peer_identity(self, peer_id: str, + signature: str, message: bytes) -> bool: + """Проверка подлинности пира""" + public_key = await self.get_peer_public_key(peer_id) + if not public_key: + return False + + return await self.verify_signature(public_key, signature, message) + + async def encrypt_message(self, message: bytes, + recipient_public_key: bytes) -> bytes: + """Шифрование сообщения для получателя""" + # Используем ECIES для асимметричного шифрования + encrypted = await self.ecies_encrypt(message, recipient_public_key) + return encrypted + + async def validate_content_integrity(self, content_hash: str, + content_data: bytes) -> bool: + """Проверка целостности контента""" + calculated_hash = hashlib.sha256(content_data).hexdigest() + return calculated_hash == content_hash +``` + +## Scalability Considerations + +### Horizontal Scaling Strategies + +1. **Sharding по Content Hash** + - Контент распределяется по нодам на основе хеша + - Consistent hashing для равномерного распределения + - Автоматическое перебалансирование при изменении топологии + +2. **Hierarchical Network Structure** + - Bootstrap ноды как суперноды + - Региональные кластеры + - Edge ноды для локального кеширования + +3. **Adaptive Replication** + - Динамическое изменение количества реплик + - Репликация популярного контента на больше нод + - Удаление неиспользуемого контента + +### Resource Management + +```python +class ResourceManager: + def __init__(self): + self.storage_limits = {} + self.bandwidth_limits = {} + self.connection_limits = {} + + async def allocate_resources(self, operation_type: str, + resource_requirements: dict) -> bool: + """Выделение ресурсов для операции""" + if not await self.check_available_resources(resource_requirements): + return False + + await self.reserve_resources(operation_type, resource_requirements) + return True + + async def optimize_resource_usage(self): + """Оптимизация использования ресурсов""" + # Анализ текущего использования + usage_stats = await self.get_resource_usage_stats() + + # Определение возможностей для оптимизации + optimizations = await self.identify_optimizations(usage_stats) + + # Применение оптимизаций + for optimization in optimizations: + await self.apply_optimization(optimization) +``` + +## Disaster Recovery & Fault Tolerance + +### Multi-Level Fault Tolerance + +```python +class FaultToleranceManager: + async def handle_node_failure(self, failed_node_id: str): + """Обработка отказа ноды""" + # 1. Обновление routing table + await self.remove_failed_node(failed_node_id) + + # 2. Перенаправление трафика + await self.reroute_traffic_from_failed_node(failed_node_id) + + # 3. Восстановление реплик + lost_content = await self.identify_lost_content(failed_node_id) + await self.restore_content_replicas(lost_content) + + # 4. Уведомление сети об отказе + await self.broadcast_node_failure(failed_node_id) + + async def restore_content_replicas(self, lost_content: List[str]): + """Восстановление потерянных реплик контента""" + for content_hash in lost_content: + # Поиск существующих реплик + available_replicas = await self.find_content_replicas(content_hash) + + if len(available_replicas) < self.min_replica_count: + # Создание дополнительных реплик + target_nodes = await self.select_replication_targets(content_hash) + await self.replicate_content(content_hash, target_nodes) +``` + +Эта архитектура обеспечивает надежную, масштабируемую и безопасную распределенную систему для репликации всех состояний контента с сохранением существующей функциональности системы. \ No newline at end of file diff --git a/docs/MY_MONITORING.md b/docs/MY_MONITORING.md new file mode 100644 index 0000000..91e8649 --- /dev/null +++ b/docs/MY_MONITORING.md @@ -0,0 +1,1052 @@ +# MY Network Monitoring System + +## Обзор Системы Мониторинга + +MY Network Monitoring System представляет собой комплексную систему мониторинга с ASCII-арт интерфейсом в хакерском стиле, API endpoints для мониторинга, веб-интерфейс и интеграцию с Telegram ботом. + +## ASCII-арт Интерфейс в Хакерском Стиле + +### 1. Terminal Dashboard + +```python +class HackerStyleTerminalUI: + def __init__(self): + self.screen_width = 120 + self.screen_height = 40 + self.refresh_rate = 1.0 # секунды + + def render_main_dashboard(self, node_status: dict) -> str: + """Главная панель мониторинга""" + + ascii_art = f""" +╔════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗ +║ ███╗ ███╗██╗ ██╗ ███╗ ██╗███████╗████████╗██╗ ██╗ ██████╗ ██████╗ ██╗ ██╗ ║ +║ ████╗ ████║╚██╗ ██╔╝ ████╗ ██║██╔════╝╚══██╔══╝██║ ██║██╔═══██╗██╔══██╗██║ ██╔╝ ║ +║ ██╔████╔██║ ╚████╔╝ ██╔██╗ ██║█████╗ ██║ ██║ █╗ ██║██║ ██║██████╔╝█████╔╝ ║ +║ ██║╚██╔╝██║ ╚██╔╝ ██║╚██╗██║██╔══╝ ██║ ██║███╗██║██║ ██║██╔══██╗██╔═██╗ ║ +║ ██║ ╚═╝ ██║ ██║ ██║ ╚████║███████╗ ██║ ╚███╔███╔╝╚██████╔╝██║ ██║██║ ██╗ ║ +║ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═══╝╚══════╝ ╚═╝ ╚══╝╚══╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ║ +║ ║ +║ Node ID: {node_status['node_id'][:16]}... Status: {self.get_status_indicator(node_status)} ║ +║ Uptime: {self.format_uptime(node_status['uptime'])} Network: ONLINE ║ +╠════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣ +║ ┌─ NETWORK STATUS ─────────────────────┐ ┌─ CONTENT METRICS ──────────────────┐ ┌─ SYSTEM RESOURCES ──────────────┐ ║ +║ │ Peers Connected: {node_status['peer_count']:>3} │ │ Total Content: {node_status['content_count']:>6} │ │ CPU Usage: {self.render_bar(node_status['cpu_usage'], 10)} │ ║ +║ │ Active Connections: {node_status.get('active_connections', 0):>3} │ │ Synced Today: {node_status.get('synced_today', 0):>7} │ │ Memory: {self.render_bar(node_status['memory_usage'], 13)} │ ║ +║ │ Network Bandwidth: {node_status.get('bandwidth', '0 MB/s'):>8} │ │ Replication Rate: {node_status.get('replication_rate', '0/s'):>4} │ │ Disk: {self.render_bar(node_status['disk_usage'], 15)} │ ║ +║ │ Consensus Participation: {node_status.get('consensus_rate', '0%'):>3} │ │ Failed Syncs: {node_status.get('failed_syncs', 0):>6} │ │ Network I/O: {node_status.get('network_io', '0 KB/s'):>8} │ ║ +║ └─────────────────────────────────────┘ └────────────────────────────────────┘ └─────────────────────────────────┘ ║ +║ ║ +║ ┌─ RECENT ACTIVITY ────────────────────────────────────────────────────────────────────────────────────────────┐ ║ +║ │ {self.format_recent_activities(node_status.get('recent_activities', []))} │ ║ +║ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ ║ +║ ║ +║ ┌─ PEER CONNECTIONS ───────────────────────────────────────────────────────────────────────────────────────────┐ ║ +║ │ {self.format_peer_connections(node_status.get('peer_connections', []))} │ ║ +║ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ ║ +║ ║ +║ Commands: [S]ync | [P]eers | [C]ontent | [L]ogs | [Q]uit Last Update: {datetime.now().strftime('%H:%M:%S')} ║ +╚════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝ + """ + return ascii_art + + def render_bar(self, percentage: float, width: int) -> str: + """Рендер прогресс-бара в ASCII""" + filled_width = int((percentage / 100) * width) + bar = "█" * filled_width + "░" * (width - filled_width) + return f"{bar} {percentage:>5.1f}%" + + def get_status_indicator(self, node_status: dict) -> str: + """Индикатор статуса ноды""" + if node_status.get('is_healthy', True): + return "🟢 HEALTHY" + elif node_status.get('has_warnings', False): + return "🟡 WARNING" + else: + return "🔴 CRITICAL" +``` + +### 2. Network Topology Visualization + +```python +def render_network_topology(self, network_data: dict) -> str: + """ASCII визуализация топологии сети""" + + topology_art = f""" +┌─ MY NETWORK TOPOLOGY ──────────────────────────────────────────────────────────────────────────────────┐ +│ │ +│ ┌─────────────┐ │ +│ ┌──│ Bootstrap-1 │──┐ │ +│ │ └─────────────┘ │ │ +│ │ │ │ +│ ┌─────────────┴──┐ ┌──┴─────────────┐ │ +│ │ Regional-EU │ │ Regional-US │ │ +│ └─────────────┬──┘ └──┬─────────────┘ │ +│ │ │ │ +│ ┌────────────────────────┼─────────────────┼────────────────────────┐ │ +│ │ │ │ │ │ +│ ┌────▼───┐ ┌───▼───┐ ┌───▼───┐ ┌───▼────┐ │ +│ │ Node-A │────────────────│ Node-B│─────────│ Node-C│────────────────│ Node-D │ │ +│ └────────┘ └───────┘ └───────┘ └────────┘ │ +│ │ │ │ │ │ +│ │ ┌──────────────┴─────────────────┴──────────────┐ │ │ +│ │ │ │ │ │ +│ ┌────▼───┐ ┌───▼───┐ ┌───▼───┐ ┌───▼────┐ │ +│ │ Node-E │ │ Node-F│ │ Node-G│ │ Node-H │ │ +│ └────────┘ └───────┘ └───────┘ └────────┘ │ +│ │ +│ Legend: ━━━ High Bandwidth │ ─── Standard │ ╬╬╬ Consensus Link │ ░░░ Sync Active │ +│ │ +│ Network Stats: │ +│ • Total Nodes: {network_data.get('total_nodes', 0)} │ +│ • Active Connections: {network_data.get('active_connections', 0)} │ +│ • Average Latency: {network_data.get('avg_latency', '0ms')} │ +│ • Network Health: {network_data.get('health_score', '0%')} │ +└────────────────────────────────────────────────────────────────────────────────────────────────────┘ + """ + return topology_art + +def render_matrix_rain_effect(self) -> str: + """Matrix-style rain effect для заставки""" + + matrix_art = """ + ╔═══════════════════════════════════════════════════════════════════════════════════════════════════╗ + ║ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ║ + ║ ░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░ ║ + ║ ░░█░░░░█░░█░░░░█░░░░█░░█░░░░█░░░░█░░█░░░░█░░░░█░░█░░░░█░░░░█░░█░░░░█░░░░█░░█░░░░█░░░░█░░█░░░░█░ ║ + ║ █░░█░█░░█░░█░█░░█░█░░█░░█░█░░█░█░░█░░█░█░░█░█░░█░░█░█░░█░█░░█░░█░█░░█░█░░█░░█░█░░█░█░░█░░█░█░ ║ + ║ ░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░ ║ + ║ ░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░ ║ + ║ ║ + ║ ╔══════════════════════════════════════════╗ ║ + ║ ║ INITIALIZING MY NETWORK MONITORING... ║ ║ + ║ ║ ║ ║ + ║ ║ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░░░░░░░░░ ║ ║ + ║ ║ ║ ║ + ║ ║ Loading quantum encryption protocols... ║ ║ + ║ ║ Establishing secure P2P connections... ║ ║ + ║ ║ Synchronizing with blockchain nodes... ║ ║ + ║ ╚══════════════════════════════════════════╝ ║ + ║ ║ + ║ ░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░ ║ + ║ ░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░ ║ + ║ █░░█░█░░█░░█░█░░█░█░░█░░█░█░░█░█░░█░░█░█░░█░█░░█░░█░█░░█░█░░█░░█░█░░█░█░░█░░█░█░░█░█░░█░░█░█░ ║ + ║ ░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░ ║ + ║ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ║ + ╚═══════════════════════════════════════════════════════════════════════════════════════════════════╝ + """ + return matrix_art +``` + +### 3. Content Flow Visualization + +```python +def render_content_flow(self, flow_data: dict) -> str: + """Визуализация потока контента в реальном времени""" + + flow_art = f""" +┌─ CONTENT FLOW MONITOR ─────────────────────────────────────────────────────────────────────────────────┐ +│ │ +│ 📥 INCOMING 🔄 PROCESSING 📤 OUTGOING │ +│ │ +│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ +│ │ Node-A │════════════════▶│ THIS-NODE │════════════════▶│ Node-B │ │ +│ │ {flow_data.get('incoming', {}).get('node_a', '0 KB/s'):>11} │ │ {flow_data.get('processing', '0 ops/s'):>11} │ │ {flow_data.get('outgoing', {}).get('node_b', '0 KB/s'):>11} │ │ +│ └─────────────┘ └─────────────┘ └─────────────┘ │ +│ ║ ║ ║ │ +│ ▼ ▼ ▼ │ +│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ +│ │ Node-C │════════════════▶│ QUEUE │════════════════▶│ Node-D │ │ +│ │ {flow_data.get('incoming', {}).get('node_c', '0 KB/s'):>11} │ │ {flow_data.get('queue_size', '0 items'):>11} │ │ {flow_data.get('outgoing', {}).get('node_d', '0 KB/s'):>11} │ │ +│ └─────────────┘ └─────────────┘ └─────────────┘ │ +│ ║ ║ ║ │ +│ ▼ ▼ ▼ │ +│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ +│ │ Node-E │════════════════▶│ STORAGE │════════════════▶│ Node-F │ │ +│ │ {flow_data.get('incoming', {}).get('node_e', '0 KB/s'):>11} │ │ {flow_data.get('storage_ops', '0 ops/s'):>11} │ │ {flow_data.get('outgoing', {}).get('node_f', '0 KB/s'):>11} │ │ +│ └─────────────┘ └─────────────┘ └─────────────┘ │ +│ │ +│ Flow Statistics: │ +│ • Total Throughput: {flow_data.get('total_throughput', '0 MB/s')} │ +│ • Peak Bandwidth: {flow_data.get('peak_bandwidth', '0 MB/s')} │ +│ • Average Latency: {flow_data.get('avg_latency', '0ms')} │ +│ • Queue Backlog: {flow_data.get('queue_backlog', '0 items')} │ +│ │ +│ Legend: ════ High Volume │ ──── Normal │ ░░░░ Low Volume │ ╳╳╳╳ Error │ +└────────────────────────────────────────────────────────────────────────────────────────────────────┘ + """ + return flow_art +``` + +## API Endpoints для Мониторинга (/api/monitor/*) + +### 1. Core Monitoring Endpoints + +```python +from fastapi import APIRouter, HTTPException, BackgroundTasks +from fastapi.responses import StreamingResponse +import json +import asyncio + +monitor_router = APIRouter(prefix="/api/monitor", tags=["monitoring"]) + +@monitor_router.get("/status") +async def get_node_status(): + """Получение статуса ноды""" + + status = await NodeStatusCollector.get_current_status() + + return { + "node_id": status["node_id"], + "uptime_seconds": status["uptime"], + "health_status": status["health"], + "peer_connections": status["peer_count"], + "content_stats": status["content_stats"], + "resource_usage": status["resource_usage"], + "network_metrics": status["network_metrics"], + "timestamp": status["timestamp"] + } + +@monitor_router.get("/peers") +async def get_peer_status(): + """Статус всех подключенных пиров""" + + peers = await PeerManager.get_all_peers_status() + + return { + "total_peers": len(peers), + "active_peers": len([p for p in peers if p["status"] == "active"]), + "peers": [ + { + "peer_id": peer["id"], + "address": peer["address"], + "status": peer["status"], + "latency_ms": peer["latency"], + "last_seen": peer["last_seen"], + "data_transferred": peer["data_transferred"], + "reputation_score": peer["reputation"] + } + for peer in peers + ] + } + +@monitor_router.get("/content") +async def get_content_metrics(): + """Метрики контента""" + + metrics = await ContentMetricsCollector.get_metrics() + + return { + "total_content_items": metrics["total_items"], + "content_by_type": metrics["by_type"], + "storage_usage": metrics["storage_usage"], + "replication_stats": metrics["replication"], + "sync_status": metrics["sync_status"], + "popular_content": metrics["popular_items"][:10] + } + +@monitor_router.get("/network") +async def get_network_metrics(): + """Сетевые метрики""" + + network_stats = await NetworkMetricsCollector.get_stats() + + return { + "network_topology": network_stats["topology"], + "bandwidth_usage": network_stats["bandwidth"], + "message_stats": network_stats["messages"], + "consensus_metrics": network_stats["consensus"], + "error_rates": network_stats["errors"] + } + +@monitor_router.get("/performance") +async def get_performance_metrics(): + """Метрики производительности""" + + perf_data = await PerformanceCollector.get_metrics() + + return { + "cpu_usage": perf_data["cpu"], + "memory_usage": perf_data["memory"], + "disk_io": perf_data["disk_io"], + "network_io": perf_data["network_io"], + "operation_latencies": perf_data["latencies"], + "throughput_stats": perf_data["throughput"] + } +``` + +### 2. Real-time Streaming Endpoints + +```python +@monitor_router.get("/stream/status") +async def stream_node_status(): + """Потоковая передача статуса ноды""" + + async def generate_status_stream(): + while True: + try: + status = await NodeStatusCollector.get_current_status() + yield f"data: {json.dumps(status)}\n\n" + await asyncio.sleep(1) + except Exception as e: + yield f"data: {json.dumps({'error': str(e)})}\n\n" + break + + return StreamingResponse( + generate_status_stream(), + media_type="text/plain", + headers={"Cache-Control": "no-cache"} + ) + +@monitor_router.get("/stream/content-flow") +async def stream_content_flow(): + """Потоковая передача данных о потоке контента""" + + async def generate_flow_stream(): + while True: + try: + flow_data = await ContentFlowMonitor.get_current_flow() + yield f"data: {json.dumps(flow_data)}\n\n" + await asyncio.sleep(0.5) # Высокая частота для real-time + except Exception as e: + yield f"data: {json.dumps({'error': str(e)})}\n\n" + break + + return StreamingResponse( + generate_flow_stream(), + media_type="text/plain" + ) + +@monitor_router.post("/alerts/subscribe") +async def subscribe_to_alerts(subscription: AlertSubscription): + """Подписка на алерты""" + + subscription_id = await AlertManager.subscribe(subscription) + + return { + "subscription_id": subscription_id, + "status": "subscribed", + "alert_types": subscription.alert_types + } + +@monitor_router.get("/logs/tail") +async def tail_logs(lines: int = 100, level: str = "info"): + """Получение последних логов""" + + logs = await LogManager.get_recent_logs(lines, level) + + return { + "logs": logs, + "total_lines": len(logs), + "level_filter": level + } +``` + +### 3. Advanced Analytics Endpoints + +```python +@monitor_router.get("/analytics/performance") +async def get_performance_analytics(hours: int = 24): + """Аналитика производительности за период""" + + analytics = await PerformanceAnalyzer.analyze_period(hours) + + return { + "period_hours": hours, + "summary": analytics["summary"], + "trends": analytics["trends"], + "bottlenecks": analytics["bottlenecks"], + "recommendations": analytics["recommendations"] + } + +@monitor_router.get("/analytics/content-distribution") +async def get_content_distribution_analytics(): + """Аналитика распределения контента""" + + distribution = await ContentAnalyzer.analyze_distribution() + + return { + "replication_efficiency": distribution["efficiency"], + "load_balancing": distribution["balance"], + "hotspots": distribution["hotspots"], + "optimization_opportunities": distribution["optimizations"] + } + +@monitor_router.get("/health-check") +async def comprehensive_health_check(): + """Комплексная проверка здоровья системы""" + + health_status = await HealthChecker.perform_full_check() + + return { + "overall_health": health_status["overall"], + "component_health": health_status["components"], + "critical_issues": health_status["critical"], + "warnings": health_status["warnings"], + "recommendations": health_status["recommendations"] + } +``` + +## Метрики Производительности и Нагрузки + +### 1. Performance Metrics Collector + +```python +class PerformanceMetricsCollector: + def __init__(self): + self.metrics_buffer = [] + self.buffer_size = 1000 + self.collection_interval = 5 # секунды + + async def start_collection(self): + """Запуск сбора метрик""" + asyncio.create_task(self.collect_system_metrics()) + asyncio.create_task(self.collect_network_metrics()) + asyncio.create_task(self.collect_application_metrics()) + + async def collect_system_metrics(self): + """Сбор системных метрик""" + while True: + try: + metrics = { + "timestamp": datetime.utcnow().isoformat(), + "type": "system", + "cpu_percent": psutil.cpu_percent(interval=1), + "memory_percent": psutil.virtual_memory().percent, + "memory_available": psutil.virtual_memory().available, + "disk_usage": { + path: psutil.disk_usage(path).percent + for path in ["/", "/tmp", "/var/log"] + }, + "disk_io": await self.get_disk_io_stats(), + "network_io": await self.get_network_io_stats(), + "load_average": os.getloadavg(), + "process_count": len(psutil.pids()) + } + + await self.store_metric(metrics) + await asyncio.sleep(self.collection_interval) + + except Exception as e: + logger.error(f"Error collecting system metrics: {e}") + await asyncio.sleep(self.collection_interval) + + async def collect_network_metrics(self): + """Сбор сетевых метрик""" + while True: + try: + network_stats = await self.get_network_statistics() + + metrics = { + "timestamp": datetime.utcnow().isoformat(), + "type": "network", + "active_connections": network_stats["connections"], + "bytes_sent": network_stats["bytes_sent"], + "bytes_received": network_stats["bytes_received"], + "packets_sent": network_stats["packets_sent"], + "packets_received": network_stats["packets_received"], + "errors": network_stats["errors"], + "drops": network_stats["drops"], + "peer_latencies": await self.measure_peer_latencies(), + "bandwidth_usage": await self.calculate_bandwidth_usage() + } + + await self.store_metric(metrics) + await asyncio.sleep(self.collection_interval) + + except Exception as e: + logger.error(f"Error collecting network metrics: {e}") + await asyncio.sleep(self.collection_interval) + + async def collect_application_metrics(self): + """Сбор метрик приложения""" + while True: + try: + app_stats = await self.get_application_statistics() + + metrics = { + "timestamp": datetime.utcnow().isoformat(), + "type": "application", + "content_operations": app_stats["content_ops"], + "sync_operations": app_stats["sync_ops"], + "consensus_operations": app_stats["consensus_ops"], + "replication_operations": app_stats["replication_ops"], + "api_requests": app_stats["api_requests"], + "error_rates": app_stats["error_rates"], + "queue_sizes": app_stats["queue_sizes"], + "cache_hit_rates": app_stats["cache_stats"] + } + + await self.store_metric(metrics) + await asyncio.sleep(self.collection_interval) + + except Exception as e: + logger.error(f"Error collecting application metrics: {e}") + await asyncio.sleep(self.collection_interval) +``` + +### 2. Load Testing and Stress Monitoring + +```python +class LoadMonitor: + def __init__(self): + self.load_thresholds = { + "cpu_critical": 90.0, + "cpu_warning": 70.0, + "memory_critical": 95.0, + "memory_warning": 80.0, + "disk_critical": 95.0, + "disk_warning": 85.0, + "network_critical": 90.0, + "network_warning": 70.0 + } + + async def monitor_load_continuously(self): + """Непрерывный мониторинг нагрузки""" + while True: + try: + current_load = await self.assess_current_load() + + # Проверка критических уровней + critical_alerts = await self.check_critical_levels(current_load) + if critical_alerts: + await self.handle_critical_alerts(critical_alerts) + + # Проверка предупреждений + warning_alerts = await self.check_warning_levels(current_load) + if warning_alerts: + await self.handle_warning_alerts(warning_alerts) + + # Адаптивное управление ресурсами + await self.adaptive_resource_management(current_load) + + await asyncio.sleep(10) # Проверка каждые 10 секунд + + except Exception as e: + logger.error(f"Error in load monitoring: {e}") + await asyncio.sleep(10) + + async def assess_current_load(self) -> dict: + """Оценка текущей нагрузки""" + return { + "cpu_load": psutil.cpu_percent(interval=1), + "memory_load": psutil.virtual_memory().percent, + "disk_load": max([ + psutil.disk_usage(path).percent + for path in ["/", "/tmp", "/var/log"] + ]), + "network_load": await self.calculate_network_load(), + "application_load": await self.calculate_application_load(), + "timestamp": datetime.utcnow() + } + + async def adaptive_resource_management(self, current_load: dict): + """Адаптивное управление ресурсами""" + + # CPU нагрузка + if current_load["cpu_load"] > self.load_thresholds["cpu_warning"]: + await self.reduce_cpu_intensive_operations() + + # Память + if current_load["memory_load"] > self.load_thresholds["memory_warning"]: + await self.optimize_memory_usage() + + # Сеть + if current_load["network_load"] > self.load_thresholds["network_warning"]: + await self.throttle_network_operations() + + # Приложение + if current_load["application_load"] > 80.0: + await self.scale_application_resources() +``` + +## Telegram Bot Команды для Управления + +### 1. MY Network Telegram Bot + +```python +from aiogram import Bot, Dispatcher, types +from aiogram.filters import Command +from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup + +class MYNetworkTelegramBot: + def __init__(self, token: str, authorized_users: List[int]): + self.bot = Bot(token) + self.dp = Dispatcher() + self.authorized_users = set(authorized_users) + self.setup_handlers() + + def setup_handlers(self): + """Настройка обработчиков команд""" + + @self.dp.message(Command("start")) + async def start_command(message: types.Message): + if message.from_user.id not in self.authorized_users: + await message.reply("❌ Access denied. Unauthorized user.") + return + + keyboard = InlineKeyboardMarkup(inline_keyboard=[ + [InlineKeyboardButton(text="📊 Node Status", callback_data="status")], + [InlineKeyboardButton(text="🌐 Network Info", callback_data="network")], + [InlineKeyboardButton(text="📁 Content Stats", callback_data="content")], + [InlineKeyboardButton(text="⚡ Performance", callback_data="performance")], + [InlineKeyboardButton(text="🔧 Controls", callback_data="controls")] + ]) + + await message.reply( + "🤖 MY Network Control Bot\n\n" + "Welcome to the MY Network monitoring and control interface.\n" + "Select an option below:", + reply_markup=keyboard + ) + + @self.dp.message(Command("status")) + async def status_command(message: types.Message): + if message.from_user.id not in self.authorized_users: + return + + try: + status = await NodeStatusCollector.get_current_status() + + status_text = f""" +🖥 **MY Network Node Status** + +🆔 Node ID: `{status['node_id'][:16]}...` +⏰ Uptime: {self.format_uptime(status['uptime'])} +🟢 Status: {status['health_status']} +👥 Peers: {status['peer_count']} connected +📁 Content: {status['content_count']} items +💾 Storage: {status['storage_usage']} +🔄 Sync: {status['sync_status']} + +📊 **Resources:** +🖥 CPU: {status['cpu_usage']:.1f}% +💾 RAM: {status['memory_usage']:.1f}% +💿 Disk: {status['disk_usage']:.1f}% +🌐 Network: {status['network_io']} + """ + + await message.reply(status_text, parse_mode="Markdown") + + except Exception as e: + await message.reply(f"❌ Error getting status: {str(e)}") + + @self.dp.message(Command("peers")) + async def peers_command(message: types.Message): + if message.from_user.id not in self.authorized_users: + return + + try: + peers = await PeerManager.get_all_peers_status() + + if not peers: + await message.reply("No peers connected.") + return + + peers_text = "👥 **Connected Peers:**\n\n" + + for peer in peers[:10]: # Показать первые 10 + status_emoji = "🟢" if peer["status"] == "active" else "🔴" + peers_text += f"{status_emoji} `{peer['id'][:12]}...`\n" + peers_text += f" 📍 {peer['address']}\n" + peers_text += f" ⏱ {peer['latency']}ms\n" + peers_text += f" 📊 {peer['reputation']:.2f}/5.0\n\n" + + if len(peers) > 10: + peers_text += f"... and {len(peers) - 10} more peers" + + await message.reply(peers_text, parse_mode="Markdown") + + except Exception as e: + await message.reply(f"❌ Error getting peers: {str(e)}") + + @self.dp.message(Command("sync")) + async def sync_command(message: types.Message): + if message.from_user.id not in self.authorized_users: + return + + try: + # Запуск принудительной синхронизации + sync_task = await ContentSyncManager.start_full_sync() + + await message.reply( + f"🔄 Full synchronization started\n" + f"Task ID: `{sync_task.id}`\n" + f"Use /sync_status to check progress." + ) + + except Exception as e: + await message.reply(f"❌ Error starting sync: {str(e)}") + + @self.dp.message(Command("alerts")) + async def alerts_command(message: types.Message): + if message.from_user.id not in self.authorized_users: + return + + try: + recent_alerts = await AlertManager.get_recent_alerts(limit=10) + + if not recent_alerts: + await message.reply("✅ No recent alerts.") + return + + alerts_text = "🚨 **Recent Alerts:**\n\n" + + for alert in recent_alerts: + severity_emoji = { + "critical": "🔴", + "warning": "🟡", + "info": "ℹ️" + }.get(alert["severity"], "ℹ️") + + alerts_text += f"{severity_emoji} **{alert['title']}**\n" + alerts_text += f" {alert['message']}\n" + alerts_text += f" 📅 {alert['timestamp']}\n\n" + + await message.reply(alerts_text, parse_mode="Markdown") + + except Exception as e: + await message.reply(f"❌ Error getting alerts: {str(e)}") +``` + +### 2. Advanced Bot Commands + +```python + @self.dp.message(Command("restart")) + async def restart_command(message: types.Message): + if message.from_user.id not in self.authorized_users: + return + + # Подтверждение перезапуска + keyboard = InlineKeyboardMarkup(inline_keyboard=[ + [InlineKeyboardButton(text="✅ Confirm Restart", callback_data="restart_confirm")], + [InlineKeyboardButton(text="❌ Cancel", callback_data="restart_cancel")] + ]) + + await message.reply( + "⚠️ **Restart Confirmation**\n\n" + "This will restart the MY Network node.\n" + "All active connections will be lost.\n\n" + "Are you sure?", + reply_markup=keyboard, + parse_mode="Markdown" + ) + + @self.dp.message(Command("config")) + async def config_command(message: types.Message, args: str = None): + if message.from_user.id not in self.authorized_users: + return + + if not args: + # Показать текущую конфигурацию + config = await ConfigManager.get_current_config() + + config_text = f""" +⚙️ **Current Configuration:** + +🔧 **Network Settings:** +• Max Peers: {config['max_peers']} +• Sync Interval: {config['sync_interval']}s +• Consensus Timeout: {config['consensus_timeout']}s + +📊 **Resource Limits:** +• Max Storage: {config['max_storage']} +• Max Bandwidth: {config['max_bandwidth']} +• Max Memory: {config['max_memory']} + +🔒 **Security:** +• Encryption: {config['encryption_enabled']} +• Auth Required: {config['auth_required']} + """ + + await message.reply(config_text, parse_mode="Markdown") + else: + # Обновить конфигурацию + try: + key, value = args.split("=", 1) + await ConfigManager.update_config(key.strip(), value.strip()) + await message.reply(f"✅ Configuration updated: {key} = {value}") + except ValueError: + await message.reply( + "❌ Invalid format. Use: /config key=value" + ) + except Exception as e: + await message.reply(f"❌ Error updating config: {str(e)}") + + @self.dp.message(Command("blacklist")) + async def blacklist_command(message: types.Message, args: str = None): + if message.from_user.id not in self.authorized_users: + return + + if not args: + # Показать blacklist + blacklisted = await PeerManager.get_blacklisted_peers() + + if not blacklisted: + await message.reply("📝 Blacklist is empty.") + return + + blacklist_text = "🚫 **Blacklisted Peers:**\n\n" + for peer_id in blacklisted: + blacklist_text += f"• `{peer_id}`\n" + + await message.reply(blacklist_text, parse_mode="Markdown") + else: + # Добавить в blacklist + try: + peer_id = args.strip() + await PeerManager.blacklist_peer(peer_id) + await message.reply(f"✅ Peer blacklisted: `{peer_id}`") + except Exception as e: + await message.reply(f"❌ Error blacklisting peer: {str(e)}") +``` + +## Web-интерфейс + +### 1. Web Dashboard + +```html + + + + + + MY Network Monitoring Dashboard + + + +
+
+

🔹 MY NETWORK MONITORING DASHBOARD 🔹

+

Real-time monitoring of distributed content network

+ +
+ +
+
+

📊 Node Status

+
+

Node ID: Loading...

+

Uptime: Loading...

+

Status: Loading...

+

Peers: Loading...

+
+
+ +
+

💾 Resources

+
+

CPU Usage:

+
+
+
+

Memory Usage:

+
+
+
+

Disk Usage:

+
+
+
+
+
+ +
+

🌐 Network

+
+

Bandwidth: Loading...

+

Latency: Loading...

+

Messages/sec: Loading...

+

Errors: Loading...

+
+
+ +
+

📁 Content

+
+

Total Items: Loading...

+

Sync Status: Loading...

+

Replication Rate: Loading...

+

Storage Used: Loading...

+
+
+
+ +
+
+

📡 Live Terminal

+
+ Connecting to MY Network node...
+ Establishing secure connection...
+ +
+
+ +
+

🗺️ Network Topology

+ +
+
+
+ + + + +``` + +Данная система мониторинга обеспечивает полный контроль над MY Network с помощью различных интерфейсов - от хакерского ASCII-арт терминала до современного веб-интерфейса и Telegram бота для удаленного управления. \ No newline at end of file diff --git a/docs/MY_NETWORK_README.md b/docs/MY_NETWORK_README.md new file mode 100644 index 0000000..b3f3f0f --- /dev/null +++ b/docs/MY_NETWORK_README.md @@ -0,0 +1,422 @@ +# MY Network v2.0 - Distributed Content Protocol + +## 🌐 Обзор + +MY Network - это распределенная система для управления и синхронизации контента между нодами. Протокол обеспечивает: + +- **P2P сеть** для обмена данными между нодами +- **Автоматическую синхронизацию** контента +- **Load balancing** на основе метрик нагрузки +- **Веб-интерфейс мониторинга** в хакерском стиле +- **Совместимость** с существующей инфраструктурой + +## 🚀 Быстрый запуск + +### Минимальный запуск для тестирования: + +```bash +# 1. Установить зависимости +pip install -r requirements_new.txt + +# 2. Запустить минимальный сервер +python start_my_network.py +``` + +Откройте http://localhost:8000/api/my/monitor/ для мониторинга. + +### Запуск с существующей системой: + +```bash +# 1. Использовать совместимые файлы +cp docker-compose.compatible.yml docker-compose.yml +cp .env.compatible .env + +# 2. Запустить через Docker +docker-compose up -d + +# 3. MY Network автоматически интегрируется +``` + +## 🏗️ Продакшен развертывание + +### Автоматическое развертывание: + +```bash +# Сохранить переменные окружения +export DOMAIN="your-domain.com" +export EMAIL="admin@your-domain.com" + +# Запустить скрипт развертывания (требует root) +sudo bash deploy_my_network.sh +``` + +Скрипт автоматически установит: +- ✅ Nginx с SSL (Let's Encrypt) +- ✅ Docker и Docker Compose +- ✅ Firewall и безопасность +- ✅ Systemd сервисы +- ✅ Мониторинг и health checks + +### Ручное развертывание: + +```bash +# 1. Создать production .env +cp .env.example .env.production +# Отредактировать настройки + +# 2. Запустить продакшен контейнеры +docker-compose -f docker-compose.prod.yml up -d + +# 3. Настроить nginx +sudo cp nginx.conf /etc/nginx/sites-available/my-network +sudo ln -s /etc/nginx/sites-available/my-network /etc/nginx/sites-enabled/ +sudo systemctl restart nginx +``` + +## 📊 Мониторинг и управление + +### Веб-интерфейс: +- **Основной мониторинг**: http://your-domain/api/my/monitor/ +- **ASCII статус**: http://your-domain/api/my/monitor/ascii +- **API документация**: http://your-domain/api/docs + +### API эндпоинты: + +#### Информация о ноде: +```bash +# Статус ноды +curl http://localhost:8000/api/my/node/info + +# Подключенные пиры +curl http://localhost:8000/api/my/node/peers + +# Статус синхронизации +curl http://localhost:8000/api/my/sync/status +``` + +#### Управление пирами: +```bash +# Подключиться к пиру +curl -X POST http://localhost:8000/api/my/node/peers/connect \ + -H "Content-Type: application/json" \ + -d '{"address": "http://peer-node:8001"}' + +# Отключиться от пира +curl -X DELETE http://localhost:8000/api/my/node/peers/PEER_ID +``` + +#### Синхронизация: +```bash +# Запустить синхронизацию +curl -X POST http://localhost:8000/api/my/sync/start + +# Реплицировать контент +curl -X POST http://localhost:8000/api/my/content/HASH/replicate \ + -H "Content-Type: application/json" \ + -d '{"target_nodes": ["node1", "node2"]}' +``` + +### Системные команды: + +```bash +# Управление сервисом +sudo systemctl start my-network +sudo systemctl stop my-network +sudo systemctl restart my-network +sudo systemctl status my-network + +# Просмотр логов +sudo journalctl -u my-network -f +tail -f /var/log/my-network/app.log + +# Проверка здоровья +/opt/my-network/health_check.sh + +# Docker команды +docker-compose logs -f my-network-app +docker-compose ps +``` + +## 🔧 Конфигурация + +### Основные настройки (.env): + +```env +# MY Network Configuration +MY_NETWORK_ENABLED=True +MY_NETWORK_NODE_ID=unique-node-id +MY_NETWORK_P2P_PORT=8001 +MY_NETWORK_API_PORT=8000 + +# Bootstrap ноды (JSON массив) +MY_NETWORK_BOOTSTRAP_NODES=["http://bootstrap1:8001", "http://bootstrap2:8001"] + +# Настройки синхронизации +SYNC_MAX_CONCURRENT=5 +SYNC_TIMEOUT=300 +SYNC_RETRY_ATTEMPTS=3 + +# Настройки пиров +PEER_HEALTH_CHECK_INTERVAL=60 +PEER_CONNECTION_TIMEOUT=30 +MAX_PEER_CONNECTIONS=50 +``` + +### Bootstrap конфигурация (bootstrap.json): + +```json +{ + "version": "2.0", + "network_id": "my-network-main", + "bootstrap_nodes": [ + { + "node_id": "bootstrap-1", + "address": "https://bootstrap1.my-network.com:8001", + "public_key": "...", + "trusted": true + } + ], + "consensus": { + "algorithm": "raft", + "election_timeout": 5000, + "heartbeat_interval": 1000 + } +} +``` + +## 🌍 Архитектура сети + +### Компоненты: + +1. **Node Service** - основной сервис ноды +2. **Peer Manager** - управление подключениями +3. **Sync Manager** - синхронизация контента +4. **Bootstrap Manager** - управление bootstrap конфигурацией + +### Протокол взаимодействия: + +``` +Нода A Нода B + | | + |--- Handshake ---------> | + |<-- Auth Response ------- | + | | + |--- Content List ------> | + |<-- Missing Content ---- | + | | + |--- File Transfer -----> | + |<-- Confirmation ------- | +``` + +### Состояния контента: + +- **Local** - только на текущей ноде +- **Syncing** - в процессе синхронизации +- **Replicated** - скопирован на другие ноды +- **Verified** - проверена целостность + +## 🔒 Безопасность + +### Встроенные механизмы: + +- **TLS шифрование** для всех соединений +- **Проверка хешей** для целостности файлов +- **Аутентификация пиров** через public key +- **Rate limiting** для предотвращения DDoS +- **Firewall правила** для ограничения доступа + +### Рекомендации: + +```bash +# Настроить firewall +sudo ufw allow 8000:8010/tcp +sudo ufw allow 8000:8010/udp + +# Включить fail2ban +sudo systemctl enable fail2ban + +# Регулярные бэкапы +0 2 * * * /opt/my-network/backup.sh +``` + +## 📈 Мониторинг и алерты + +### Метрики: + +- **Количество подключенных пиров** +- **Статус синхронизации** +- **Использование ресурсов** +- **Время отклика** +- **Ошибки сети** + +### Health checks: + +```bash +# HTTP health check +curl -f http://localhost:8000/health + +# MY Network specific +curl -f http://localhost:8000/api/my/health + +# Detailed status +curl http://localhost:8000/api/my/network/stats +``` + +### Prometheus интеграция: + +```yaml +# prometheus.yml +scrape_configs: + - job_name: 'my-network' + static_configs: + - targets: ['localhost:9090'] + metrics_path: '/metrics' +``` + +## 🐛 Устранение неисправностей + +### Частые проблемы: + +#### 1. Нода не подключается к пирам: +```bash +# Проверить сетевые соединения +netstat -tulpn | grep 8001 + +# Проверить firewall +sudo ufw status + +# Проверить логи +tail -f /var/log/my-network/app.log +``` + +#### 2. Синхронизация не работает: +```bash +# Проверить статус синхронизации +curl http://localhost:8000/api/my/sync/status + +# Перезапустить синхронизацию +curl -X POST http://localhost:8000/api/my/sync/start + +# Проверить доступность целевых нод +curl http://target-node:8001/api/my/health +``` + +#### 3. Высокое использование ресурсов: +```bash +# Проверить использование CPU/памяти +docker stats my-network-app + +# Ограничить ресурсы +docker update --memory=2g --cpus=2 my-network-app + +# Настроить параметры синхронизации +echo "SYNC_MAX_CONCURRENT=2" >> .env +``` + +### Диагностические команды: + +```bash +# Проверить все компоненты +curl http://localhost:8000/api/my/health | jq + +# Список активных соединений +curl http://localhost:8000/api/my/node/peers | jq + +# Статистика сети +curl http://localhost:8000/api/my/network/stats | jq + +# ASCII статус (для консоли) +curl http://localhost:8000/api/my/monitor/ascii +``` + +## 🔄 Обновление системы + +### Обновление без downtime: + +```bash +# 1. Подготовить новую версию +git pull origin main + +# 2. Собрать новый образ +docker-compose build my-network-app + +# 3. Rolling update +docker-compose up -d --no-deps my-network-app + +# 4. Проверить статус +curl http://localhost:8000/health +``` + +### Миграция данных: + +```bash +# Экспорт данных +docker exec my-network-db mysqldump -u root -p mymusic > backup.sql + +# Миграция схемы (если нужно) +docker exec my-network-app python -m alembic upgrade head + +# Импорт данных +docker exec -i my-network-db mysql -u root -p mymusic < backup.sql +``` + +## 📚 Дополнительная документация + +- **MY_ARCHITECTURE.md** - детальная архитектура системы +- **MY_PROTOCOL.md** - спецификация протокола +- **MY_NODE_SPEC.md** - технические характеристики нод +- **MY_MONITORING.md** - руководство по мониторингу + +## 🤝 Вклад в проект + +### Структура проекта: + +``` +my-uploader-bot/ +├── app/ +│ ├── core/ +│ │ └── my_network/ # MY Network компоненты +│ │ ├── node_service.py +│ │ ├── peer_manager.py +│ │ ├── sync_manager.py +│ │ └── bootstrap_manager.py +│ ├── api/ +│ │ └── routes/ # API маршруты +│ │ ├── my_network_routes.py +│ │ └── my_monitoring.py +│ └── templates/ # Web интерфейс +│ └── my_network_monitor.html +├── bootstrap.json # Bootstrap конфигурация +├── start_my_network.py # Быстрый запуск +└── deploy_my_network.sh # Продакшен деплой +``` + +### Development workflow: + +```bash +# 1. Создать ветку для фичи +git checkout -b feature/my-feature + +# 2. Разработка с hot reload +python start_my_network.py --debug + +# 3. Тестирование +pytest tests/test_my_network.py + +# 4. Создать pull request +git push origin feature/my-feature +``` + +## 📞 Поддержка + +Если у вас возникли вопросы или проблемы: + +1. Проверьте [Troubleshooting](#-устранение-неисправностей) +2. Посмотрите логи: `tail -f /var/log/my-network/app.log` +3. Проверьте health check: `curl http://localhost:8000/api/my/health` +4. Создайте issue с подробным описанием проблемы + +--- + +**MY Network v2.0** - Distributed Content Protocol +*Decentralized content distribution made simple* \ No newline at end of file diff --git a/docs/MY_NODE_SPEC.md b/docs/MY_NODE_SPEC.md new file mode 100644 index 0000000..15b73ad --- /dev/null +++ b/docs/MY_NODE_SPEC.md @@ -0,0 +1,791 @@ +# MY Network Node Specification + +## Обзор MY Network Node + +MY Network Node представляет собой расширение существующего my-uploader-bot, добавляющее возможности участия в децентрализованной сети без нарушения текущей функциональности. + +## Процесс Запуска и Инициализации Ноды + +### 1. Startup Sequence + +```python +class MYNetworkNode: + async def initialize(self): + """Полная инициализация MY Network ноды""" + + # Phase 1: Core System Check + await self.verify_core_system() + + # Phase 2: Load Configuration + await self.load_configuration() + + # Phase 3: Initialize Cryptography + await self.initialize_crypto_system() + + # Phase 4: Start Network Services + await self.start_network_services() + + # Phase 5: Connect to Bootstrap Nodes + await self.connect_to_bootstrap_nodes() + + # Phase 6: Discover Peers + await self.start_peer_discovery() + + # Phase 7: Sync Content + await self.start_initial_sync() + + # Phase 8: Start Background Services + await self.start_background_services() + + logger.info("MY Network Node successfully initialized") +``` + +### 2. Configuration Loading + +```python +async def load_configuration(self): + """Загрузка конфигурации ноды""" + + # Загрузка bootstrap.json + self.bootstrap_config = await self.load_bootstrap_config() + + # Загрузка локальной конфигурации + self.node_config = await self.load_node_config() + + # Объединение конфигураций + self.config = { + **self.bootstrap_config, + **self.node_config, + "node_id": self.generate_or_load_node_id(), + "startup_time": datetime.utcnow().isoformat() + } +``` + +### 3. Crypto System Initialization + +```python +async def initialize_crypto_system(self): + """Инициализация криптографической системы""" + + # Загрузка или генерация ключевой пары ноды + self.node_keypair = await self.load_or_generate_keypair() + + # Создание подписывающего объекта + self.signer = Ed25519Signer(self.node_keypair.private_key) + + # Инициализация шифрования транспорта + self.transport_crypto = TransportCrypto(self.node_keypair) + + # Проверка криптографической системы + await self.verify_crypto_system() +``` + +## Подключение к Bootstrap Нодам + +### 1. Bootstrap Discovery Process + +```python +class BootstrapConnector: + async def connect_to_bootstrap_nodes(self): + """Подключение к bootstrap нодам""" + + bootstrap_nodes = self.config["bootstrap_nodes"] + connected_nodes = [] + + for node_info in bootstrap_nodes: + try: + connection = await self.establish_connection(node_info) + if connection: + connected_nodes.append(connection) + logger.info(f"Connected to bootstrap node: {node_info['id']}") + + except Exception as e: + logger.warning(f"Failed to connect to bootstrap node {node_info['id']}: {e}") + + if len(connected_nodes) == 0: + raise BootstrapConnectionError("Failed to connect to any bootstrap nodes") + + # Сохранение подключений + self.bootstrap_connections = connected_nodes + + # Запрос информации о сети + await self.request_network_info() +``` + +### 2. Network Information Exchange + +```python +async def request_network_info(self): + """Запрос информации о сети от bootstrap нод""" + + network_info = {} + + for connection in self.bootstrap_connections: + try: + # Запрос списка активных нод + peers_response = await connection.request("get_active_peers") + network_info["peers"] = peers_response.get("peers", []) + + # Запрос статистики сети + stats_response = await connection.request("get_network_stats") + network_info["stats"] = stats_response.get("stats", {}) + + # Запрос популярного контента + content_response = await connection.request("get_popular_content") + network_info["popular_content"] = content_response.get("content", []) + + break # Достаточно получить от одной ноды + + except Exception as e: + logger.warning(f"Failed to get network info from bootstrap: {e}") + continue + + self.network_info = network_info +``` + +## Механизм Обнаружения Других Нод + +### 1. Peer Discovery Algorithm + +```python +class PeerDiscovery: + def __init__(self, node: MYNetworkNode): + self.node = node + self.discovered_peers = {} + self.discovery_interval = 60 # секунды + + async def start_discovery(self): + """Запуск процесса обнаружения пиров""" + + # Обнаружение через bootstrap ноды + await self.discover_through_bootstrap() + + # DHT-based discovery + await self.discover_through_dht() + + # Multicast discovery (для локальной сети) + await self.discover_through_multicast() + + # Запуск периодического обнаружения + asyncio.create_task(self.periodic_discovery()) + + async def discover_through_bootstrap(self): + """Обнаружение через bootstrap ноды""" + + for connection in self.node.bootstrap_connections: + try: + # Запрос списка пиров + response = await connection.request("discover_peers", { + "requesting_node": self.node.node_id, + "max_peers": 50, + "exclude_nodes": list(self.discovered_peers.keys()) + }) + + # Обработка найденных пиров + for peer_info in response.get("peers", []): + await self.process_discovered_peer(peer_info) + + except Exception as e: + logger.error(f"Peer discovery through bootstrap failed: {e}") + + async def discover_through_dht(self): + """Обнаружение через DHT""" + + # Поиск нод ответственных за наш ключ + our_key_hash = self.node.calculate_key_hash(self.node.node_id) + responsible_nodes = await self.find_responsible_nodes(our_key_hash) + + for node_info in responsible_nodes: + await self.process_discovered_peer(node_info) + + async def process_discovered_peer(self, peer_info: dict): + """Обработка обнаруженного пира""" + + peer_id = peer_info["node_id"] + + # Проверка, что это не мы сами + if peer_id == self.node.node_id: + return + + # Проверка, что пир не в черном списке + if peer_id in self.node.blacklisted_peers: + return + + # Попытка подключения + try: + connection = await self.establish_peer_connection(peer_info) + if connection: + self.discovered_peers[peer_id] = { + "info": peer_info, + "connection": connection, + "discovered_at": datetime.utcnow(), + "status": "connected" + } + + logger.info(f"Successfully connected to peer: {peer_id}") + + except Exception as e: + logger.warning(f"Failed to connect to peer {peer_id}: {e}") +``` + +### 2. Peer Connection Management + +```python +class PeerConnectionManager: + def __init__(self): + self.connections = {} + self.connection_limits = { + "max_outbound": 50, + "max_inbound": 100, + "max_per_ip": 3 + } + + async def establish_peer_connection(self, peer_info: dict) -> Optional[PeerConnection]: + """Установка соединения с пиром""" + + peer_id = peer_info["node_id"] + peer_address = peer_info["address"] + + # Проверка лимитов соединений + if not await self.check_connection_limits(peer_info): + return None + + try: + # Создание TCP соединения + connection = await self.create_tcp_connection(peer_address) + + # MY Network handshake + handshake_success = await self.perform_handshake(connection, peer_info) + if not handshake_success: + await connection.close() + return None + + # Создание MY Network peer connection + peer_connection = PeerConnection( + peer_id=peer_id, + connection=connection, + peer_info=peer_info + ) + + # Регистрация соединения + self.connections[peer_id] = peer_connection + + # Запуск обработчика сообщений + asyncio.create_task(self.handle_peer_messages(peer_connection)) + + return peer_connection + + except Exception as e: + logger.error(f"Failed to establish connection to {peer_id}: {e}") + return None + + async def perform_handshake(self, connection: Connection, peer_info: dict) -> bool: + """Выполнение MY Network handshake""" + + # Отправка handshake сообщения + handshake_msg = { + "type": "handshake", + "node_id": self.node.node_id, + "public_key": self.node.public_key_hex, + "network_version": "1.0.0", + "supported_features": ["content_sync", "consensus", "dht"], + "timestamp": datetime.utcnow().isoformat() + } + + # Подписание сообщения + handshake_msg["signature"] = await self.node.sign_message(handshake_msg) + + # Отправка handshake + await connection.send_message(handshake_msg) + + # Ожидание ответа + response = await connection.receive_message(timeout=10) + + # Проверка ответа + if response.get("type") != "handshake_response": + return False + + # Проверка подписи пира + peer_signature = response.get("signature") + if not await self.verify_peer_signature(peer_info, response, peer_signature): + return False + + return True +``` + +## Протокол Синхронизации Контента + +### 1. Content Sync Protocol + +```python +class ContentSyncProtocol: + def __init__(self, node: MYNetworkNode): + self.node = node + self.sync_queue = asyncio.Queue() + self.sync_stats = { + "synced_content": 0, + "failed_syncs": 0, + "bytes_synced": 0 + } + + async def start_initial_sync(self): + """Начальная синхронизация контента""" + + logger.info("Starting initial content synchronization") + + # Получение списка доступного контента от пиров + available_content = await self.discover_available_content() + + # Определение контента для синхронизации + content_to_sync = await self.select_content_for_sync(available_content) + + # Добавление в очередь синхронизации + for content_hash in content_to_sync: + await self.sync_queue.put(content_hash) + + # Запуск worker'ов синхронизации + workers = [] + for i in range(3): # 3 параллельных worker'а + worker = asyncio.create_task(self.sync_worker(f"worker-{i}")) + workers.append(worker) + + # Ожидание завершения начальной синхронизации + await self.sync_queue.join() + + # Остановка worker'ов + for worker in workers: + worker.cancel() + + logger.info(f"Initial sync completed. Synced {self.sync_stats['synced_content']} items") + + async def sync_worker(self, worker_id: str): + """Worker для синхронизации контента""" + + while True: + try: + # Получение контента для синхронизации + content_hash = await self.sync_queue.get() + + # Синхронизация контента + success = await self.sync_single_content(content_hash) + + if success: + self.sync_stats["synced_content"] += 1 + else: + self.sync_stats["failed_syncs"] += 1 + + # Отметка о завершении задачи + self.sync_queue.task_done() + + except asyncio.CancelledError: + break + except Exception as e: + logger.error(f"Sync worker {worker_id} error: {e}") + self.sync_queue.task_done() + + async def sync_single_content(self, content_hash: str) -> bool: + """Синхронизация одного элемента контента""" + + try: + # Проверка, есть ли уже этот контент локально + local_content = await StoredContent.get_by_hash(self.node.db_session, content_hash) + if local_content: + return True # Уже есть + + # Поиск пиров с этим контентом + peers_with_content = await self.find_peers_with_content(content_hash) + if not peers_with_content: + logger.warning(f"No peers found with content: {content_hash}") + return False + + # Выбор оптимального пира для загрузки + selected_peer = await self.select_optimal_peer(peers_with_content) + + # Загрузка метаданных контента + content_metadata = await self.download_content_metadata(selected_peer, content_hash) + if not content_metadata: + return False + + # Загрузка данных контента + content_data = await self.download_content_data(selected_peer, content_hash) + if not content_data: + return False + + # Проверка целостности + if not await self.verify_content_integrity(content_hash, content_data): + logger.error(f"Content integrity check failed: {content_hash}") + return False + + # Сохранение контента локально + await self.store_content_locally(content_metadata, content_data) + + # Обновление статистики + self.sync_stats["bytes_synced"] += len(content_data) + + logger.info(f"Successfully synced content: {content_hash}") + return True + + except Exception as e: + logger.error(f"Failed to sync content {content_hash}: {e}") + return False +``` + +### 2. Differential Sync Algorithm + +```python +class DifferentialSync: + async def perform_differential_sync(self, peer_id: str): + """Дифференциальная синхронизация с пиром""" + + # Получение локального state + local_state = await self.get_local_content_state() + + # Запрос state от пира + peer_state = await self.request_peer_content_state(peer_id) + + # Вычисление различий + diff = await self.calculate_state_diff(local_state, peer_state) + + # Синхронизация различий + if diff["missing_locally"]: + await self.sync_missing_content(peer_id, diff["missing_locally"]) + + if diff["missing_on_peer"]: + await self.send_missing_content(peer_id, diff["missing_on_peer"]) + + # Разрешение конфликтов + if diff["conflicts"]: + await self.resolve_content_conflicts(peer_id, diff["conflicts"]) + + async def calculate_state_diff(self, local_state: dict, peer_state: dict) -> dict: + """Вычисление различий между состояниями""" + + local_hashes = set(local_state.keys()) + peer_hashes = set(peer_state.keys()) + + missing_locally = peer_hashes - local_hashes + missing_on_peer = local_hashes - peer_hashes + common_content = local_hashes & peer_hashes + + # Проверка конфликтов в общем контенте + conflicts = [] + for content_hash in common_content: + local_meta = local_state[content_hash] + peer_meta = peer_state[content_hash] + + if local_meta["version"] != peer_meta["version"]: + conflicts.append({ + "content_hash": content_hash, + "local_version": local_meta["version"], + "peer_version": peer_meta["version"] + }) + + return { + "missing_locally": list(missing_locally), + "missing_on_peer": list(missing_on_peer), + "conflicts": conflicts + } +``` + +## Обработка Всех Состояний Контента + +### 1. Multi-State Content Handler + +```python +class MultiStateContentHandler: + def __init__(self, node: MYNetworkNode): + self.node = node + self.state_processors = { + "encrypted": EncryptedContentProcessor(), + "decrypted": DecryptedContentProcessor(), + "preview": PreviewContentProcessor() + } + + async def process_content_group(self, content_group_id: str): + """Обработка группы связанных состояний контента""" + + # Обнаружение всех состояний в группе + content_states = await self.discover_content_states(content_group_id) + + # Обработка каждого состояния + for state in content_states: + processor = self.state_processors.get(state.type) + if processor: + await processor.process_state(state) + + # Проверка целостности связей между состояниями + await self.verify_state_relationships(content_states) + + # Репликация всех состояний + await self.replicate_content_group(content_states) + + async def discover_content_states(self, content_group_id: str) -> List[ContentState]: + """Обнаружение всех состояний контента в группе""" + + # Поиск корневого контента + root_content = await StoredContent.get_by_id( + self.node.db_session, content_group_id + ) + + if not root_content: + return [] + + states = [ContentState( + content=root_content, + type=self.determine_content_state_type(root_content) + )] + + # Поиск связанных состояний через relationships + relationships = await self.get_content_relationships(content_group_id) + + for rel in relationships: + related_content = await StoredContent.get_by_id( + self.node.db_session, rel.child_content_id + ) + + if related_content: + states.append(ContentState( + content=related_content, + type=rel.relationship_type, + parent_id=content_group_id + )) + + return states + + def determine_content_state_type(self, content: StoredContent) -> str: + """Определение типа состояния контента""" + + if content.encrypted: + return "encrypted" + elif "preview" in content.tags: + return "preview" + else: + return "decrypted" +``` + +### 2. State-Specific Processors + +```python +class EncryptedContentProcessor: + async def process_state(self, state: ContentState): + """Обработка зашифрованного состояния""" + + content = state.content + + # Проверка наличия ключа шифрования + if not content.encryption_key_id: + logger.warning(f"Encrypted content without key: {content.id}") + return + + # Проверка доступности ключа + encryption_key = await EncryptionKey.get_by_id( + self.node.db_session, content.encryption_key_id + ) + + if not encryption_key or not encryption_key.is_valid: + logger.warning(f"Invalid encryption key for content: {content.id}") + return + + # Обработка зашифрованного контента + await self.process_encrypted_content(content, encryption_key) + +class DecryptedContentProcessor: + async def process_state(self, state: ContentState): + """Обработка расшифрованного состояния""" + + content = state.content + + # Проверка связи с зашифрованной версией + if state.parent_id: + encrypted_content = await StoredContent.get_by_id( + self.node.db_session, state.parent_id + ) + + if encrypted_content and encrypted_content.encrypted: + # Проверка соответствия с зашифрованной версией + await self.verify_encrypted_decrypted_relationship( + encrypted_content, content + ) + + # Обработка расшифрованного контента + await self.process_decrypted_content(content) + +class PreviewContentProcessor: + async def process_state(self, state: ContentState): + """Обработка preview состояния""" + + content = state.content + + # Проверка, что это действительно preview + if "preview" not in content.tags: + content.add_tag("preview") + + # Проверка размера (preview должен быть меньше оригинала) + if state.parent_id: + original_content = await StoredContent.get_by_id( + self.node.db_session, state.parent_id + ) + + if original_content and content.file_size >= original_content.file_size: + logger.warning(f"Preview size is not smaller than original: {content.id}") + + # Обработка preview контента + await self.process_preview_content(content) +``` + +## Node Status Monitoring + +### 1. Real-time Status Monitoring + +```python +class NodeStatusMonitor: + def __init__(self, node: MYNetworkNode): + self.node = node + self.status_data = {} + self.monitoring_interval = 30 # секунды + + async def start_monitoring(self): + """Запуск мониторинга статуса ноды""" + + # Запуск периодического сбора метрик + asyncio.create_task(self.collect_metrics_loop()) + + # Запуск health check'ов + asyncio.create_task(self.health_check_loop()) + + # Запуск отправки статуса в сеть + asyncio.create_task(self.broadcast_status_loop()) + + async def collect_current_status(self) -> dict: + """Сбор текущего статуса ноды""" + + return { + "node_id": self.node.node_id, + "uptime": self.get_uptime_seconds(), + "peer_count": len(self.node.peer_connections), + "content_count": await self.get_local_content_count(), + "storage_usage": await self.get_storage_usage(), + "network_stats": await self.get_network_stats(), + "sync_status": await self.get_sync_status(), + "resource_usage": await self.get_resource_usage(), + "timestamp": datetime.utcnow().isoformat() + } + + async def get_sync_status(self) -> dict: + """Получение статуса синхронизации""" + + return { + "is_syncing": self.node.sync_manager.is_syncing, + "sync_progress": self.node.sync_manager.get_progress(), + "last_sync": self.node.sync_manager.last_sync_time, + "pending_sync_items": self.node.sync_manager.get_pending_count(), + "sync_errors": self.node.sync_manager.get_error_count() + } +``` + +### 2. Node Performance Metrics + +```python +class NodePerformanceMetrics: + def __init__(self): + self.metrics_history = [] + self.max_history_size = 1000 + + async def collect_performance_metrics(self) -> dict: + """Сбор метрик производительности""" + + metrics = { + "cpu_usage": psutil.cpu_percent(), + "memory_usage": psutil.virtual_memory().percent, + "disk_usage": psutil.disk_usage('/').percent, + "network_io": await self.get_network_io_stats(), + "content_operations": await self.get_content_operations_stats(), + "p2p_performance": await self.get_p2p_performance_stats(), + "consensus_performance": await self.get_consensus_performance_stats() + } + + # Сохранение в историю + self.metrics_history.append({ + "timestamp": datetime.utcnow(), + "metrics": metrics + }) + + # Ограничение размера истории + if len(self.metrics_history) > self.max_history_size: + self.metrics_history.pop(0) + + return metrics + + async def get_p2p_performance_stats(self) -> dict: + """Статистика производительности P2P""" + + return { + "avg_latency": await self.calculate_avg_peer_latency(), + "message_throughput": await self.get_message_throughput(), + "connection_success_rate": await self.get_connection_success_rate(), + "bandwidth_usage": await self.get_bandwidth_usage() + } +``` + +## Configuration Management + +### 1. Dynamic Configuration + +```python +class NodeConfigManager: + def __init__(self, node: MYNetworkNode): + self.node = node + self.config_file = "node_config.json" + self.config_watchers = [] + + async def load_configuration(self) -> dict: + """Загрузка конфигурации ноды""" + + # Загрузка базовой конфигурации + base_config = await self.load_base_config() + + # Загрузка bootstrap конфигурации + bootstrap_config = await self.load_bootstrap_config() + + # Загрузка локальных настроек + local_config = await self.load_local_config() + + # Объединение конфигураций + merged_config = { + **base_config, + **bootstrap_config, + **local_config + } + + # Валидация конфигурации + await self.validate_configuration(merged_config) + + return merged_config + + async def update_configuration(self, new_config: dict): + """Обновление конфигурации на лету""" + + # Валидация новой конфигурации + await self.validate_configuration(new_config) + + # Создание backup старой конфигурации + old_config = self.node.config.copy() + + try: + # Применение новой конфигурации + self.node.config.update(new_config) + + # Уведомление watchers об изменениях + for watcher in self.config_watchers: + await watcher.on_config_changed(old_config, new_config) + + # Сохранение конфигурации + await self.save_configuration(new_config) + + except Exception as e: + # Откат к старой конфигурации в случае ошибки + self.node.config = old_config + raise ConfigurationError(f"Failed to update configuration: {e}") +``` + +Эта спецификация определяет полный жизненный цикл MY Network ноды от инициализации до мониторинга производительности, обеспечивая надежную работу в децентрализованной сети. \ No newline at end of file diff --git a/docs/MY_PROTOCOL.md b/docs/MY_PROTOCOL.md new file mode 100644 index 0000000..08d3853 --- /dev/null +++ b/docs/MY_PROTOCOL.md @@ -0,0 +1,265 @@ +# MY Network Protocol Specification + +## Обзор + +MY Network представляет собой децентрализованный overlay протокол для распределенной репликации и синхронизации контента поверх существующей системы my-uploader-bot. Протокол сохраняет все существующие состояния и функциональность, добавляя P2P синхронизацию с кворумным консенсусом. + +## Принципы Overlay Protocol + +### 1. Совместимость с Существующей Системой +- **Полное сохранение** всех состояний [`StoredContent`](app/core/models/content.py:61) +- **Неизменность** существующих API endpoints +- **Прозрачная интеграция** без нарушения работы текущих клиентов +- **Обратная совместимость** со всеми версиями API + +### 2. Состояния Контента в MY Network + +#### Поддерживаемые Состояния +``` +encrypted: Boolean - Статус шифрования контента +decrypted: Virtual - Расшифрованная версия (через decrypted_content_id) +preview: Virtual - Превью-версия для публичного доступа +``` + +MY Network реплицирует **все состояния** контента: +- **Encrypted Content** - зашифрованные данные с [`encryption_key_id`](app/core/models/content.py:157) +- **Decrypted Content** - расшифрованные версии через связи +- **Preview Content** - публичные превью для демонстрации +- **Metadata** - все метаданные включая теги, описание, медиа-информацию + +#### Связи Между Состояниями +```sql +-- Существующая структура StoredContent поддерживает связи +SELECT * FROM stored_content sc1 +LEFT JOIN stored_content sc2 ON sc1.decrypted_content_id = sc2.id; +``` + +### 3. P2P Синхронизация Architecture + +#### Кворумный Консенсус +``` +Минимальный кворум: 3 ноды +Консенсус требует: 2/3 + 1 подтверждений +Timeout для консенсуса: 30 секунд +``` + +#### Алгоритм Репликации +1. **Content Discovery** - обнаружение нового контента +2. **Integrity Check** - проверка целостности через хеш +3. **Quorum Voting** - голосование за принятие контента +4. **Replication** - репликация на кворум нод +5. **Confirmation** - подтверждение успешной репликации + +### 4. Bootstrap Configuration + +#### Структура bootstrap.json +```json +{ + "version": "1.0.0", + "network_id": "my-network-mainnet", + "bootstrap_nodes": [ + { + "id": "node-001", + "address": "my://192.168.1.100:8080", + "public_key": "ed25519:AAAA...", + "region": "eu-west-1", + "weight": 100 + } + ], + "consensus": { + "min_quorum": 3, + "consensus_threshold": 0.67, + "timeout_seconds": 30, + "retry_attempts": 3 + }, + "sync_settings": { + "sync_interval": 60, + "max_batch_size": 100, + "compression": "gzip", + "encryption": "aes-256-gcm" + } +} +``` + +## API Endpoints для MY Network + +### Core MY Protocol Endpoints + +#### Node Management +``` +GET /api/my/node/status - Статус текущей ноды +GET /api/my/node/peers - Список подключенных пиров +POST /api/my/node/connect - Подключение к новому пиру +POST /api/my/node/disconnect - Отключение от пира +``` + +#### Content Synchronization +``` +GET /api/my/sync/status - Статус синхронизации +POST /api/my/sync/request - Запрос синхронизации контента +GET /api/my/sync/conflicts - Список конфликтов синхронизации +POST /api/my/sync/resolve - Разрешение конфликтов +``` + +#### Quorum & Consensus +``` +GET /api/my/quorum/status - Статус кворума +POST /api/my/quorum/vote - Голосование за контент +GET /api/my/quorum/results - Результаты голосования +POST /api/my/consensus/propose - Предложение изменений +``` + +#### Content Distribution +``` +GET /api/my/content/{hash} - Получение контента через MY Network +GET /api/my/content/{hash}/peers - Список пиров с контентом +POST /api/my/content/announce - Анонс нового контента +GET /api/my/content/search - Поиск контента в сети +``` + +### Integration API Endpoints + +#### Health Check & Discovery +``` +GET /api/my/health - Проверка здоровья MY ноды +GET /api/my/discovery/nodes - Обнаружение новых нод +POST /api/my/discovery/announce - Анонс собственной ноды +``` + +#### Metrics & Analytics +``` +GET /api/my/metrics/network - Метрики сети +GET /api/my/metrics/content - Метрики контента +GET /api/my/metrics/performance - Метрики производительности +``` + +## Protocol Messages + +### MY Network Message Types + +#### Node Communication +```protobuf +message NodeHandshake { + string node_id = 1; + string public_key = 2; + string network_version = 3; + repeated string supported_features = 4; + int64 timestamp = 5; +} + +message PeerInfo { + string node_id = 1; + string address = 2; + int32 connection_count = 3; + int64 last_seen = 4; + float reputation_score = 5; +} +``` + +#### Content Sync Messages +```protobuf +message ContentAnnouncement { + string content_hash = 1; + int64 file_size = 2; + string content_type = 3; + bool encrypted = 4; + string encryption_key_id = 5; + repeated string tags = 6; + int64 timestamp = 7; +} + +message SyncRequest { + repeated string content_hashes = 1; + string requesting_node = 2; + int32 priority = 3; + int64 timestamp = 4; +} +``` + +#### Consensus Messages +```protobuf +message QuorumVote { + string content_hash = 1; + string voter_node_id = 2; + bool vote = 3; // true = accept, false = reject + string signature = 4; + int64 timestamp = 5; +} + +message ConsensusResult { + string content_hash = 1; + int32 votes_for = 2; + int32 votes_against = 3; + bool consensus_reached = 4; + repeated string participating_nodes = 5; +} +``` + +## Security Model + +### Cryptographic Security +- **Node Identity**: Ed25519 ключи для идентификации нод +- **Message Signing**: Все сообщения подписываются отправителем +- **Content Integrity**: SHA-256 хеши для проверки целостности +- **Transport Security**: TLS 1.3 для всех сетевых соединений + +### Access Control +- **Content Access**: Сохранение существующих прав доступа +- **Network Participation**: Whitelist/blacklist механизмы +- **Rate Limiting**: Защита от спама и DoS атак +- **Reputation System**: Система репутации для узлов + +## MY Network Service Layer + +### Service Architecture +``` +┌─────────────────────┐ +│ Existing API │ <- Без изменений +├─────────────────────┤ +│ MY Network Layer │ <- Новый overlay слой +├─────────────────────┤ +│ StoredContent │ <- Существующая модель +└─────────────────────┘ +``` + +### Service Components +- **MY Node Manager** - управление статусом ноды +- **P2P Communication** - межузловое взаимодействие +- **Content Replicator** - репликация контента +- **Consensus Engine** - механизм консенсуса +- **Sync Coordinator** - координация синхронизации + +## Performance Considerations + +### Scalability Targets +- **Network Size**: До 1000 активных нод +- **Content Volume**: До 10TB на ноду +- **Sync Throughput**: 100 MB/s между нодами +- **Consensus Latency**: < 5 секунд для кворума + +### Optimization Strategies +- **Content Chunking** - разбиение больших файлов +- **Delta Sync** - синхронизация только изменений +- **Compression** - сжатие передаваемых данных +- **Caching** - кеширование популярного контента +- **Load Balancing** - балансировка нагрузки между нодами + +## Future Roadmap + +### Phase 1: Core Protocol (Q1 2025) +- [x] Protocol specification +- [ ] Basic P2P communication +- [ ] Simple consensus mechanism +- [ ] Bootstrap node implementation + +### Phase 2: Advanced Features (Q2 2025) +- [ ] Content deduplication +- [ ] Advanced routing algorithms +- [ ] Performance optimizations +- [ ] Monitoring and analytics + +### Phase 3: Enterprise Features (Q3 2025) +- [ ] Multi-region replication +- [ ] Enterprise security features +- [ ] SLA guarantees +- [ ] Professional support tools \ No newline at end of file diff --git a/docs/QUICK_START_RU.md b/docs/QUICK_START_RU.md new file mode 100644 index 0000000..13d6e9e --- /dev/null +++ b/docs/QUICK_START_RU.md @@ -0,0 +1,84 @@ +# 🚀 MY Network - Быстрый старт + +## ⚡ Установка в две команды + +### 📋 Требования +- **Сервер:** Ubuntu 20.04+ / Debian 11+ +- **Права:** Root доступ +- **Домен:** Настроенный A-запись +- **Email:** Для SSL сертификата + +--- + +## 🥇 Команда 1: Установка сервиса + +```bash +curl -O https://raw.githubusercontent.com/your-repo/my-uploader-bot/main/install_service.sh +sudo bash install_service.sh +``` + +**Что происходит:** +- ✅ Обновление системы +- ✅ Установка Docker, Python, зависимостей +- ✅ Настройка MY Network сервиса +- ✅ Запуск на порту 15100 +- ✅ Создание systemd сервиса + +**Результат:** Базовый сервис работает на `http://your-server:15100` + +--- + +## 🥈 Команда 2: Защита и SSL + +```bash +sudo bash secure_service.sh +``` + +**Что происходит:** +- 🔒 SSL сертификат (Let's Encrypt) +- 🌐 Настройка Nginx с proxy +- 🔥 Настройка UFW firewall +- 🚫 Установка Fail2ban +- 📊 Система мониторинга + +**Результат:** Защищенный сервис на `https://your-domain.com` + +--- + +## 🎯 Проверка работы + +```bash +# Проверка API +curl https://your-domain.com/api/my/health + +# Веб-мониторинг +https://your-domain.com/api/my/monitor/ + +# Статус сервисов +systemctl status my-network nginx fail2ban +``` + +--- + +## 📚 Полная документация + +- **[DOCS_RU.md](DOCS_RU.md)** - Полная документация с архитектурой +- **[MY_NETWORK_README.md](MY_NETWORK_README.md)** - Техническое описание +- **[bootstrap.json](bootstrap.json)** - Конфигурация сети + +--- + +## 🆘 Поддержка + +```bash +# Логи +journalctl -u my-network -f + +# Конфигурация +cat /opt/my-network-config.txt + +# Перезапуск +systemctl restart my-network nginx +``` + +**Готово!** 🎉 Ваша MY Network работает и защищена! \ No newline at end of file diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..b98ce22 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,504 @@ +# My Uploader Bot - Comprehensive File Upload & Blockchain Integration System + +A modern, scalable file upload and management system with blockchain integration, built with async Python and enterprise-grade security. + +## 🚀 Features + +### Core Features +- **Chunked File Upload**: Support for large files with resume capability +- **Multi-Storage Backend**: Local, S3-compatible storage with automatic failover +- **File Processing**: Automatic image optimization, thumbnail generation, media conversion +- **Content Management**: Version control, metadata management, search functionality +- **User Management**: JWT authentication, API keys, session management + +### Blockchain Integration +- **TON Blockchain**: Wallet creation, transaction management, balance tracking +- **Smart Contracts**: Interaction with TON smart contracts +- **NFT Support**: NFT collection indexing and management +- **DeFi Integration**: Staking positions, token balances, yield farming + +### Enterprise Features +- **Security**: Rate limiting, CORS, CSP, input validation, file encryption +- **Monitoring**: Prometheus metrics, Grafana dashboards, health checks +- **Caching**: Redis integration with intelligent cache management +- **Background Services**: Async task processing, blockchain indexing +- **API Documentation**: OpenAPI/Swagger with interactive interface + +## 🏗️ Architecture + +### Technology Stack +- **Backend**: Python 3.11+, Sanic (async web framework) +- **Database**: PostgreSQL 15+ with async SQLAlchemy 2.0 +- **Cache**: Redis 7+ with connection pooling +- **Blockchain**: TON SDK for blockchain operations +- **Storage**: Local filesystem with S3-compatible support +- **Monitoring**: Prometheus, Grafana, structured logging +- **Deployment**: Docker Compose with multi-stage builds + +### System Architecture +``` +┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ +│ Load Balancer │ │ Grafana │ │ Prometheus │ +│ (Nginx) │ │ (Monitoring) │ │ (Metrics) │ +└─────────────────┘ └─────────────────┘ └─────────────────┘ + │ │ │ + ▼ ▼ ▼ +┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ +│ Sanic App │◄──►│ Redis │ │ PostgreSQL │ +│ (API Server) │ │ (Cache) │ │ (Database) │ +└─────────────────┘ └─────────────────┘ └─────────────────┘ + │ │ │ + ▼ ▼ ▼ +┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ +│ Background │ │ File Storage │ │ TON Blockchain │ +│ Services │ │ (Local/S3/CDN) │ │ Integration │ +└─────────────────┘ └─────────────────┘ └─────────────────┘ +``` + +## 🔧 Installation & Setup + +### Prerequisites +- Python 3.11+ +- PostgreSQL 15+ +- Redis 7+ +- Docker & Docker Compose (recommended) + +### Quick Start with Docker + +1. **Clone the repository**: +```bash +git clone https://github.com/your-org/my-uploader-bot.git +cd my-uploader-bot +``` + +2. **Create environment file**: +```bash +cp .env.example .env +# Edit .env with your configuration +``` + +3. **Start services**: +```bash +docker-compose -f docker-compose.new.yml up -d +``` + +4. **Initialize database**: +```bash +docker-compose -f docker-compose.new.yml exec app alembic upgrade head +``` + +5. **Create admin user**: +```bash +docker-compose -f docker-compose.new.yml exec app python -m app.scripts.create_admin +``` + +### Manual Installation + +1. **Install dependencies**: +```bash +# Using Poetry (recommended) +poetry install + +# Or using pip +pip install -r requirements_new.txt +``` + +2. **Set up database**: +```bash +# Create database +createdb myuploader + +# Run migrations +alembic upgrade head +``` + +3. **Configure Redis**: +```bash +# Start Redis with custom config +redis-server config/redis.conf +``` + +4. **Start application**: +```bash +# Development mode +python -m app + +# Production mode +gunicorn app:create_app --bind 0.0.0.0:8000 --worker-class sanic.worker.GunicornWorker +``` + +## ⚙️ Configuration + +### Environment Variables + +**Database Configuration**: +```bash +DATABASE_URL=postgresql+asyncpg://user:password@localhost:5432/myuploader +DB_POOL_SIZE=20 +DB_MAX_OVERFLOW=30 +``` + +**Redis Configuration**: +```bash +REDIS_URL=redis://localhost:6379/0 +REDIS_POOL_SIZE=20 +REDIS_POOL_MAX_CONNECTIONS=100 +``` + +**Security Configuration**: +```bash +SECRET_KEY=your-super-secret-key-here +JWT_SECRET_KEY=your-jwt-secret-key +JWT_ACCESS_TOKEN_EXPIRE_MINUTES=30 +JWT_REFRESH_TOKEN_EXPIRE_DAYS=7 +``` + +**Storage Configuration**: +```bash +STORAGE_BACKEND=local # or s3, gcs, azure +STORAGE_PATH=/app/uploads +MAX_FILE_SIZE=104857600 # 100MB +ALLOWED_FILE_TYPES=image,video,audio,document +``` + +**Blockchain Configuration**: +```bash +TON_NETWORK=mainnet # or testnet +TON_API_KEY=your-ton-api-key +TON_WALLET_VERSION=v4 +``` + +### Configuration Files + +**Redis Configuration** (`config/redis.conf`): +- Optimized for caching workload +- Memory management and persistence settings +- Security and performance tuning + +**Prometheus Configuration** (`monitoring/prometheus.yml`): +- Scraping configuration for all services +- Alert rules and metric collection +- Storage and retention settings + +## 📊 API Documentation + +### Interactive Documentation +- **Swagger UI**: http://localhost:8000/docs +- **ReDoc**: http://localhost:8000/redoc +- **OpenAPI JSON**: http://localhost:8000/openapi.json + +### Authentication Methods + +1. **JWT Bearer Token**: +```bash +curl -H "Authorization: Bearer " \ + https://api.myuploader.com/api/v1/content/ +``` + +2. **API Key**: +```bash +curl -H "X-API-Key: " \ + https://api.myuploader.com/api/v1/content/ +``` + +3. **Session Cookie**: +```bash +curl -b "session=" \ + https://api.myuploader.com/api/v1/content/ +``` + +### Key Endpoints + +**Authentication**: +- `POST /api/v1/auth/register` - User registration +- `POST /api/v1/auth/login` - User login +- `POST /api/v1/auth/refresh` - Token refresh +- `DELETE /api/v1/auth/logout` - User logout + +**Content Management**: +- `GET /api/v1/content/` - List content +- `POST /api/v1/content/` - Create content +- `GET /api/v1/content/{id}` - Get content details +- `PUT /api/v1/content/{id}` - Update content +- `DELETE /api/v1/content/{id}` - Delete content + +**File Upload**: +- `POST /api/v1/storage/upload/initiate` - Start upload +- `POST /api/v1/storage/upload/chunk` - Upload chunk +- `POST /api/v1/storage/upload/complete` - Complete upload +- `GET /api/v1/storage/download/{id}` - Download file + +**Blockchain**: +- `POST /api/v1/blockchain/wallet/create` - Create wallet +- `GET /api/v1/blockchain/wallet/{id}` - Get wallet info +- `POST /api/v1/blockchain/transaction/send` - Send transaction +- `GET /api/v1/blockchain/transaction/{hash}` - Get transaction status + +## 🛡️ Security + +### Security Features +- **Authentication**: Multi-factor authentication support +- **Authorization**: Role-based access control (RBAC) +- **Input Validation**: Comprehensive request validation +- **Rate Limiting**: Per-user and per-endpoint limits +- **File Security**: Virus scanning, type validation, encryption +- **Network Security**: CORS, CSP, HTTPS enforcement + +### Security Best Practices + +1. **Environment Variables**: Store sensitive data in environment variables +2. **Database Security**: Use connection pooling, parameterized queries +3. **File Upload Security**: Validate file types, scan for malware +4. **API Security**: Implement rate limiting, request validation +5. **Monitoring**: Track security events and anomalies + +### Audit Logging +All security-relevant events are logged: +- Authentication attempts +- Authorization failures +- File upload/download events +- API key usage +- Blockchain transactions + +## 📈 Monitoring & Observability + +### Metrics Collection +- **Application Metrics**: Request counts, response times, error rates +- **System Metrics**: CPU, memory, disk usage +- **Database Metrics**: Connection pool, query performance +- **Cache Metrics**: Hit rates, memory usage +- **Blockchain Metrics**: Transaction status, wallet balances + +### Dashboards +- **Application Dashboard**: Request metrics, error rates +- **Infrastructure Dashboard**: System resources, service health +- **Database Dashboard**: Query performance, connection pools +- **Security Dashboard**: Failed logins, rate limits + +### Alerting Rules +- High error rates (>5% for 5 minutes) +- High response times (>2s for 95th percentile) +- Database connection issues +- High memory usage (>90%) +- Failed blockchain transactions + +## 🔄 Background Services + +### File Conversion Service +- **Image Processing**: Resize, optimize, generate thumbnails +- **Video Processing**: Transcode, extract thumbnails +- **Document Processing**: Extract metadata, generate previews +- **Retry Logic**: Automatic retry for failed conversions + +### Blockchain Indexer Service +- **Transaction Monitoring**: Track pending transactions +- **Wallet Balance Updates**: Sync wallet balances +- **NFT Indexing**: Track NFT collections and transfers +- **Event Processing**: Process blockchain events + +## 🚀 Deployment + +### Docker Deployment + +1. **Production Build**: +```bash +docker build -f Dockerfile.new --target production -t my-uploader-bot:latest . +``` + +2. **Deploy with Compose**: +```bash +docker-compose -f docker-compose.new.yml up -d +``` + +3. **Health Checks**: +```bash +curl http://localhost:8000/health +``` + +### Kubernetes Deployment + +1. **Create ConfigMaps**: +```bash +kubectl create configmap app-config --from-env-file=.env +``` + +2. **Deploy Application**: +```bash +kubectl apply -f k8s/ +``` + +3. **Check Status**: +```bash +kubectl get pods -l app=my-uploader-bot +``` + +### Production Considerations + +1. **Database**: Use managed PostgreSQL service +2. **Cache**: Use managed Redis service +3. **Storage**: Use S3-compatible object storage +4. **Load Balancer**: Use cloud load balancer +5. **SSL/TLS**: Use Let's Encrypt or cloud SSL +6. **Monitoring**: Use managed monitoring service + +## 🧪 Testing + +### Running Tests +```bash +# Run all tests +pytest + +# Run with coverage +pytest --cov=app + +# Run specific test file +pytest tests/test_auth.py + +# Run integration tests +pytest tests/integration/ +``` + +### Test Categories +- **Unit Tests**: Individual function/method tests +- **Integration Tests**: Service integration tests +- **API Tests**: HTTP endpoint tests +- **Database Tests**: Database operation tests +- **Security Tests**: Security vulnerability tests + +## 🔍 Development + +### Development Setup +```bash +# Install dev dependencies +poetry install --dev + +# Pre-commit hooks +pre-commit install + +# Run linting +black app/ +isort app/ +mypy app/ + +# Database migrations +alembic revision --autogenerate -m "Description" +alembic upgrade head +``` + +### Code Quality Tools +- **Black**: Code formatting +- **isort**: Import sorting +- **mypy**: Type checking +- **bandit**: Security scanning +- **pytest**: Testing framework + +### Contributing Guidelines +1. Fork the repository +2. Create feature branch +3. Write tests for new features +4. Ensure all tests pass +5. Run security scans +6. Submit pull request + +## 📝 Migration Guide + +### From v1.x to v2.x + +1. **Database Migration**: +```bash +# Backup existing database +pg_dump myuploader > backup.sql + +# Run new migrations +alembic upgrade head +``` + +2. **Configuration Updates**: +- Update environment variables +- Migrate Redis configuration +- Update storage configuration + +3. **API Changes**: +- Authentication endpoints changed +- New blockchain endpoints added +- Response format updates + +## 🐛 Troubleshooting + +### Common Issues + +**Database Connection Issues**: +```bash +# Check database connectivity +psql -h localhost -U postgres -d myuploader + +# Check connection pool +docker-compose logs db +``` + +**Redis Connection Issues**: +```bash +# Test Redis connection +redis-cli ping + +# Check Redis logs +docker-compose logs redis +``` + +**File Upload Issues**: +```bash +# Check storage permissions +ls -la /app/uploads + +# Check disk space +df -h +``` + +**Blockchain Issues**: +```bash +# Check TON network status +curl https://toncenter.com/api/v2/getAddressInformation + +# Check wallet balance +curl -X GET /api/v1/blockchain/wallet/{wallet_id} +``` + +### Performance Optimization + +1. **Database Optimization**: + - Add indexes for frequently queried columns + - Optimize query patterns + - Use connection pooling + +2. **Cache Optimization**: + - Implement cache warming + - Use appropriate TTL values + - Monitor cache hit rates + +3. **File Storage Optimization**: + - Use CDN for static files + - Implement file compression + - Use efficient storage backends + +## 📚 Additional Resources + +- **API Documentation**: https://docs.myuploader.com +- **SDK Documentation**: https://sdk.myuploader.com +- **Community Forum**: https://community.myuploader.com +- **GitHub Repository**: https://github.com/your-org/my-uploader-bot +- **Docker Images**: https://hub.docker.com/r/myuploader/app + +## 📄 License + +This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. + +## 🤝 Support + +- **Email**: support@myuploader.com +- **Discord**: https://discord.gg/myuploader +- **GitHub Issues**: https://github.com/your-org/my-uploader-bot/issues +- **Documentation**: https://docs.myuploader.com + +--- + +**Built with ❤️ by the My Uploader Bot Team** diff --git a/README_COMPATIBLE_UPDATE.md b/docs/README_COMPATIBLE_UPDATE.md similarity index 100% rename from README_COMPATIBLE_UPDATE.md rename to docs/README_COMPATIBLE_UPDATE.md diff --git a/docs/REMOTE_DIAGNOSIS_GUIDE.md b/docs/REMOTE_DIAGNOSIS_GUIDE.md new file mode 100644 index 0000000..1fb8d27 --- /dev/null +++ b/docs/REMOTE_DIAGNOSIS_GUIDE.md @@ -0,0 +1,139 @@ +# Руководство по удаленной диагностике MY Network сервера + +## Проблема +- SSH недоступен на порту 22 (Connection refused) +- Nginx работает на порту 80, но возвращает 404 для всех запросов +- Приложения на портах 3000, 5000, 8080 недоступны + +## Диагностика на сервере (выполнить локально) + +### 1. Проверить статус служб +```bash +# Проверить статус Docker +sudo systemctl status docker + +# Проверить статус MyUploader service +sudo systemctl status myuploader + +# Проверить запущенные контейнеры +sudo docker ps -a + +# Проверить логи контейнеров +sudo docker logs uploader-bot-app-1 +sudo docker logs uploader-bot-postgres-1 +sudo docker logs uploader-bot-nginx-1 +``` + +### 2. Проверить сетевые соединения +```bash +# Проверить какие порты слушает система +sudo netstat -tulpn | grep LISTEN + +# Проверить статус nginx +sudo nginx -t +sudo systemctl status nginx + +# Проверить конфигурацию nginx +sudo cat /etc/nginx/sites-enabled/default +``` + +### 3. Проверить Docker Compose +```bash +# Перейти в директорию проекта +cd /home/myuploader/my-uploader-bot + +# Проверить статус compose +sudo docker-compose -f docker-compose.production.yml ps + +# Посмотреть логи всех сервисов +sudo docker-compose -f docker-compose.production.yml logs --tail=50 + +# Перезапустить сервисы +sudo docker-compose -f docker-compose.production.yml down +sudo docker-compose -f docker-compose.production.yml up -d +``` + +### 4. Проверить SSH +```bash +# Проверить статус SSH +sudo systemctl status ssh + +# Проверить конфигурацию SSH +sudo cat /etc/ssh/sshd_config | grep -E "Port|PasswordAuthentication|PubkeyAuthentication" + +# Перезапустить SSH если нужно +sudo systemctl restart ssh +``` + +### 5. Проверить брандмауэр +```bash +# Проверить статус UFW +sudo ufw status + +# Если UFW активен, проверить правила +sudo ufw status numbered + +# Разрешить SSH (если заблокирован) +sudo ufw allow 22/tcp +``` + +### 6. Быстрое восстановление +```bash +# Если сервисы не работают, запустить быстрое восстановление +cd /home/myuploader/my-uploader-bot +sudo ./diagnose.sh + +# Проверить health API приложения +curl -I http://localhost:3000/api/health +curl -I http://localhost:5000/api/health +``` + +## Возможные решения + +### Проблема с nginx proxy +Если nginx возвращает 404, проверить файл `/etc/nginx/sites-enabled/default`: +```bash +sudo cat /etc/nginx/sites-enabled/default +``` + +Должен содержать: +```nginx +location /api/ { + proxy_pass http://localhost:3000/api/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; +} +``` + +### Проблема с Docker +Если контейнеры не запущены: +```bash +cd /home/myuploader/my-uploader-bot +sudo docker-compose -f docker-compose.production.yml up -d --build +``` + +### Проблема с SSH +Если SSH заблокирован файрволлом: +```bash +sudo ufw allow 22/tcp +sudo systemctl restart ssh +``` + +## Команды для отправки результатов +После выполнения диагностики, отправьте результаты: + +```bash +# Сохранить всю диагностику в файл +echo "=== DOCKER STATUS ===" > diagnosis.txt +sudo docker ps -a >> diagnosis.txt +echo "=== DOCKER LOGS ===" >> diagnosis.txt +sudo docker-compose -f docker-compose.production.yml logs --tail=20 >> diagnosis.txt +echo "=== NGINX STATUS ===" >> diagnosis.txt +sudo systemctl status nginx >> diagnosis.txt +echo "=== SSH STATUS ===" >> diagnosis.txt +sudo systemctl status ssh >> diagnosis.txt +echo "=== NETWORK PORTS ===" >> diagnosis.txt +sudo netstat -tulpn | grep LISTEN >> diagnosis.txt + +# Просмотреть файл +cat diagnosis.txt \ No newline at end of file diff --git a/docs/TROUBLESHOOTING_502.md b/docs/TROUBLESHOOTING_502.md new file mode 100644 index 0000000..47aefad --- /dev/null +++ b/docs/TROUBLESHOOTING_502.md @@ -0,0 +1,157 @@ +# Устранение 502 ошибки MY Uploader Bot + +## 🚨 Если получаете 502 Bad Gateway + +Ошибка 502 означает, что nginx работает, но не может подключиться к backend приложению. + +## 🔍 Быстрая диагностика + +### 1. Запустите диагностический скрипт: +```bash +sudo /home/myuploader/uploader-bot/diagnose.sh my-public-node-3.projscale.dev +``` + +### 2. Проверьте статус контейнеров: +```bash +cd /home/myuploader/uploader-bot +sudo docker-compose -f docker-compose.production.yml ps +``` + +### 3. Проверьте логи приложения: +```bash +sudo docker-compose -f docker-compose.production.yml logs -f app +``` + +## 🛠️ Частые решения + +### Решение 1: Приложение еще запускается +```bash +# Подождите 2-3 минуты и проверьте снова +sleep 180 +curl -v https://your-domain.com/health +``` + +### Решение 2: Перезапуск сервисов +```bash +cd /home/myuploader/uploader-bot +sudo docker-compose -f docker-compose.production.yml restart app +``` + +### Решение 3: Полная перезагрузка +```bash +cd /home/myuploader/uploader-bot +sudo docker-compose -f docker-compose.production.yml down +sudo docker-compose -f docker-compose.production.yml up -d +``` + +### Решение 4: Проверка базы данных +```bash +# Проверка PostgreSQL +sudo docker-compose -f docker-compose.production.yml exec postgres pg_isready -U my_user -d my_uploader_db + +# Перезапуск базы данных если нужно +sudo docker-compose -f docker-compose.production.yml restart postgres redis +``` + +## 🔍 Детальная диагностика + +### Проверка локальных портов: +```bash +# API приложения (должен отвечать) +curl http://localhost:15100/health + +# Nginx (должен перенаправлять) +curl -I http://localhost + +# Проверка подключения к базе +sudo docker-compose -f docker-compose.production.yml exec app python -c " +import asyncpg +import asyncio +async def test(): + try: + conn = await asyncpg.connect('postgresql://my_user:PASSWORD@postgres:5432/my_uploader_db') + await conn.close() + print('✅ База данных доступна') + except Exception as e: + print(f'❌ Ошибка подключения к БД: {e}') +asyncio.run(test()) +" +``` + +### Проверка конфигурации nginx: +```bash +sudo docker-compose -f docker-compose.production.yml exec nginx nginx -t +``` + +### Просмотр логов в реальном времени: +```bash +# Все сервисы +sudo docker-compose -f docker-compose.production.yml logs -f + +# Только основное приложение +sudo docker-compose -f docker-compose.production.yml logs -f app + +# Только nginx +sudo docker-compose -f docker-compose.production.yml logs -f nginx +``` + +## 🚀 Тестирование после исправления + +```bash +# 1. Проверьте статус всех контейнеров +sudo docker-compose -f docker-compose.production.yml ps + +# 2. Проверьте health endpoints +curl http://localhost:15100/health +curl https://your-domain.com/health + +# 3. Проверьте основные endpoints +curl -I https://your-domain.com/ +curl https://your-domain.com/api/my/bootstrap/config +``` + +## 📞 Если проблема не решается + +1. **Соберите диагностическую информацию:** +```bash +sudo /home/myuploader/uploader-bot/diagnose.sh your-domain.com > diagnostic_report.txt +``` + +2. **Сохраните логи:** +```bash +sudo docker-compose -f docker-compose.production.yml logs --tail=100 > all_logs.txt +``` + +3. **Проверьте ресурсы системы:** +```bash +docker stats --no-stream +df -h +free -h +``` + +## ⚡ Экстренное восстановление + +Если ничего не помогает: + +```bash +# 1. Полная остановка +sudo systemctl stop my-uploader-bot +sudo docker-compose -f docker-compose.production.yml down -v + +# 2. Очистка и перезапуск +sudo docker system prune -f +sudo docker-compose -f docker-compose.production.yml pull +sudo docker-compose -f docker-compose.production.yml up -d --build + +# 3. Проверка через 5 минут +sleep 300 +curl -v https://your-domain.com/health +``` + +## 🎯 Ожидаемый результат + +После успешного исправления: +- `curl http://localhost:15100/health` возвращает 200 OK +- `curl https://your-domain.com/health` возвращает 200 OK +- Все контейнеры в статусе "Up" +- В логах нет критических ошибок \ No newline at end of file diff --git a/docs/archive/test.ipynb b/docs/archive/test.ipynb new file mode 100644 index 0000000..bc98f2c --- /dev/null +++ b/docs/archive/test.ipynb @@ -0,0 +1,152 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from tonsdk.boc import Cell\n", + "from base64 import b64decode" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "s = Cell.one_from_boc(b64decode(\n", + " \"te6cckECCwEAAWcAAotUkdCMcWNw723qPXgUdCcgt8COtmF/zIqTQpNUO7Hx3cFkE6SAHuuAXC2ImbR2RbW6eaLmYTaiOFzd06Q3v6GEw1xpHOswAQUCAaACAwALAECPDRgIAQHRBABHgB7rgFwtiJm0dkW1unmi5mE2ojhc3dOkN7+hhMNcaRzrJOIQAgAGBwD6aHR0cHM6Ly9teS1wdWJsaWMtbm9kZS0xLnByb2pzY2FsZS5kZXYvYXBpL3YxLjUvc3RvcmFnZS85S0h5RHAyYUppRTRuaG1uOExxazd4dmZxeWpwQXdXR1dYU2ozMkNVQW04V3NLdVFLSkJlTktIV0prZzhyZFloTm82MzcDAAgJCgBYajZGa3ZtREN1RUJhOHhrTDlpV1NSem1peXAxSGhYMlJkUFNFWWZpb1JRMWgAAABYblJUVW96dGJBcXF0Z25EWEN1cFU4UXRZWmFtY1dxdjlSTDQ0UURYbVpvQVbtCcTY\"\n", + "))" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "s = s.begin_parse()" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'AddressEQD3XALhbETNo7ItrdPNFzMJtRHC5u6dIb39DCYa40jnWcql'" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "s.read_uint(32)\n", + "s.read_uint(256)\n", + "'Address' + s.read_msg_addr().to_string(1, 1, 1)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "ename": "ValueError", + "evalue": "invalid literal for int() with base 10: 'b'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[7], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mAddress\u001b[39m\u001b[38;5;124m'\u001b[39m \u001b[38;5;241m+\u001b[39m s\u001b[38;5;241m.\u001b[39mread_msg_addr()\u001b[38;5;241m.\u001b[39mto_string(\u001b[38;5;241m1\u001b[39m, \u001b[38;5;241m1\u001b[39m, \u001b[38;5;241m1\u001b[39m)\n", + "File \u001b[0;32m/opt/anaconda3/lib/python3.12/site-packages/tonsdk/boc/_slice.py:93\u001b[0m, in \u001b[0;36mSlice.read_msg_addr\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 91\u001b[0m workchain_id \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mhex\u001b[39m(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mread_int(\u001b[38;5;241m8\u001b[39m))\u001b[38;5;241m.\u001b[39mreplace(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m0x\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 92\u001b[0m hashpart \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mread_bytes(\u001b[38;5;241m32\u001b[39m)\u001b[38;5;241m.\u001b[39mhex()\n\u001b[0;32m---> 93\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m Address(workchain_id \u001b[38;5;241m+\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m:\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;241m+\u001b[39m hashpart)\n", + "File \u001b[0;32m/opt/anaconda3/lib/python3.12/site-packages/tonsdk/utils/_address.py:87\u001b[0m, in \u001b[0;36mAddress.__init__\u001b[0;34m(self, any_form)\u001b[0m\n\u001b[1;32m 84\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(arr) \u001b[38;5;241m!=\u001b[39m \u001b[38;5;241m2\u001b[39m:\n\u001b[1;32m 85\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m InvalidAddressError(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mInvalid address \u001b[39m\u001b[38;5;132;01m{\u001b[39;00many_form\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m---> 87\u001b[0m wc \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mint\u001b[39m(arr[\u001b[38;5;241m0\u001b[39m])\n\u001b[1;32m 88\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m wc \u001b[38;5;241m!=\u001b[39m \u001b[38;5;241m0\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m wc \u001b[38;5;241m!=\u001b[39m \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m:\n\u001b[1;32m 89\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m InvalidAddressError(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mInvalid address wc \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mwc\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n", + "\u001b[0;31mValueError\u001b[0m: invalid literal for int() with base 10: 'b'" + ] + } + ], + "source": [ + "'Address' + s.read_msg_addr().to_string(1, 1, 1)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "s = Cell.one_from_boc('b5ee9c7201020b0100016700028b5491d08c716370ef6dea3d7814742720b7c08eb6617fcc8a934293543bb1f1ddc16413a4801eeb805c2d8899b47645b5ba79a2e66136a2385cddd3a437bfa184c35c691ceb3001020201a0030402000607000b00408f0d18080101d1050047801eeb805c2d8899b47645b5ba79a2e66136a2385cddd3a437bfa184c35c691ceb24e21000fa68747470733a2f2f6d792d7075626c69632d6e6f64652d312e70726f6a7363616c652e6465762f6170692f76312e352f73746f726167652f394b4879447032614a6945346e686d6e384c716b3778766671796a70417757475758536a33324355416d3857734b75514b4a42654e4b48574a6b6738726459684e6f363337030008090a00586a36466b766d44437545426138786b4c39695753527a6d697970314868583252645053455966696f52513168000000586e5254556f7a746241717174676e445843757055385174595a616d6357717639524c34345144586d5a6f4156')\n", + "s = s.begin_parse()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\n", + "s.read_uint(256)\n", + "s.read_uint(2)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'0b11'" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bin(3)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.7" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/uploader_test.html b/docs/archive/uploader_test.html similarity index 100% rename from uploader_test.html rename to docs/archive/uploader_test.html diff --git a/auto_deploy.sh b/scripts/auto_deploy.sh similarity index 100% rename from auto_deploy.sh rename to scripts/auto_deploy.sh diff --git a/auto_ssh_deploy.exp b/scripts/auto_ssh_deploy.exp similarity index 100% rename from auto_ssh_deploy.exp rename to scripts/auto_ssh_deploy.exp diff --git a/deploy_bootstrap_node.sh b/scripts/deploy_bootstrap_node.sh similarity index 100% rename from deploy_bootstrap_node.sh rename to scripts/deploy_bootstrap_node.sh diff --git a/deploy_my_network.sh b/scripts/deploy_my_network.sh similarity index 100% rename from deploy_my_network.sh rename to scripts/deploy_my_network.sh diff --git a/diagnose.sh b/scripts/diagnose.sh similarity index 100% rename from diagnose.sh rename to scripts/diagnose.sh diff --git a/fix_server_issues.sh b/scripts/fix_server_issues.sh similarity index 100% rename from fix_server_issues.sh rename to scripts/fix_server_issues.sh diff --git a/full_diagnosis.sh b/scripts/full_diagnosis.sh similarity index 100% rename from full_diagnosis.sh rename to scripts/full_diagnosis.sh diff --git a/install_service.sh b/scripts/install_service.sh similarity index 100% rename from install_service.sh rename to scripts/install_service.sh diff --git a/mariadb-healthcheck.sh b/scripts/mariadb-healthcheck.sh similarity index 100% rename from mariadb-healthcheck.sh rename to scripts/mariadb-healthcheck.sh diff --git a/monitor_deployment.sh b/scripts/monitor_deployment.sh similarity index 100% rename from monitor_deployment.sh rename to scripts/monitor_deployment.sh diff --git a/quick_check.sh b/scripts/quick_check.sh similarity index 100% rename from quick_check.sh rename to scripts/quick_check.sh diff --git a/secure_service.sh b/scripts/secure_service.sh similarity index 100% rename from secure_service.sh rename to scripts/secure_service.sh diff --git a/setup_minimal_service.sh b/scripts/setup_minimal_service.sh similarity index 100% rename from setup_minimal_service.sh rename to scripts/setup_minimal_service.sh diff --git a/setup_nginx_ssl.sh b/scripts/setup_nginx_ssl.sh similarity index 100% rename from setup_nginx_ssl.sh rename to scripts/setup_nginx_ssl.sh diff --git a/setup_production_server.sh b/scripts/setup_production_server.sh similarity index 100% rename from setup_production_server.sh rename to scripts/setup_production_server.sh diff --git a/setup_server_direct.sh b/scripts/setup_server_direct.sh similarity index 100% rename from setup_server_direct.sh rename to scripts/setup_server_direct.sh diff --git a/setup_simple_service.sh b/scripts/setup_simple_service.sh similarity index 100% rename from setup_simple_service.sh rename to scripts/setup_simple_service.sh diff --git a/setup_user_service.sh b/scripts/setup_user_service.sh similarity index 100% rename from setup_user_service.sh rename to scripts/setup_user_service.sh diff --git a/ssh_connect.exp b/scripts/ssh_connect.exp similarity index 100% rename from ssh_connect.exp rename to scripts/ssh_connect.exp diff --git a/universal_installer.sh b/universal_installer.sh new file mode 100644 index 0000000..fc1d2e3 --- /dev/null +++ b/universal_installer.sh @@ -0,0 +1,433 @@ +#!/bin/bash + +# MY NETWORK UNIVERSAL INSTALLER +# Универсальный установщик для любого сервера с автопоиском проекта и полной настройкой + +set -e + +echo "==================================================" +echo "🚀 MY NETWORK UNIVERSAL INSTALLER" +echo "Универсальная установка и восстановление сервера" +echo "==================================================" + +# Определение системы +OS_ID=$(lsb_release -i 2>/dev/null | cut -f2 || echo "unknown") +OS_VERSION=$(lsb_release -r 2>/dev/null | cut -f2 || echo "unknown") + +echo "🖥️ Система: $OS_ID $OS_VERSION" +echo "👤 Пользователь: $(whoami)" +echo "📁 Текущая директория: $(pwd)" + +# =========================== +# ПОИСК ПРОЕКТА +# =========================== +echo "" +echo "=== 1. ПОИСК ПРОЕКТА ===" + +PROJECT_LOCATIONS=( + "/home/myuploader/uploader-bot" + "/home/uploader-bot" + "/home/myuploader/my-uploader-bot" + "/root/uploader-bot" + "/root/my-uploader-bot" + "/opt/uploader-bot" + "/opt/my-uploader-bot" + "/var/www/uploader-bot" + "/var/www/my-uploader-bot" + "$(pwd)" + "$(pwd)/../uploader-bot" + "$(pwd)/../my-uploader-bot" +) + +PROJECT_DIR="" +COMPOSE_FILE="" + +echo "🔍 Поиск проекта в стандартных местах..." +for dir in "${PROJECT_LOCATIONS[@]}"; do + if [ -d "$dir" ]; then + for compose in "docker-compose.production.yml" "docker-compose.yml" "docker-compose.new.yml"; do + if [ -f "$dir/$compose" ]; then + PROJECT_DIR="$dir" + COMPOSE_FILE="$compose" + echo "✅ Проект найден: $PROJECT_DIR" + echo "✅ Compose файл: $COMPOSE_FILE" + break 2 + fi + done + fi +done + +if [ -z "$PROJECT_DIR" ]; then + echo "🔍 Глобальный поиск проекта..." + FOUND_PROJECTS=$(find / -name "docker-compose*.yml" -path "*/uploader-bot*" 2>/dev/null | head -3) + if [ -n "$FOUND_PROJECTS" ]; then + echo "Найдены проекты:" + echo "$FOUND_PROJECTS" + FIRST_FOUND=$(echo "$FOUND_PROJECTS" | head -1) + PROJECT_DIR=$(dirname "$FIRST_FOUND") + COMPOSE_FILE=$(basename "$FIRST_FOUND") + echo "✅ Выбран: $PROJECT_DIR" + else + echo "❌ Проект не найден автоматически!" + read -p "📝 Введите полный путь к директории проекта: " PROJECT_DIR + if [ ! -d "$PROJECT_DIR" ]; then + echo "❌ Директория не существует: $PROJECT_DIR" + exit 1 + fi + # Найти compose файл + for compose in "docker-compose.production.yml" "docker-compose.yml" "docker-compose.new.yml"; do + if [ -f "$PROJECT_DIR/$compose" ]; then + COMPOSE_FILE="$compose" + break + fi + done + if [ -z "$COMPOSE_FILE" ]; then + echo "❌ Docker compose файл не найден в $PROJECT_DIR" + exit 1 + fi + fi +fi + +cd "$PROJECT_DIR" +echo "📁 Работаю в: $(pwd)" + +# =========================== +# УСТАНОВКА ЗАВИСИМОСТЕЙ +# =========================== +echo "" +echo "=== 2. УСТАНОВКА СИСТЕМНЫХ ЗАВИСИМОСТЕЙ ===" + +# Обновление системы +echo "📦 Обновление системы..." +sudo apt update && sudo apt upgrade -y + +# Установка основных пакетов +echo "📦 Установка базовых пакетов..." +sudo apt install -y curl wget git nginx ufw fail2ban htop nano net-tools + +# Установка Docker +if ! command -v docker &> /dev/null; then + echo "🐳 Установка Docker..." + curl -fsSL https://get.docker.com -o get-docker.sh + sudo sh get-docker.sh + sudo usermod -aG docker $USER + rm get-docker.sh +else + echo "✅ Docker уже установлен: $(docker --version)" +fi + +# Установка Docker Compose +if ! command -v docker-compose &> /dev/null; then + echo "🐳 Установка Docker Compose..." + sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose + sudo chmod +x /usr/local/bin/docker-compose +else + echo "✅ Docker Compose уже установлен: $(docker-compose --version)" +fi + +# =========================== +# НАСТРОЙКА БЕЗОПАСНОСТИ +# =========================== +echo "" +echo "=== 3. НАСТРОЙКА БЕЗОПАСНОСТИ ===" + +# Настройка UFW +echo "🔥 Настройка файрвола..." +sudo ufw --force reset +sudo ufw default deny incoming +sudo ufw default allow outgoing +sudo ufw allow 22/tcp +sudo ufw allow 80/tcp +sudo ufw allow 443/tcp +sudo ufw --force enable + +# Настройка fail2ban +echo "🛡️ Настройка fail2ban..." +sudo systemctl enable fail2ban +sudo systemctl start fail2ban + +# =========================== +# ОЧИСТКА И ПОДГОТОВКА +# =========================== +echo "" +echo "=== 4. ОЧИСТКА СТАРЫХ КОНТЕЙНЕРОВ ===" + +echo "🛑 Останавливаю все контейнеры..." +docker stop $(docker ps -aq) 2>/dev/null || true + +echo "🗑️ Удаляю старые контейнеры..." +docker rm $(docker ps -aq) 2>/dev/null || true + +echo "🧹 Очистка системы Docker..." +docker system prune -af --volumes + +# =========================== +# ПОДГОТОВКА ФАЙЛОВ +# =========================== +echo "" +echo "=== 5. ПОДГОТОВКА КОНФИГУРАЦИИ ===" + +# Создание .env файла если нет +if [ ! -f ".env" ]; then + echo "📝 Создание .env файла..." + if [ -f "env.example" ]; then + cp env.example .env + else + cat > .env << 'EOF' +# Database Configuration +DATABASE_URL=postgresql://myuser:mypassword@postgres:5432/mydb +POSTGRES_USER=myuser +POSTGRES_PASSWORD=mypassword +POSTGRES_DB=mydb + +# Redis Configuration +REDIS_URL=redis://redis:6379 + +# Application Configuration +API_HOST=0.0.0.0 +API_PORT=3000 +DEBUG=false + +# Security +SECRET_KEY=your-secret-key-here + +# Telegram Bot (if needed) +BOT_TOKEN=your-bot-token +WEBHOOK_URL=https://your-domain.com +EOF + fi + echo "✅ .env файл создан" +fi + +# Проверка requirements.txt +REQUIREMENTS_FILE="requirements.txt" +if [ ! -f "$REQUIREMENTS_FILE" ]; then + if [ -f "requirements_new.txt" ]; then + REQUIREMENTS_FILE="requirements_new.txt" + elif [ -f "requirements.compatible.txt" ]; then + REQUIREMENTS_FILE="requirements.compatible.txt" + fi +fi +echo "✅ Используется файл зависимостей: $REQUIREMENTS_FILE" + +# =========================== +# NGINX КОНФИГУРАЦИЯ +# =========================== +echo "" +echo "=== 6. НАСТРОЙКА NGINX ===" + +cat > /tmp/nginx_universal.conf << 'EOF' +server { + listen 80; + server_name _; + + # Максимальный размер загружаемых файлов + client_max_body_size 100M; + + # API проксирование + location /api/ { + proxy_pass http://localhost:3000/api/; + 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_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + proxy_buffering off; + } + + # Health check + location /health { + proxy_pass http://localhost:3000/api/health; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + } + + # Альтернативные порты + location /api5000/ { + proxy_pass http://localhost:5000/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + } + + # WebSocket поддержка (если нужна) + location /ws/ { + proxy_pass http://localhost:3000/ws/; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + } + + # Статические файлы (если есть web2-client) + location / { + try_files $uri $uri/ @app; + } + + # Fallback на приложение + location @app { + proxy_pass http://localhost:3000/; + 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; + } + + # Gzip сжатие + gzip on; + gzip_vary on; + gzip_min_length 1024; + gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json; +} +EOF + +sudo mv /tmp/nginx_universal.conf /etc/nginx/sites-available/default +sudo ln -sf /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default + +# Удаление дефолтной страницы nginx +sudo rm -f /var/www/html/index.nginx-debian.html + +echo "✅ Nginx конфигурация создана" + +# =========================== +# ЗАПУСК ПРИЛОЖЕНИЯ +# =========================== +echo "" +echo "=== 7. ЗАПУСК ПРИЛОЖЕНИЯ ===" + +echo "🚀 Запуск Docker Compose..." + +# Стратегия запуска: сначала базовые сервисы, потом приложение +echo "📊 Запуск базы данных и Redis..." +if docker-compose -f "$COMPOSE_FILE" up -d postgres redis 2>/dev/null; then + echo "✅ База данных запущена" +else + echo "⚠️ Ошибка запуска БД, пробую альтернативные имена сервисов..." + docker-compose -f "$COMPOSE_FILE" up -d db database mysql mariadb redis 2>/dev/null || true +fi + +echo "⏳ Ждем запуска БД (15 секунд)..." +sleep 15 + +echo "🚀 Запуск основного приложения..." +if docker-compose -f "$COMPOSE_FILE" --profile main-node up -d 2>/dev/null; then + echo "✅ Main-node профиль запущен" +elif docker-compose -f "$COMPOSE_FILE" up -d app 2>/dev/null; then + echo "✅ Приложение запущено" +else + echo "⚠️ Пробую запустить все сервисы..." + docker-compose -f "$COMPOSE_FILE" up -d +fi + +echo "⏳ Ждем запуска приложения (30 секунд)..." +sleep 30 + +# =========================== +# СОЗДАНИЕ SYSTEMD SERVICE +# =========================== +echo "" +echo "=== 8. СОЗДАНИЕ SYSTEMD SERVICE ===" + +cat > /tmp/mynetwork.service << EOF +[Unit] +Description=MY Network Service +After=docker.service +Requires=docker.service + +[Service] +Type=oneshot +RemainAfterExit=yes +WorkingDirectory=$PROJECT_DIR +ExecStart=/usr/bin/docker-compose -f $COMPOSE_FILE up -d +ExecStop=/usr/bin/docker-compose -f $COMPOSE_FILE down +TimeoutStartSec=300 +User=root + +[Install] +WantedBy=multi-user.target +EOF + +sudo mv /tmp/mynetwork.service /etc/systemd/system/ +sudo systemctl daemon-reload +sudo systemctl enable mynetwork + +echo "✅ SystemD service создан и активирован" + +# =========================== +# ФИНАЛЬНАЯ ПРОВЕРКА +# =========================== +echo "" +echo "=== 9. ФИНАЛЬНАЯ ПРОВЕРКА ===" + +# Перезапуск nginx +sudo nginx -t && sudo systemctl restart nginx +echo "✅ Nginx перезапущен" + +# Проверка статуса +echo "📊 Статус контейнеров:" +docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}" + +echo "" +echo "🔍 Тестирование соединений:" +sleep 10 + +# Тест локальных портов +for port in 3000 5000 8080; do + if timeout 5 curl -s http://localhost:$port/api/health > /dev/null 2>&1; then + echo "✅ localhost:$port/api/health - РАБОТАЕТ" + else + echo "❌ localhost:$port/api/health - НЕ РАБОТАЕТ" + fi +done + +# Тест nginx proxy +if timeout 5 curl -s http://localhost/api/health > /dev/null 2>&1; then + echo "✅ nginx proxy (/api/health) - РАБОТАЕТ" +else + echo "❌ nginx proxy (/api/health) - НЕ РАБОТАЕТ" +fi + +if timeout 5 curl -s http://localhost/health > /dev/null 2>&1; then + echo "✅ nginx proxy (/health) - РАБОТАЕТ" +else + echo "❌ nginx proxy (/health) - НЕ РАБОТАЕТ" +fi + +# =========================== +# РЕЗУЛЬТАТ +# =========================== +echo "" +echo "==================================================" +echo "🎉 УСТАНОВКА ЗАВЕРШЕНА!" +echo "==================================================" + +echo "" +echo "📊 ИНФОРМАЦИЯ О СИСТЕМЕ:" +echo "Проект: $PROJECT_DIR" +echo "Compose: $COMPOSE_FILE" +echo "Внешний IP: $(curl -s ifconfig.me 2>/dev/null || echo "неизвестно")" + +echo "" +echo "🌐 ТЕСТИРОВАНИЕ:" +EXTERNAL_IP=$(curl -s ifconfig.me 2>/dev/null || echo "YOUR_SERVER_IP") +echo "curl -I http://$EXTERNAL_IP/api/health" +echo "curl -I http://$EXTERNAL_IP/health" + +echo "" +echo "🔍 ДИАГНОСТИКА (если нужна):" +echo "docker ps" +echo "docker logs \$(docker ps --format \"{{.Names}}\" | grep app | head -1)" +echo "sudo systemctl status mynetwork" +echo "sudo journalctl -u nginx -f" + +echo "" +echo "🛠️ УПРАВЛЕНИЕ:" +echo "Запуск: sudo systemctl start mynetwork" +echo "Остановка: sudo systemctl stop mynetwork" +echo "Перезапуск: sudo systemctl restart mynetwork" +echo "Статус: sudo systemctl status mynetwork" + +echo "" +echo "✅ MY Network готов к работе!" \ No newline at end of file