#!/bin/bash # ============================================================================= # СОЗДАНИЕ SYSTEMD СЕРВИСОВ ДЛЯ MY UPLOADER BOT # ============================================================================= if [ $# -lt 1 ]; then echo "Usage: $0 [user]" exit 1 fi PROJECT_DIR="$1" SERVICE_USER="${2:-service}" echo "Создание systemd сервисов для MY Uploader Bot..." echo "Проект: $PROJECT_DIR" echo "Пользователь: $SERVICE_USER" # Проверка прав root if [ "$EUID" -ne 0 ]; then echo "❌ Этот скрипт должен запускаться с правами root" exit 1 fi # ============================================================================= # ОСНОВНОЙ СЕРВИС MY-UPLOADER-BOT # ============================================================================= echo "📝 Создание сервиса my-uploader-bot..." cat > /etc/systemd/system/my-uploader-bot.service << EOF [Unit] Description=MY Uploader Bot - Distributed Content Network Documentation=https://github.com/your-org/my-uploader-bot After=network.target postgresql.service redis.service docker.service Wants=postgresql.service redis.service docker.service [Service] Type=simple User=$SERVICE_USER Group=$SERVICE_USER WorkingDirectory=$PROJECT_DIR Environment=PATH=/usr/local/bin:/usr/bin:/bin Environment=PYTHONPATH=$PROJECT_DIR Environment=PYTHONUNBUFFERED=1 # Переменные окружения EnvironmentFile=$PROJECT_DIR/.env # Команда запуска ExecStart=/usr/bin/python3 -m app.main ExecReload=/bin/kill -HUP \$MAINPID # Настройки перезапуска Restart=always RestartSec=10 StartLimitInterval=60 StartLimitBurst=3 # Безопасность NoNewPrivileges=yes PrivateTmp=yes ProtectSystem=strict ProtectHome=yes ReadWritePaths=$PROJECT_DIR # Ресурсы MemoryMax=512M CPUQuota=50% # Логирование StandardOutput=journal StandardError=journal SyslogIdentifier=my-uploader-bot [Install] WantedBy=multi-user.target EOF echo "✅ Сервис my-uploader-bot создан" # ============================================================================= # СЕРВИС MY NETWORK BOOTSTRAP NODE # ============================================================================= echo "📝 Создание сервиса my-network-bootstrap..." cat > /etc/systemd/system/my-network-bootstrap.service << EOF [Unit] Description=MY Network Bootstrap Node Documentation=https://github.com/your-org/my-uploader-bot After=network.target Requires=network.target [Service] Type=simple User=$SERVICE_USER Group=$SERVICE_USER WorkingDirectory=$PROJECT_DIR Environment=PATH=/usr/local/bin:/usr/bin:/bin Environment=PYTHONPATH=$PROJECT_DIR Environment=PYTHONUNBUFFERED=1 # Переменные окружения EnvironmentFile=$PROJECT_DIR/.env Environment=MY_NETWORK_MODE=bootstrap Environment=MY_NETWORK_PORT=15100 # Команда запуска bootstrap узла ExecStart=/usr/bin/python3 -c " import sys sys.path.insert(0, '$PROJECT_DIR') from app.my_network.bootstrap_node import start_bootstrap_node start_bootstrap_node() " # Настройки перезапуска Restart=always RestartSec=5 StartLimitInterval=60 StartLimitBurst=5 # Безопасность NoNewPrivileges=yes PrivateTmp=yes ProtectSystem=strict ProtectHome=yes ReadWritePaths=$PROJECT_DIR # Ресурсы MemoryMax=256M CPUQuota=25% # Логирование StandardOutput=journal StandardError=journal SyslogIdentifier=my-network-bootstrap [Install] WantedBy=multi-user.target EOF echo "✅ Сервис my-network-bootstrap создан" # ============================================================================= # СЕРВИС WEB2 CLIENT # ============================================================================= if [ -d "$PROJECT_DIR/modules/web2-client" ]; then echo "📝 Создание сервиса my-web2-client..." cat > /etc/systemd/system/my-web2-client.service << EOF [Unit] Description=MY Web2 Client - Web Interface Documentation=https://github.com/your-org/my-uploader-bot After=network.target Requires=network.target [Service] Type=simple User=$SERVICE_USER Group=$SERVICE_USER WorkingDirectory=$PROJECT_DIR/modules/web2-client Environment=PATH=/usr/local/bin:/usr/bin:/bin Environment=NODE_ENV=production Environment=API_URL=http://localhost:15100 # Команда запуска ExecStart=/usr/bin/node server.js # Настройки перезапуска Restart=always RestartSec=10 StartLimitInterval=60 StartLimitBurst=3 # Безопасность NoNewPrivileges=yes PrivateTmp=yes ProtectSystem=strict ProtectHome=yes ReadWritePaths=$PROJECT_DIR/modules/web2-client # Ресурсы MemoryMax=256M CPUQuota=25% # Логирование StandardOutput=journal StandardError=journal SyslogIdentifier=my-web2-client [Install] WantedBy=multi-user.target EOF echo "✅ Сервис my-web2-client создан" fi # ============================================================================= # СЕРВИС DOCKER COMPOSE УПРАВЛЕНИЯ # ============================================================================= echo "📝 Создание сервиса my-docker-compose..." cat > /etc/systemd/system/my-docker-compose.service << EOF [Unit] Description=MY Uploader Bot - Docker Compose Stack Documentation=https://github.com/your-org/my-uploader-bot After=docker.service network.target Requires=docker.service Before=my-uploader-bot.service [Service] Type=oneshot RemainAfterExit=yes User=$SERVICE_USER Group=$SERVICE_USER WorkingDirectory=$PROJECT_DIR Environment=PATH=/usr/local/bin:/usr/bin:/bin # Команды запуска и остановки ExecStart=/usr/local/bin/docker-compose -f docker-compose.production.yml up -d ExecStop=/usr/local/bin/docker-compose -f docker-compose.production.yml down ExecReload=/usr/local/bin/docker-compose -f docker-compose.production.yml restart # Настройки TimeoutStartSec=300 TimeoutStopSec=120 # Логирование StandardOutput=journal StandardError=journal SyslogIdentifier=my-docker-compose [Install] WantedBy=multi-user.target EOF echo "✅ Сервис my-docker-compose создан" # ============================================================================= # СЕРВИС CONVERTER BUILDER (только сборка image) # ============================================================================= echo "📝 Создание сервиса my-converter-builder..." cat > /etc/systemd/system/my-converter-builder.service << EOF [Unit] Description=MY Converter Builder - Build Docker Image Documentation=https://github.com/your-org/my-uploader-bot After=docker.service Requires=docker.service [Service] Type=oneshot User=$SERVICE_USER Group=$SERVICE_USER WorkingDirectory=$PROJECT_DIR Environment=PATH=/usr/local/bin:/usr/bin:/bin # Команда сборки converter image ExecStart=/usr/local/bin/docker-compose -f docker-compose.production.yml build converter-build # Настройки TimeoutStartSec=600 RemainAfterExit=yes # Логирование StandardOutput=journal StandardError=journal SyslogIdentifier=my-converter-builder [Install] WantedBy=multi-user.target EOF echo "✅ Сервис my-converter-builder создан" # ============================================================================= # СЕРВИС МОНИТОРИНГА MY NETWORK # ============================================================================= echo "📝 Создание сервиса my-network-monitor..." cat > /etc/systemd/system/my-network-monitor.service << EOF [Unit] Description=MY Network Monitor - Health Checker Documentation=https://github.com/your-org/my-uploader-bot After=network.target my-uploader-bot.service Wants=my-uploader-bot.service [Service] Type=simple User=$SERVICE_USER Group=$SERVICE_USER WorkingDirectory=$PROJECT_DIR Environment=PATH=/usr/local/bin:/usr/bin:/bin Environment=PYTHONPATH=$PROJECT_DIR Environment=PYTHONUNBUFFERED=1 # Переменные окружения EnvironmentFile=$PROJECT_DIR/.env # Команда запуска мониторинга ExecStart=/usr/bin/python3 -c " import asyncio import sys import time import logging import subprocess import docker sys.path.insert(0, '$PROJECT_DIR') logging.basicConfig(level=logging.INFO) logger = logging.getLogger('my-network-monitor') def check_converter_image(): '''Проверяет наличие и обновляет converter image''' try: client = docker.from_env() images = client.images.list('my-converter:latest') if not images: logger.warning('Converter image не найден, собираем...') subprocess.run(['systemctl', 'start', 'my-converter-builder'], check=True) else: logger.info('Converter image готов к использованию') except Exception as e: logger.error(f'Ошибка проверки converter image: {e}') async def monitor_health(): while True: try: # Проверка основного здоровья системы logger.info('MY Network: Health check passed') # Проверка converter image каждые 10 минут if int(time.time()) % 600 == 0: check_converter_image() except Exception as e: logger.error(f'MY Network: Health check failed: {e}') await asyncio.sleep(30) if __name__ == '__main__': asyncio.run(monitor_health()) " # Настройки перезапуска Restart=always RestartSec=30 StartLimitInterval=300 StartLimitBurst=5 # Безопасность NoNewPrivileges=yes PrivateTmp=yes ProtectSystem=strict ProtectHome=yes # Ресурсы MemoryMax=64M CPUQuota=10% # Логирование StandardOutput=journal StandardError=journal SyslogIdentifier=my-network-monitor [Install] WantedBy=multi-user.target EOF echo "✅ Сервис my-network-monitor создан" # ============================================================================= # НАСТРОЙКА ЛОГРОТАЦИИ # ============================================================================= echo "📝 Настройка logrotate для MY Network..." cat > /etc/logrotate.d/my-network << EOF # Ротация логов MY Network $PROJECT_DIR/logs/*.log { daily missingok rotate 30 compress delaycompress notifempty create 644 $SERVICE_USER $SERVICE_USER postrotate systemctl reload my-uploader-bot my-network-bootstrap my-web2-client || true endscript } # Ротация логов systemd для MY Network /var/log/journal/my-uploader-bot.log /var/log/journal/my-network-bootstrap.log /var/log/journal/my-web2-client.log /var/log/journal/my-network-monitor.log /var/log/journal/my-docker-compose.log { weekly missingok rotate 4 compress delaycompress notifempty } EOF echo "✅ Logrotate настроен" # ============================================================================= # ПРИМЕНЕНИЕ НАСТРОЕК # ============================================================================= echo "🔄 Применение настроек systemd..." # Перезагрузка systemd systemctl daemon-reload # Включение автозапуска сервисов systemctl enable my-docker-compose.service systemctl enable my-converter-builder.service systemctl enable my-uploader-bot.service systemctl enable my-network-bootstrap.service systemctl enable my-network-monitor.service if [ -f "/etc/systemd/system/my-web2-client.service" ]; then systemctl enable my-web2-client.service fi echo "✅ Все сервисы включены для автозапуска" # ============================================================================= # СОЗДАНИЕ УПРАВЛЯЮЩИХ СКРИПТОВ # ============================================================================= echo "📝 Создание управляющих скриптов..." # Скрипт запуска всех сервисов cat > "$PROJECT_DIR/start_all_services.sh" << EOF #!/bin/bash echo "🚀 Запуск всех сервисов MY Network..." # Сначала запуск Docker Compose stack sudo systemctl start my-docker-compose # Сборка converter image если нужно sudo systemctl start my-converter-builder # Запуск основных сервисов sudo systemctl start my-uploader-bot sudo systemctl start my-network-bootstrap sudo systemctl start my-network-monitor if systemctl list-unit-files | grep -q my-web2-client; then sudo systemctl start my-web2-client fi echo "✅ Все сервисы запущены" sudo systemctl status my-uploader-bot my-network-bootstrap --no-pager EOF # Скрипт остановки всех сервисов cat > "$PROJECT_DIR/stop_all_services.sh" << EOF #!/bin/bash echo "🛑 Остановка всех сервисов MY Network..." sudo systemctl stop my-uploader-bot sudo systemctl stop my-network-bootstrap sudo systemctl stop my-network-monitor if systemctl list-unit-files | grep -q my-web2-client; then sudo systemctl stop my-web2-client fi # Остановка Docker Compose stack sudo systemctl stop my-docker-compose echo "✅ Все сервисы остановлены" EOF # Скрипт проверки статуса cat > "$PROJECT_DIR/check_services.sh" << EOF #!/bin/bash echo "📊 Статус сервисов MY Network:" echo "================================" sudo systemctl status my-docker-compose --no-pager -l echo "" sudo systemctl status my-uploader-bot --no-pager -l echo "" sudo systemctl status my-network-bootstrap --no-pager -l echo "" sudo systemctl status my-network-monitor --no-pager -l if systemctl list-unit-files | grep -q my-web2-client; then echo "" sudo systemctl status my-web2-client --no-pager -l fi echo "" echo "🐳 Docker контейнеры:" sudo docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" echo "" echo "🖼️ Docker images:" sudo docker images | grep my- echo "" echo "🌐 Активные порты:" sudo netstat -tlnp | grep -E ":(15100|3000|80|443)" EOF # Скрипт пересборки converter cat > "$PROJECT_DIR/rebuild_converter.sh" << EOF #!/bin/bash echo "🔄 Пересборка converter image..." cd $PROJECT_DIR sudo systemctl stop my-converter-builder sudo docker rmi my-converter:latest 2>/dev/null || true sudo systemctl start my-converter-builder echo "✅ Converter image пересобран" sudo docker images | grep my-converter EOF # Установка прав доступа chmod +x "$PROJECT_DIR/start_all_services.sh" chmod +x "$PROJECT_DIR/stop_all_services.sh" chmod +x "$PROJECT_DIR/check_services.sh" chmod +x "$PROJECT_DIR/rebuild_converter.sh" chown $SERVICE_USER:$SERVICE_USER "$PROJECT_DIR"/*.sh echo "✅ Управляющие скрипты созданы" echo "" echo "🎉 SystemD сервисы успешно настроены!" echo "" echo "📋 Созданные сервисы:" echo " • my-docker-compose.service - Docker Compose stack" echo " • my-converter-builder.service - Сборка converter image" echo " • my-uploader-bot.service - Основное приложение" echo " • my-network-bootstrap.service - Bootstrap узел" echo " • my-network-monitor.service - Мониторинг сети" if [ -f "/etc/systemd/system/my-web2-client.service" ]; then echo " • my-web2-client.service - Web интерфейс" fi echo "" echo "🎛️ Управление сервисами:" echo " Запуск всех: $PROJECT_DIR/start_all_services.sh" echo " Остановка всех: $PROJECT_DIR/stop_all_services.sh" echo " Проверка: $PROJECT_DIR/check_services.sh" echo " Пересборка converter: $PROJECT_DIR/rebuild_converter.sh" echo "" echo "📝 Логи сервисов:" echo " journalctl -u my-uploader-bot -f" echo " journalctl -u my-network-bootstrap -f" echo " journalctl -u my-docker-compose -f" echo "" echo "💡 Converter работает on-demand:" echo " - Image собирается один раз при установке" echo " - MY Uploader Bot создает контейнеры по мере необходимости" echo " - Контейнеры автоматически удаляются после завершения задач" echo ""