568 lines
16 KiB
Bash
568 lines
16 KiB
Bash
#!/bin/bash
|
||
|
||
# =============================================================================
|
||
# СОЗДАНИЕ SYSTEMD СЕРВИСОВ ДЛЯ MY UPLOADER BOT
|
||
# =============================================================================
|
||
|
||
if [ $# -lt 1 ]; then
|
||
echo "Usage: $0 <project_dir> [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 "" |