diff --git a/app/__main__.py b/app/__main__.py index 250aaa7..a5238bc 100644 --- a/app/__main__.py +++ b/app/__main__.py @@ -1,158 +1,30 @@ +#!/usr/bin/env python3 """ -Main application entry point for my-uploader-bot. -Handles startup, shutdown, and application lifecycle management. +MY Network App Entry Point +Точка входа для запуска через python -m app """ -import asyncio -import signal import sys +import os from pathlib import Path -from app.api import create_app -from app.core.config import get_settings -from app.core.database import init_database, close_database -from app.core.logging import get_logger, setup_logging -from app.core.background.ton_service import cleanup_ton_service +# Добавить корневую директорию в путь +root_dir = Path(__file__).parent.parent +sys.path.insert(0, str(root_dir)) -# Setup logging first -setup_logging() -logger = get_logger(__name__) -settings = get_settings() - -class ApplicationManager: - """Manages application lifecycle and graceful shutdown.""" +# Импортировать и запустить main из start_my_network.py +try: + from start_my_network import main - def __init__(self): - self.app = None - self.shutdown_event = asyncio.Event() - self.tasks = [] - - async def startup(self): - """Initialize application and all services.""" - try: - await logger.ainfo("Starting my-uploader-bot application", version="2.0.0") - - # Initialize database connections - await logger.ainfo("Initializing database connections") - await init_database() - - # Create Sanic application - await logger.ainfo("Creating Sanic application") - self.app = await create_app() - - # Setup signal handlers for graceful shutdown - self._setup_signal_handlers() - - await logger.ainfo( - "Application startup completed", - host=settings.HOST, - port=settings.PORT, - debug=settings.DEBUG, - workers=settings.WORKERS - ) - - except Exception as e: - await logger.aerror("Application startup failed", error=str(e)) - await self.shutdown() - sys.exit(1) - - async def run(self): - """Run the application server.""" - try: - if not self.app: - await self.startup() - - # Run the Sanic server - await logger.ainfo("Starting HTTP server") - - server_config = { - "host": settings.HOST, - "port": settings.PORT, - "debug": settings.DEBUG, - "access_log": settings.DEBUG, - "auto_reload": settings.AUTO_RELOAD, - "workers": settings.WORKERS if not settings.DEBUG else 1, - } - - # Start server - await self.app.create_server(**server_config, return_asyncio_server=True) - - # Wait for shutdown signal - await self.shutdown_event.wait() - - except KeyboardInterrupt: - await logger.ainfo("Received keyboard interrupt, shutting down") - except Exception as e: - await logger.aerror("Server error", error=str(e)) - finally: - await self.shutdown() - - async def shutdown(self): - """Gracefully shutdown the application.""" - await logger.ainfo("Initiating graceful shutdown") + if __name__ == "__main__": + print("🚀 Starting MY Network via app.__main__.py") + main() - try: - # Cancel all background tasks - for task in self.tasks: - if not task.done(): - task.cancel() - try: - await task - except asyncio.CancelledError: - pass - - # Cleanup services - await logger.ainfo("Cleaning up services") - - # Cleanup TON service - await cleanup_ton_service() - - # Close database connections - await close_database() - - await logger.ainfo("Graceful shutdown completed") - - except Exception as e: - await logger.aerror("Error during shutdown", error=str(e)) - - def _setup_signal_handlers(self): - """Setup signal handlers for graceful shutdown.""" - def signal_handler(signum, frame): - signal_name = signal.Signals(signum).name - logger.info(f"Received {signal_name}, initiating shutdown") - self.shutdown_event.set() - - # Register signal handlers - signal.signal(signal.SIGINT, signal_handler) - signal.signal(signal.SIGTERM, signal_handler) - - # Unix-specific signals - if hasattr(signal, 'SIGHUP'): - signal.signal(signal.SIGHUP, signal_handler) - -async def main(): - """Main application entry point.""" - app_manager = ApplicationManager() - - try: - await app_manager.run() - except Exception as e: - logger.error(f"Application failed: {e}") - sys.exit(1) - -if __name__ == "__main__": - # Ensure we're running from the correct directory - app_root = Path(__file__).parent.parent - if app_root.exists(): - import os - os.chdir(app_root) - - # Run the application - try: - asyncio.run(main()) - except KeyboardInterrupt: - print("\nApplication interrupted by user") - sys.exit(0) - except Exception as e: - print(f"Failed to start application: {e}") - sys.exit(1) +except ImportError as e: + print(f"❌ Error importing start_my_network: {e}") + print("📂 Current working directory:", os.getcwd()) + print("🐍 Python path:", sys.path) + sys.exit(1) +except Exception as e: + print(f"❌ Fatal error: {e}") + sys.exit(1) diff --git a/deployment/Dockerfile.simple b/deployment/Dockerfile.simple index 39c419f..d41728a 100644 --- a/deployment/Dockerfile.simple +++ b/deployment/Dockerfile.simple @@ -21,7 +21,7 @@ RUN apt-get update && apt-get install -y \ WORKDIR /app # Copy requirements first for better caching -COPY requirements.txt ./requirements.txt +COPY requirements_new.txt ./requirements.txt # Development stage FROM base as development @@ -40,7 +40,7 @@ ENV DEBUG=true EXPOSE 15100 9090 # Default command for development -CMD ["python", "-m", "app"] +CMD ["python", "start_my_network.py"] # Production stage FROM base as production @@ -73,4 +73,4 @@ USER appuser EXPOSE 15100 9090 # Default command -CMD ["python", "-m", "app"] \ No newline at end of file +CMD ["python", "start_my_network.py"] \ No newline at end of file diff --git a/fix_app_restart.sh b/fix_app_restart.sh index a0c71f0..48225bc 100644 --- a/fix_app_restart.sh +++ b/fix_app_restart.sh @@ -10,25 +10,31 @@ echo "" echo "=== 1. ОСТАНОВКА КОНТЕЙНЕРОВ ===" docker-compose -f deployment/docker-compose.production.yml down app +# Очистка старых образов +echo "" +echo "=== 2. ОЧИСТКА СТАРЫХ ОБРАЗОВ ===" +docker image prune -f +docker rmi $(docker images -f "dangling=true" -q) 2>/dev/null || true + # Перестройка приложения echo "" -echo "=== 2. ПЕРЕСТРОЙКА ПРИЛОЖЕНИЯ ===" -docker-compose -f deployment/docker-compose.production.yml build app --no-cache +echo "=== 3. ПЕРЕСТРОЙКА ПРИЛОЖЕНИЯ ===" +docker-compose -f deployment/docker-compose.production.yml build app --no-cache --pull # Запуск приложения echo "" -echo "=== 3. ЗАПУСК ПРИЛОЖЕНИЯ ===" +echo "=== 4. ЗАПУСК ПРИЛОЖЕНИЯ ===" docker-compose -f deployment/docker-compose.production.yml up app -d # Ожидание запуска echo "" -echo "=== 4. ОЖИДАНИЕ ЗАПУСКА ===" -echo "Ждем 30 секунд для инициализации..." -sleep 30 +echo "=== 5. ОЖИДАНИЕ ЗАПУСКА ===" +echo "Ждем 45 секунд для инициализации..." +sleep 45 # Проверка статуса echo "" -echo "=== 5. ПРОВЕРКА СТАТУСА ===" +echo "=== 6. ПРОВЕРКА СТАТУСА ===" echo "📦 Статус контейнеров:" docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep -E "(my-uploader-app|my-postgres|my-redis)" @@ -49,7 +55,7 @@ fi # Показать информацию echo "" -echo "=== 6. ИНФОРМАЦИЯ О ПРИЛОЖЕНИИ ===" +echo "=== 7. ИНФОРМАЦИЯ О ПРИЛОЖЕНИИ ===" curl -s http://localhost:15100/health | python3 -m json.tool 2>/dev/null || echo "Health endpoint недоступен" echo ""