From a3e99d6e62f8e099fec19d4ab6bf211dc610e1f5 Mon Sep 17 00:00:00 2001 From: user Date: Thu, 3 Jul 2025 00:34:15 +0300 Subject: [PATCH] edit script --- setup_production_server.sh | 828 +++++++++++++++++++++++++++---------- 1 file changed, 613 insertions(+), 215 deletions(-) diff --git a/setup_production_server.sh b/setup_production_server.sh index bbf2d63..305cf3c 100644 --- a/setup_production_server.sh +++ b/setup_production_server.sh @@ -1,17 +1,12 @@ #!/bin/bash # ============================================================================= -# MY UPLOADER BOT - PRODUCTION SERVER SETUP SCRIPT +# MY UPLOADER BOT - ПОЛНАЯ АВТОМАТИЧЕСКАЯ УСТАНОВКА НА PRODUCTION СЕРВЕР # ============================================================================= -# Полная автоматическая установка на чистом Ubuntu/Debian сервере -# -# Использование: -# ./setup_production_server.sh yourdomain.com your@email.com -# -# Автор: MY Network Team +# Клонирует все модули из projscale.dev и настраивает полную систему # ============================================================================= -set -e # Выход при любой ошибке +set -euo pipefail # Выход при любой ошибке # Цвета для вывода RED='\033[0;31m' @@ -19,330 +14,733 @@ GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' PURPLE='\033[0;35m' +CYAN='\033[0;36m' +WHITE='\033[1;37m' NC='\033[0m' # No Color -# Логирование +# Функция логирования log() { - echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')] $1${NC}" + echo -e "${WHITE}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1" } -warn() { - echo -e "${YELLOW}[$(date +'%Y-%m-%d %H:%M:%S')] WARNING: $1${NC}" +log_error() { + echo -e "${RED}[ERROR]${NC} $1" >&2 } -error() { - echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: $1${NC}" - exit 1 +log_success() { + echo -e "${GREEN}[SUCCESS]${NC} $1" } -info() { - echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')] $1${NC}" +log_warning() { + echo -e "${YELLOW}[WARNING]${NC} $1" } -header() { - echo -e "${PURPLE}" - echo "==============================================" - echo " $1" - echo "==============================================" - echo -e "${NC}" +log_info() { + echo -e "${BLUE}[INFO]${NC} $1" } # Проверка аргументов -if [ $# -lt 2 ]; then - error "Usage: $0 " - echo "Example: $0 mydomain.com admin@mydomain.com" +if [ $# -lt 1 ]; then + echo -e "${RED}Использование: $0 [email]${NC}" + echo "Примеры:" + echo " $0 my-uploader.example.com" + echo " $0 my-uploader.example.com admin@example.com" exit 1 fi DOMAIN="$1" -EMAIL="$2" -PROJECT_DIR="/opt/my-uploader-bot" -NGINX_CONFIG="/etc/nginx/sites-available/my-uploader-bot" +EMAIL="${2:-admin@${DOMAIN}}" +PROJECT_DIR="/home/myuploader" SERVICE_USER="myuploader" -header "🚀 УСТАНОВКА MY UPLOADER BOT НА СЕРВЕР $DOMAIN" +# Репозитории для клонирования +UPLOADER_REPO="https://git.projscale.dev/my-dev/uploader-bot" +CONVERTER_REPO="https://git.projscale.dev/my-dev/converter-module" +WEB2_REPO="https://git.projscale.dev/my-dev/web2-client" -log "Домен: $DOMAIN" -log "Email: $EMAIL" -log "Проект будет установлен в: $PROJECT_DIR" +echo "" +echo -e "${PURPLE}================================================${NC}" +echo -e "${WHITE}🚀 MY UPLOADER BOT - PRODUCTION SETUP${NC}" +echo -e "${PURPLE}================================================${NC}" +echo -e "${CYAN}Домен:${NC} $DOMAIN" +echo -e "${CYAN}Email:${NC} $EMAIL" +echo -e "${CYAN}Пользователь:${NC} $SERVICE_USER" +echo -e "${CYAN}Директория:${NC} $PROJECT_DIR" +echo "" +echo -e "${CYAN}Репозитории:${NC}" +echo -e " 📦 Uploader Bot: $UPLOADER_REPO" +echo -e " 🔄 Converter: $CONVERTER_REPO" +echo -e " 🌐 Web2 Client: $WEB2_REPO" +echo -e "${PURPLE}================================================${NC}" +echo "" -# Проверка root прав -if [[ $EUID -ne 0 ]]; then - error "Этот скрипт должен запускаться с правами root (sudo)" +# Проверка прав root +if [ "$EUID" -ne 0 ]; then + log_error "Этот скрипт должен запускаться с правами root" + exit 1 fi -# Проверка операционной системы -if ! command -v apt-get &> /dev/null; then - error "Этот скрипт поддерживает только Ubuntu/Debian системы" +# Проверка интернет соединения +if ! ping -c 1 google.com &> /dev/null; then + log_error "Нет интернет соединения" + exit 1 fi -header "📦 ШАГ 1: ОБНОВЛЕНИЕ СИСТЕМЫ" +echo "" +echo -e "${BLUE}==========================================${NC}" +echo -e "${WHITE} 🔄 ШАГ 1: ОБНОВЛЕНИЕ СИСТЕМЫ${NC}" +echo -e "${BLUE}==========================================${NC}" +echo "" log "Обновление списка пакетов..." -apt-get update -y +apt update -y -log "Обновление установленных пакетов..." -apt-get upgrade -y +log "Обновление системы..." +apt upgrade -y log "Установка базовых пакетов..." -apt-get install -y \ +apt install -y \ curl \ wget \ git \ unzip \ + htop \ + nano \ + vim \ + tree \ + jq \ software-properties-common \ apt-transport-https \ ca-certificates \ gnupg \ lsb-release \ - htop \ - nano \ - vim \ - net-tools \ - ufw + ufw \ + fail2ban \ + netstat-nat \ + python3 \ + python3-pip \ + nodejs \ + npm -header "🐳 ШАГ 2: УСТАНОВКА DOCKER" +log_success "Система обновлена" + +echo "" +echo -e "${BLUE}==========================================${NC}" +echo -e "${WHITE} 🐳 ШАГ 2: УСТАНОВКА DOCKER${NC}" +echo -e "${BLUE}==========================================${NC}" +echo "" # Удаление старых версий Docker log "Удаление старых версий Docker..." -apt-get remove -y docker docker-engine docker.io containerd runc || true - -# Добавление репозитория Docker -log "Добавление Docker репозитория..." -curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg - -echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null +apt remove -y docker docker-engine docker.io containerd runc 2>/dev/null || true # Установка Docker +log "Добавление Docker GPG ключа..." +curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg + +log "Добавление Docker репозитория..." +echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null + +log "Обновление списка пакетов..." +apt update -y + log "Установка Docker..." -apt-get update -apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin +apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin # Установка Docker Compose standalone log "Установка Docker Compose..." -curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose +DOCKER_COMPOSE_VERSION=$(curl -s https://api.github.com/repos/docker/compose/releases/latest | grep 'tag_name' | cut -d\" -f4) +curl -L "https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose -ln -sf /usr/local/bin/docker-compose /usr/bin/docker-compose -# Запуск и включение Docker -systemctl enable docker +# Запуск Docker +log "Запуск Docker..." systemctl start docker +systemctl enable docker -log "Docker версия: $(docker --version)" -log "Docker Compose версия: $(docker-compose --version)" +# Проверка Docker +log "Проверка Docker..." +docker --version +docker-compose --version -header "🔥 ШАГ 3: НАСТРОЙКА FIREWALL" +log_success "Docker установлен" -log "Настройка UFW firewall..." +echo "" +echo -e "${BLUE}==========================================${NC}" +echo -e "${WHITE} 🌐 ШАГ 3: УСТАНОВКА NGINX${NC}" +echo -e "${BLUE}==========================================${NC}" +echo "" -# Сброс правил UFW -ufw --force reset +log "Установка Nginx..." +apt install -y nginx -# Базовая политика -ufw default deny incoming -ufw default allow outgoing +log "Запуск Nginx..." +systemctl start nginx +systemctl enable nginx -# Разрешение SSH (важно для сохранения доступа) -ufw allow 22/tcp comment "SSH" +log "Nginx версия: $(nginx -v 2>&1)" +log_success "Nginx установлен" -# Разрешение HTTP и HTTPS -ufw allow 80/tcp comment "HTTP" -ufw allow 443/tcp comment "HTTPS" +echo "" +echo -e "${BLUE}==========================================${NC}" +echo -e "${WHITE} 🔐 ШАГ 4: УСТАНОВКА CERTBOT${NC}" +echo -e "${BLUE}==========================================${NC}" +echo "" -# Включение firewall -ufw --force enable - -log "Статус firewall:" -ufw status verbose - -header "🔒 ШАГ 4: УСТАНОВКА CERTBOT" - -log "Установка snapd..." -apt-get install -y snapd +log "Установка snapd (если нужно)..." +apt install -y snapd log "Установка Certbot через snap..." -snap install core -snap refresh core +snap install core; snap refresh core snap install --classic certbot -# Создание symlink +log "Создание симлинка для certbot..." ln -sf /snap/bin/certbot /usr/bin/certbot log "Certbot версия: $(certbot --version)" +log_success "Certbot установлен" -header "👤 ШАГ 5: СОЗДАНИЕ ПОЛЬЗОВАТЕЛЯ СЕРВИСА" +echo "" +echo -e "${BLUE}==========================================${NC}" +echo -e "${WHITE} 👤 ШАГ 5: СОЗДАНИЕ ПОЛЬЗОВАТЕЛЯ СЕРВИСА${NC}" +echo -e "${BLUE}==========================================${NC}" +echo "" log "Создание пользователя $SERVICE_USER..." if ! id "$SERVICE_USER" &>/dev/null; then - useradd -r -s /bin/bash -d /home/$SERVICE_USER -m $SERVICE_USER - usermod -aG docker $SERVICE_USER - log "Пользователь $SERVICE_USER создан" + useradd -m -s /bin/bash "$SERVICE_USER" + usermod -aG sudo "$SERVICE_USER" + usermod -aG docker "$SERVICE_USER" + log_success "Пользователь $SERVICE_USER создан" else - log "Пользователь $SERVICE_USER уже существует" + usermod -aG docker "$SERVICE_USER" + log_info "Пользователь $SERVICE_USER уже существует" fi -header "📂 ШАГ 6: ПОДГОТОВКА ПРОЕКТА" +echo "" +echo -e "${BLUE}==========================================${NC}" +echo -e "${WHITE} 📂 ШАГ 6: КЛОНИРОВАНИЕ РЕПОЗИТОРИЕВ${NC}" +echo -e "${BLUE}==========================================${NC}" +echo "" log "Создание директории проекта..." -mkdir -p $PROJECT_DIR -cd $PROJECT_DIR +mkdir -p "$PROJECT_DIR" +chown "$SERVICE_USER:$SERVICE_USER" "$PROJECT_DIR" -# Если это git репозиторий, клонируем. Иначе копируем текущую директорию -if [ -d "$(dirname $0)/.git" ]; then - log "Клонирование из Git репозитория..." - # Определяем URL репозитория - REPO_URL=$(cd "$(dirname $0)" && git config --get remote.origin.url || echo "") - if [ -n "$REPO_URL" ]; then - git clone "$REPO_URL" . - else - warn "Git репозиторий не найден, копирую файлы локально..." - cp -r "$(dirname $0)"/* . - fi -else - log "Копирование файлов проекта..." - cp -r "$(dirname $0)"/* . +# Переключение на пользователя myuploader для клонирования +cd "$PROJECT_DIR" + +log "Клонирование uploader-bot..." +if [ -d "uploader-bot" ]; then + log_warning "Директория uploader-bot уже существует, удаляем..." + rm -rf uploader-bot fi +sudo -u "$SERVICE_USER" git clone "$UPLOADER_REPO" uploader-bot +log_success "uploader-bot склонирован" -# Установка владельца -chown -R $SERVICE_USER:$SERVICE_USER $PROJECT_DIR +log "Клонирование converter-module..." +if [ -d "converter-module" ]; then + log_warning "Директория converter-module уже существует, удаляем..." + rm -rf converter-module +fi +sudo -u "$SERVICE_USER" git clone "$CONVERTER_REPO" converter-module +log_success "converter-module склонирован" -header "⚙️ ШАГ 7: НАСТРОЙКА NGINX" +log "Клонирование web2-client..." +if [ -d "web2-client" ]; then + log_warning "Директория web2-client уже существует, удаляем..." + rm -rf web2-client +fi +sudo -u "$SERVICE_USER" git clone "$WEB2_REPO" web2-client +log_success "web2-client склонирован" -log "Установка Nginx..." -apt-get install -y nginx +# Проверка структуры +log "Структура проекта:" +sudo -u "$SERVICE_USER" tree -L 2 "$PROJECT_DIR" || ls -la "$PROJECT_DIR" -# Остановка Nginx для получения сертификатов -systemctl stop nginx +echo "" +echo -e "${BLUE}==========================================${NC}" +echo -e "${WHITE} ⚙️ ШАГ 7: НАСТРОЙКА ОКРУЖЕНИЯ${NC}" +echo -e "${BLUE}==========================================${NC}" +echo "" -log "Создание конфигурации Nginx..." -./scripts/create_nginx_config.sh $DOMAIN $PROJECT_DIR +# Переход в основную директорию uploader-bot +MAIN_PROJECT_DIR="$PROJECT_DIR/uploader-bot" +cd "$MAIN_PROJECT_DIR" -header "🔐 ШАГ 8: ПОЛУЧЕНИЕ SSL СЕРТИФИКАТОВ" +log "Генерация .env файла для uploader-bot..." -log "Получение Let's Encrypt сертификатов для $DOMAIN..." +# Генерация случайных ключей +SECRET_KEY=$(openssl rand -hex 32) +JWT_SECRET=$(openssl rand -hex 32) +ENCRYPTION_KEY=$(openssl rand -hex 16) +POSTGRES_PASSWORD=$(openssl rand -hex 16) +NODE_ID="production-node-$(date +%s)" -# Остановка процессов на портах 80/443 -fuser -k 80/tcp 2>/dev/null || true -fuser -k 443/tcp 2>/dev/null || true +# Создание .env файла +cat > "$MAIN_PROJECT_DIR/.env" << EOF +# MY UPLOADER BOT - PRODUCTION CONFIGURATION +NODE_ENV=production +DEBUG=false -# Получение сертификатов -certbot certonly \ - --standalone \ - --non-interactive \ - --agree-tos \ - --email "$EMAIL" \ - --domains "$DOMAIN,www.$DOMAIN" \ - --no-eff-email +# Domain +MY_NETWORK_DOMAIN=$DOMAIN -log "Настройка автообновления сертификатов..." -systemctl enable certbot.timer -systemctl start certbot.timer +# Database +DATABASE_URL=postgresql://my_user:$POSTGRES_PASSWORD@postgres:5432/my_uploader_db +POSTGRES_HOST=postgres +POSTGRES_PORT=5432 +POSTGRES_DB=my_uploader_db +POSTGRES_USER=my_user +POSTGRES_PASSWORD=$POSTGRES_PASSWORD -# Проверка автообновления -certbot renew --dry-run +# Redis +REDIS_URL=redis://redis:6379/0 +REDIS_HOST=redis +REDIS_PORT=6379 -header "🔧 ШАГ 9: КОНФИГУРАЦИЯ ПРОЕКТА" +# Security Keys +SECRET_KEY=$SECRET_KEY +JWT_SECRET=$JWT_SECRET +ENCRYPTION_KEY=$ENCRYPTION_KEY -log "Создание production конфигурации..." -./scripts/setup_production_env.sh $DOMAIN $EMAIL +# MY Network Settings +MY_NETWORK_NODE_ID=$NODE_ID +MY_NETWORK_PORT=15100 +MY_NETWORK_HOST=0.0.0.0 +MY_NETWORK_DOMAIN=$DOMAIN +MY_NETWORK_SSL_ENABLED=true -header "📦 ШАГ 10: КОПИРОВАНИЕ ДОПОЛНИТЕЛЬНЫХ МОДУЛЕЙ" +# API Settings +API_HOST=0.0.0.0 +API_PORT=15100 +API_WORKERS=4 +MAX_UPLOAD_SIZE=100MB -log "Настройка дополнительных модулей..." -./scripts/setup_modules.sh $PROJECT_DIR +# Converter Settings (On-Demand) +CONVERTER_DOCKER_IMAGE=my-converter:latest +CONVERTER_SHARED_PATH=/shared/converter +CONVERTER_MAX_PARALLEL=3 +CONVERTER_TIMEOUT=300 -header "🐳 ШАГ 11: ЗАПУСК DOCKER СЕРВИСОВ" +# Logging +LOG_LEVEL=INFO +LOG_FORMAT=json -log "Запуск Docker Compose в production режиме..." -cd $PROJECT_DIR +# Monitoring +GRAFANA_PASSWORD=admin123 +EOF -# Запуск от имени пользователя сервиса -sudo -u $SERVICE_USER docker-compose -f docker-compose.production.yml pull -sudo -u $SERVICE_USER docker-compose -f docker-compose.production.yml build --no-cache -sudo -u $SERVICE_USER docker-compose -f docker-compose.production.yml up -d +chown "$SERVICE_USER:$SERVICE_USER" "$MAIN_PROJECT_DIR/.env" +log_success "Файл .env создан" -log "Ожидание запуска сервисов..." -sleep 30 +# Создание симлинков для модулей в uploader-bot +log "Создание симлинков для модулей..." +sudo -u "$SERVICE_USER" mkdir -p "$MAIN_PROJECT_DIR/modules" +sudo -u "$SERVICE_USER" ln -sf "$PROJECT_DIR/converter-module" "$MAIN_PROJECT_DIR/modules/converter-module" +sudo -u "$SERVICE_USER" ln -sf "$PROJECT_DIR/web2-client" "$MAIN_PROJECT_DIR/modules/web2-client" -# Проверка статуса -log "Статус Docker сервисов:" -sudo -u $SERVICE_USER docker-compose -f docker-compose.production.yml ps +log_success "Симлинки созданы" -header "🌐 ШАГ 12: ЗАПУСК NGINX" +echo "" +echo -e "${BLUE}==========================================${NC}" +echo -e "${WHITE} 🌐 ШАГ 8: НАСТРОЙКА NGINX${NC}" +echo -e "${BLUE}==========================================${NC}" +echo "" -log "Включение конфигурации Nginx..." -ln -sf $NGINX_CONFIG /etc/nginx/sites-enabled/my-uploader-bot +log "Создание Nginx конфигурации..." + +# Создание базового nginx конфига +mkdir -p /etc/nginx/sites-available +mkdir -p /etc/nginx/sites-enabled + +cat > "/etc/nginx/sites-available/$DOMAIN" << EOF +server { + listen 80; + server_name $DOMAIN; + + # Redirect all HTTP requests to HTTPS + return 301 https://\$server_name\$request_uri; +} + +server { + listen 443 ssl http2; + server_name $DOMAIN; + + # SSL configuration will be added by certbot + + # Security headers + add_header X-Frame-Options DENY; + add_header X-Content-Type-Options nosniff; + add_header X-XSS-Protection "1; mode=block"; + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"; + + # Rate limiting + limit_req_zone \$binary_remote_addr zone=api:10m rate=10r/s; + limit_req zone=api burst=20 nodelay; + + # Main API (uploader-bot) + location / { + proxy_pass http://127.0.0.1:15100; + 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; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto \$scheme; + proxy_cache_bypass \$http_upgrade; + proxy_read_timeout 300s; + proxy_connect_timeout 75s; + } + + # Web2 Client + location /web/ { + proxy_pass http://127.0.0.1:3000/; + 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; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto \$scheme; + } + + # Converter API (on-demand, через uploader-bot) + location /converter/ { + proxy_pass http://127.0.0.1:15100/api/convert/; + proxy_http_version 1.1; + proxy_set_header Host \$host; + proxy_set_header X-Real-IP \$remote_addr; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto \$scheme; + proxy_read_timeout 600s; # Увеличенный таймаут для конвертации + } + + # Health check (no rate limiting) + location /health { + proxy_pass http://127.0.0.1:15100/health; + access_log off; + } + + # Static files + location /static/ { + alias $MAIN_PROJECT_DIR/static/; + expires 30d; + add_header Cache-Control "public, immutable"; + } +} +EOF + +# Активация сайта +ln -sf "/etc/nginx/sites-available/$DOMAIN" "/etc/nginx/sites-enabled/" + +# Удаление дефолтного сайта rm -f /etc/nginx/sites-enabled/default -log "Проверка конфигурации Nginx..." -nginx -t - -log "Запуск Nginx..." -systemctl enable nginx -systemctl start nginx - -header "🔄 ШАГ 13: НАСТРОЙКА АВТОЗАПУСКА" - -log "Создание systemd сервисов..." -./scripts/create_systemd_services.sh $PROJECT_DIR $SERVICE_USER - -header "✅ ШАГ 14: ФИНАЛЬНАЯ ПРОВЕРКА" - -log "Проверка всех сервисов..." - -# Проверка Docker -if sudo -u $SERVICE_USER docker-compose -f $PROJECT_DIR/docker-compose.production.yml ps | grep -q "Up"; then - log "✅ Docker сервисы: Работают" +# Проверка конфигурации +if nginx -t; then + systemctl reload nginx + log_success "Nginx конфигурация создана" else - error "❌ Docker сервисы: Не запущены" + log_error "Ошибка в конфигурации Nginx" + exit 1 fi -# Проверка Nginx -if systemctl is-active --quiet nginx; then - log "✅ Nginx: Работает" -else - error "❌ Nginx: Не запущен" +echo "" +echo -e "${BLUE}==========================================${NC}" +echo -e "${WHITE} 🔐 ШАГ 9: ПОЛУЧЕНИЕ SSL СЕРТИФИКАТА${NC}" +echo -e "${BLUE}==========================================${NC}" +echo "" + +log "Получение SSL сертификата для $DOMAIN..." + +# Проверка что домен указывает на этот сервер +DOMAIN_IP=$(dig +short "$DOMAIN" | tail -n1) +SERVER_IP=$(curl -s ifconfig.me || curl -s ipinfo.io/ip) + +if [ "$DOMAIN_IP" != "$SERVER_IP" ]; then + log_warning "Домен $DOMAIN не указывает на этот сервер" + log_warning "Домен IP: $DOMAIN_IP, Сервер IP: $SERVER_IP" + log_warning "Попытка получения сертификата может не удаться" fi -# Проверка SSL -if curl -sf "https://$DOMAIN/health" > /dev/null; then - log "✅ SSL сертификат: Работает" +# Получение SSL сертификата +if certbot --nginx -d "$DOMAIN" --non-interactive --agree-tos --email "$EMAIL" --redirect; then + log_success "SSL сертификат получен" else - warn "⚠️ SSL проверка не прошла (сервис может еще запускаться)" + log_error "Не удалось получить SSL сертификат" + log_warning "Можете получить его позже командой:" + log_warning "sudo certbot --nginx -d $DOMAIN" fi -# Проверка API -log "Ожидание полного запуска API..." -sleep 60 +echo "" +echo -e "${BLUE}==========================================${NC}" +echo -e "${WHITE} 🔒 ШАГ 10: НАСТРОЙКА БЕЗОПАСНОСТИ${NC}" +echo -e "${BLUE}==========================================${NC}" +echo "" -if curl -sf "https://$DOMAIN/api/my/health" > /dev/null; then - log "✅ MY Network API: Работает" +log "Настройка UFW firewall..." + +# Сброс UFW +ufw --force reset + +# Базовые правила +ufw default deny incoming +ufw default allow outgoing + +# Разрешение SSH +ufw allow ssh + +# Разрешение HTTP/HTTPS +ufw allow 80/tcp +ufw allow 443/tcp + +# Включение UFW +ufw --force enable + +log "Настройка Fail2Ban..." + +# Создание кастомного фильтра для nginx +cat > /etc/fail2ban/filter.d/nginx-my-uploader.conf << 'EOF' +[Definition] +failregex = ^ -.*"(GET|POST|HEAD).*" (4\d\d|5\d\d) .*$ + ^ -.*".*" (4\d\d|5\d\d) .*$ +ignoreregex = +EOF + +# Конфигурация jail для MY Uploader +cat > /etc/fail2ban/jail.d/my-uploader.conf << 'EOF' +[nginx-my-uploader] +enabled = true +port = http,https +filter = nginx-my-uploader +logpath = /var/log/nginx/access.log +maxretry = 5 +findtime = 600 +bantime = 3600 +action = iptables-multiport[name=nginx-my-uploader, port="http,https", protocol=tcp] +EOF + +# Перезапуск Fail2Ban +systemctl restart fail2ban +systemctl enable fail2ban + +log_success "Безопасность настроена" + +echo "" +echo -e "${BLUE}==========================================${NC}" +echo -e "${WHITE} 🐳 ШАГ 11: СБОРКА И ЗАПУСК${NC}" +echo -e "${BLUE}==========================================${NC}" +echo "" + +cd "$MAIN_PROJECT_DIR" + +log "Сборка Docker образов..." + +# Проверяем наличие docker-compose файлов +if [ -f "docker-compose.production.yml" ]; then + COMPOSE_FILE="docker-compose.production.yml" +elif [ -f "docker-compose.yml" ]; then + COMPOSE_FILE="docker-compose.yml" else - warn "⚠️ MY Network API пока не доступен" + log_error "Не найден docker-compose файл" + exit 1 fi -header "🎉 УСТАНОВКА ЗАВЕРШЕНА!" +log "Используется $COMPOSE_FILE" -info "=== ИНФОРМАЦИЯ О РАЗВЕРТЫВАНИИ ===" -info "Домен: https://$DOMAIN" -info "API: https://$DOMAIN/api/" -info "Мониторинг: https://$DOMAIN/api/my/monitor/" -info "Health Check: https://$DOMAIN/health" -info "Директория проекта: $PROJECT_DIR" -info "Пользователь: $SERVICE_USER" -info "Nginx конфиг: $NGINX_CONFIG" +# Сборка образов от имени пользователя сервиса +log "Сборка основного приложения..." +sudo -u "$SERVICE_USER" docker-compose -f "$COMPOSE_FILE" build -info "=== ПОЛЕЗНЫЕ КОМАНДЫ ===" -info "Просмотр логов: cd $PROJECT_DIR && sudo -u $SERVICE_USER docker-compose -f docker-compose.production.yml logs -f" -info "Перезапуск: cd $PROJECT_DIR && sudo -u $SERVICE_USER docker-compose -f docker-compose.production.yml restart" -info "Обновление: cd $PROJECT_DIR && git pull && sudo -u $SERVICE_USER docker-compose -f docker-compose.production.yml build --no-cache && sudo -u $SERVICE_USER docker-compose -f docker-compose.production.yml up -d" +# Сборка converter image (если есть профиль build-only) +log "Сборка converter image..." +sudo -u "$SERVICE_USER" docker-compose -f "$COMPOSE_FILE" --profile build-only build converter-build 2>/dev/null || \ +sudo -u "$SERVICE_USER" docker-compose -f "$COMPOSE_FILE" build converter 2>/dev/null || \ +log_warning "Converter build пропущен (нет соответствующего сервиса)" -info "=== БЕЗОПАСНОСТЬ ===" -info "Firewall: ufw status" -info "SSL сертификаты: ls -la /etc/letsencrypt/live/$DOMAIN/" -info "Автообновление SSL: systemctl status certbot.timer" +log "Запуск приложения..." +sudo -u "$SERVICE_USER" docker-compose -f "$COMPOSE_FILE" up -d -log "🚀 Проект успешно развернут на https://$DOMAIN" -log "📝 Не забудьте настроить Telegram токены в $PROJECT_DIR/.env.production" +# Ожидание запуска +log "Ожидание запуска сервисов..." +sleep 15 -exit 0 \ No newline at end of file +# Проверка статуса +log "Проверка статуса контейнеров..." +sudo -u "$SERVICE_USER" docker-compose -f "$COMPOSE_FILE" ps + +log_success "Приложение запущено" + +echo "" +echo -e "${BLUE}==========================================${NC}" +echo -e "${WHITE} 🏁 ШАГ 12: ФИНАЛЬНАЯ ПРОВЕРКА${NC}" +echo -e "${BLUE}==========================================${NC}" +echo "" + +log "Проверка доступности сервисов..." + +# Проверка локального API +if curl -f -s http://localhost:15100/health > /dev/null; then + log_success "Локальный API доступен" +else + log_error "Локальный API недоступен" +fi + +# Проверка web2-client +if curl -f -s http://localhost:3000/health > /dev/null 2>&1; then + log_success "Web2-client доступен" +else + log_warning "Web2-client может быть недоступен" +fi + +# Проверка HTTPS API +if curl -f -s "https://$DOMAIN/health" > /dev/null; then + log_success "HTTPS API доступен" +else + log_warning "HTTPS API пока недоступен (может потребоваться время)" +fi + +# Создание управляющих скриптов +log "Создание управляющих скриптов..." + +cat > "$MAIN_PROJECT_DIR/start.sh" << EOF +#!/bin/bash +cd $MAIN_PROJECT_DIR +docker-compose -f $COMPOSE_FILE up -d +echo "✅ MY Uploader Bot запущен" +docker-compose -f $COMPOSE_FILE ps +EOF + +cat > "$MAIN_PROJECT_DIR/stop.sh" << EOF +#!/bin/bash +cd $MAIN_PROJECT_DIR +docker-compose -f $COMPOSE_FILE down +echo "🛑 MY Uploader Bot остановлен" +EOF + +cat > "$MAIN_PROJECT_DIR/status.sh" << EOF +#!/bin/bash +cd $MAIN_PROJECT_DIR +echo "📊 Статус MY Uploader Bot:" +docker-compose -f $COMPOSE_FILE ps +echo "" +echo "🌐 API статус:" +curl -s http://localhost:15100/health | jq . 2>/dev/null || echo "API недоступен" +echo "" +echo "🔒 SSL сертификат:" +sudo certbot certificates | grep -A2 -B2 $DOMAIN || echo "Нет SSL сертификата" +EOF + +cat > "$MAIN_PROJECT_DIR/logs.sh" << EOF +#!/bin/bash +cd $MAIN_PROJECT_DIR +docker-compose -f $COMPOSE_FILE logs -f +EOF + +cat > "$MAIN_PROJECT_DIR/rebuild.sh" << EOF +#!/bin/bash +cd $MAIN_PROJECT_DIR +echo "🔄 Пересборка и перезапуск..." +docker-compose -f $COMPOSE_FILE down +docker-compose -f $COMPOSE_FILE build +docker-compose -f $COMPOSE_FILE up -d +echo "✅ Пересборка завершена" +docker-compose -f $COMPOSE_FILE ps +EOF + +chmod +x "$MAIN_PROJECT_DIR"/{start,stop,status,logs,rebuild}.sh +chown "$SERVICE_USER:$SERVICE_USER" "$MAIN_PROJECT_DIR"/{start,stop,status,logs,rebuild}.sh + +# Настройка автозапуска +log "Настройка автозапуска..." + +cat > /etc/systemd/system/my-uploader-bot.service << EOF +[Unit] +Description=MY Uploader Bot +Requires=docker.service +After=docker.service + +[Service] +Type=oneshot +RemainAfterExit=yes +User=$SERVICE_USER +Group=$SERVICE_USER +WorkingDirectory=$MAIN_PROJECT_DIR +ExecStart=/usr/local/bin/docker-compose -f $COMPOSE_FILE up -d +ExecStop=/usr/local/bin/docker-compose -f $COMPOSE_FILE down +TimeoutStartSec=300 + +[Install] +WantedBy=multi-user.target +EOF + +systemctl daemon-reload +systemctl enable my-uploader-bot.service + +log_success "Автозапуск настроен" + +echo "" +echo -e "${GREEN}================================================${NC}" +echo -e "${WHITE}🎉 УСТАНОВКА ЗАВЕРШЕНА УСПЕШНО!${NC}" +echo -e "${GREEN}================================================${NC}" +echo "" +echo -e "${CYAN}🌐 Домен:${NC} https://$DOMAIN" +echo -e "${CYAN}📁 Проект:${NC} $MAIN_PROJECT_DIR" +echo -e "${CYAN}👤 Пользователь:${NC} $SERVICE_USER" +echo "" +echo -e "${YELLOW}📦 Установленные модули:${NC}" +echo -e " 🚀 Uploader Bot: $PROJECT_DIR/uploader-bot" +echo -e " 🔄 Converter: $PROJECT_DIR/converter-module" +echo -e " 🌐 Web2 Client: $PROJECT_DIR/web2-client" +echo "" +echo -e "${YELLOW}🌍 Доступные endpoints:${NC}" +echo -e " 📊 API: https://$DOMAIN/" +echo -e " 💻 Web Interface: https://$DOMAIN/web/" +echo -e " 🔄 Converter API: https://$DOMAIN/converter/" +echo -e " ❤️ Health Check: https://$DOMAIN/health" +echo "" +echo -e "${YELLOW}📋 Полезные команды:${NC}" +echo -e "${WHITE}# Статус системы${NC}" +echo "sudo $MAIN_PROJECT_DIR/status.sh" +echo "" +echo -e "${WHITE}# Просмотр логов${NC}" +echo "sudo $MAIN_PROJECT_DIR/logs.sh" +echo "" +echo -e "${WHITE}# Перезапуск системы${NC}" +echo "sudo $MAIN_PROJECT_DIR/stop.sh && sudo $MAIN_PROJECT_DIR/start.sh" +echo "" +echo -e "${WHITE}# Пересборка и перезапуск${NC}" +echo "sudo $MAIN_PROJECT_DIR/rebuild.sh" +echo "" +echo -e "${WHITE}# Проверка SSL сертификата${NC}" +echo "sudo certbot certificates" +echo "" +echo -e "${YELLOW}🔧 Управление сервисом:${NC}" +echo "sudo systemctl start my-uploader-bot" +echo "sudo systemctl stop my-uploader-bot" +echo "sudo systemctl status my-uploader-bot" +echo "" +echo -e "${YELLOW}🌍 MY Network API:${NC}" +echo "curl https://$DOMAIN/api/my/bootstrap/config" +echo "" +echo -e "${YELLOW}📊 Мониторинг:${NC}" +echo "docker stats" +echo "sudo docker-compose -f $MAIN_PROJECT_DIR/$COMPOSE_FILE logs -f" +echo "" +echo -e "${GREEN}✅ MY Uploader Bot готов к работе!${NC}" +echo "" + +# Финальная проверка доступности +log "Финальная проверка через 5 секунд..." +sleep 5 + +if curl -f -s "https://$DOMAIN/health" > /dev/null; then + log_success "Система полностью функциональна: https://$DOMAIN" +else + log_warning "Система запущена, но требует времени для полной готовности" + log_info "Проверьте статус через несколько минут: https://$DOMAIN/health" +fi + +echo -e "${GREEN}🚀 Добро пожаловать в MY Network!${NC}" \ No newline at end of file