This commit is contained in:
user 2025-07-03 01:12:50 +03:00
parent a3e99d6e62
commit 84acc64ad3
1 changed files with 587 additions and 290 deletions

View File

@ -4,6 +4,7 @@
# MY UPLOADER BOT - ПОЛНАЯ АВТОМАТИЧЕСКАЯ УСТАНОВКА НА PRODUCTION СЕРВЕР # MY UPLOADER BOT - ПОЛНАЯ АВТОМАТИЧЕСКАЯ УСТАНОВКА НА PRODUCTION СЕРВЕР
# ============================================================================= # =============================================================================
# Клонирует все модули из projscale.dev и настраивает полную систему # Клонирует все модули из projscale.dev и настраивает полную систему
# Поддерживает типы нод: main (основная) и regular (обычная)
# ============================================================================= # =============================================================================
set -euo pipefail # Выход при любой ошибке set -euo pipefail # Выход при любой ошибке
@ -18,6 +19,19 @@ CYAN='\033[0;36m'
WHITE='\033[1;37m' WHITE='\033[1;37m'
NC='\033[0m' # No Color NC='\033[0m' # No Color
# Конфигурация
DOMAIN="$1"
NODE_TYPE="${2:-regular}" # main или regular, по умолчанию: regular
EMAIL="${3:-admin@${1}}"
PROJECT_DIR="/home/myuploader"
SERVICE_USER="myuploader"
PROGRESS_FILE="/home/myuploader/.installation_progress"
# Репозитории для клонирования
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() { log() {
echo -e "${WHITE}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1" echo -e "${WHITE}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1"
@ -39,38 +53,73 @@ log_info() {
echo -e "${BLUE}[INFO]${NC} $1" echo -e "${BLUE}[INFO]${NC} $1"
} }
# Функция записи прогресса
log_progress() {
local step="$1"
echo "$step:$(date '+%Y-%m-%d %H:%M:%S')" >> "$PROGRESS_FILE"
log_success "Этап завершен: $step"
}
# Функция проверки завершенности этапа
is_step_completed() {
local step="$1"
if [ -f "$PROGRESS_FILE" ]; then
grep -q "^$step:" "$PROGRESS_FILE"
else
return 1
fi
}
# Функция пропуска уже выполненных этапов
check_and_skip() {
local step="$1"
local description="$2"
if is_step_completed "$step"; then
log_info "⏭️ Пропускаем: $description (уже выполнено)"
return 0
else
log "🔄 Выполняется: $description"
return 1
fi
}
# Проверка аргументов # Проверка аргументов
if [ $# -lt 1 ]; then if [ $# -lt 1 ]; then
echo -e "${RED}Использование: $0 <domain> [email]${NC}" echo -e "${RED}Использование: $0 <domain> [node_type] [email]${NC}"
echo "Примеры:" echo "Примеры:"
echo " $0 my-uploader.example.com" echo " $0 my-uploader.example.com regular"
echo " $0 my-uploader.example.com admin@example.com" echo " $0 my-uploader.example.com main admin@example.com"
echo ""
echo "Типы нод:"
echo " main - Основная нода (с web2-client, полные возможности)"
echo " regular - Обычная нода (только uploader-bot + converter-module)"
exit 1 exit 1
fi fi
DOMAIN="$1" # Создание директории прогресса
EMAIL="${2:-admin@${DOMAIN}}" mkdir -p "$(dirname "$PROGRESS_FILE")"
PROJECT_DIR="/home/myuploader" touch "$PROGRESS_FILE"
SERVICE_USER="myuploader"
# Репозитории для клонирования
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"
echo "" echo ""
echo -e "${PURPLE}================================================${NC}" echo -e "${PURPLE}================================================${NC}"
echo -e "${WHITE}🚀 MY UPLOADER BOT - PRODUCTION SETUP${NC}" echo -e "${WHITE}🚀 MY UPLOADER BOT - PRODUCTION SETUP${NC}"
echo -e "${PURPLE}================================================${NC}" echo -e "${PURPLE}================================================${NC}"
echo -e "${CYAN}Домен:${NC} $DOMAIN" echo -e "${CYAN}Домен:${NC} $DOMAIN"
echo -e "${CYAN}Тип ноды:${NC} $NODE_TYPE"
echo -e "${CYAN}Email:${NC} $EMAIL" echo -e "${CYAN}Email:${NC} $EMAIL"
echo -e "${CYAN}Пользователь:${NC} $SERVICE_USER" echo -e "${CYAN}Пользователь:${NC} $SERVICE_USER"
echo -e "${CYAN}Директория:${NC} $PROJECT_DIR" echo -e "${CYAN}Директория:${NC} $PROJECT_DIR"
echo -e "${CYAN}Прогресс файл:${NC} $PROGRESS_FILE"
echo "" echo ""
echo -e "${CYAN}Репозитории:${NC}" echo -e "${CYAN}Репозитории:${NC}"
echo -e " 📦 Uploader Bot: $UPLOADER_REPO" echo -e " 📦 Uploader Bot: $UPLOADER_REPO"
echo -e " 🔄 Converter: $CONVERTER_REPO" echo -e " 🔄 Converter: $CONVERTER_REPO"
if [ "$NODE_TYPE" = "main" ]; then
echo -e " 🌐 Web2 Client: $WEB2_REPO" echo -e " 🌐 Web2 Client: $WEB2_REPO"
else
echo -e " 🌐 Web2 Client: ${YELLOW}пропускается (обычная нода)${NC}"
fi
echo -e "${PURPLE}================================================${NC}" echo -e "${PURPLE}================================================${NC}"
echo "" echo ""
@ -92,6 +141,7 @@ echo -e "${WHITE} 🔄 ШАГ 1: ОБНОВЛЕНИЕ СИСТЕМЫ${NC}"
echo -e "${BLUE}==========================================${NC}" echo -e "${BLUE}==========================================${NC}"
echo "" echo ""
if ! check_and_skip "system_update" "Обновление системы"; then
log "Обновление списка пакетов..." log "Обновление списка пакетов..."
apt update -y apt update -y
@ -122,7 +172,8 @@ apt install -y \
nodejs \ nodejs \
npm npm
log_success "Система обновлена" log_progress "system_update"
fi
echo "" echo ""
echo -e "${BLUE}==========================================${NC}" echo -e "${BLUE}==========================================${NC}"
@ -130,6 +181,7 @@ echo -e "${WHITE} 🐳 ШАГ 2: УСТАНОВКА DOCKER${NC}"
echo -e "${BLUE}==========================================${NC}" echo -e "${BLUE}==========================================${NC}"
echo "" echo ""
if ! check_and_skip "docker_install" "Установка Docker"; then
# Удаление старых версий Docker # Удаление старых версий Docker
log "Удаление старых версий Docker..." log "Удаление старых версий Docker..."
apt remove -y docker docker-engine docker.io containerd runc 2>/dev/null || true apt remove -y docker docker-engine docker.io containerd runc 2>/dev/null || true
@ -163,7 +215,8 @@ log "Проверка Docker..."
docker --version docker --version
docker-compose --version docker-compose --version
log_success "Docker установлен" log_progress "docker_install"
fi
echo "" echo ""
echo -e "${BLUE}==========================================${NC}" echo -e "${BLUE}==========================================${NC}"
@ -171,6 +224,7 @@ echo -e "${WHITE} 🌐 ШАГ 3: УСТАНОВКА NGINX${NC}"
echo -e "${BLUE}==========================================${NC}" echo -e "${BLUE}==========================================${NC}"
echo "" echo ""
if ! check_and_skip "nginx_install" "Установка Nginx"; then
log "Установка Nginx..." log "Установка Nginx..."
apt install -y nginx apt install -y nginx
@ -179,7 +233,8 @@ systemctl start nginx
systemctl enable nginx systemctl enable nginx
log "Nginx версия: $(nginx -v 2>&1)" log "Nginx версия: $(nginx -v 2>&1)"
log_success "Nginx установлен" log_progress "nginx_install"
fi
echo "" echo ""
echo -e "${BLUE}==========================================${NC}" echo -e "${BLUE}==========================================${NC}"
@ -187,6 +242,7 @@ echo -e "${WHITE} 🔐 ШАГ 4: УСТАНОВКА CERTBOT${NC}"
echo -e "${BLUE}==========================================${NC}" echo -e "${BLUE}==========================================${NC}"
echo "" echo ""
if ! check_and_skip "certbot_install" "Установка Certbot"; then
log "Установка snapd (если нужно)..." log "Установка snapd (если нужно)..."
apt install -y snapd apt install -y snapd
@ -198,7 +254,8 @@ log "Создание симлинка для certbot..."
ln -sf /snap/bin/certbot /usr/bin/certbot ln -sf /snap/bin/certbot /usr/bin/certbot
log "Certbot версия: $(certbot --version)" log "Certbot версия: $(certbot --version)"
log_success "Certbot установлен" log_progress "certbot_install"
fi
echo "" echo ""
echo -e "${BLUE}==========================================${NC}" echo -e "${BLUE}==========================================${NC}"
@ -206,6 +263,7 @@ echo -e "${WHITE} 👤 ШАГ 5: СОЗДАНИЕ ПОЛЬЗОВАТЕЛЯ СЕ
echo -e "${BLUE}==========================================${NC}" echo -e "${BLUE}==========================================${NC}"
echo "" echo ""
if ! check_and_skip "service_user" "Создание пользователя сервиса"; then
log "Создание пользователя $SERVICE_USER..." log "Создание пользователя $SERVICE_USER..."
if ! id "$SERVICE_USER" &>/dev/null; then if ! id "$SERVICE_USER" &>/dev/null; then
useradd -m -s /bin/bash "$SERVICE_USER" useradd -m -s /bin/bash "$SERVICE_USER"
@ -216,6 +274,8 @@ else
usermod -aG docker "$SERVICE_USER" usermod -aG docker "$SERVICE_USER"
log_info "Пользователь $SERVICE_USER уже существует" log_info "Пользователь $SERVICE_USER уже существует"
fi fi
log_progress "service_user"
fi
echo "" echo ""
echo -e "${BLUE}==========================================${NC}" echo -e "${BLUE}==========================================${NC}"
@ -223,6 +283,7 @@ echo -e "${WHITE} 📂 ШАГ 6: КЛОНИРОВАНИЕ РЕПОЗИТОРИЕ
echo -e "${BLUE}==========================================${NC}" echo -e "${BLUE}==========================================${NC}"
echo "" echo ""
if ! check_and_skip "repositories_clone" "Клонирование репозиториев"; then
log "Создание директории проекта..." log "Создание директории проекта..."
mkdir -p "$PROJECT_DIR" mkdir -p "$PROJECT_DIR"
chown "$SERVICE_USER:$SERVICE_USER" "$PROJECT_DIR" chown "$SERVICE_USER:$SERVICE_USER" "$PROJECT_DIR"
@ -246,6 +307,8 @@ fi
sudo -u "$SERVICE_USER" git clone "$CONVERTER_REPO" converter-module sudo -u "$SERVICE_USER" git clone "$CONVERTER_REPO" converter-module
log_success "converter-module склонирован" log_success "converter-module склонирован"
# Клонирование web2-client только для основной ноды
if [ "$NODE_TYPE" = "main" ]; then
log "Клонирование web2-client..." log "Клонирование web2-client..."
if [ -d "web2-client" ]; then if [ -d "web2-client" ]; then
log_warning "Директория web2-client уже существует, удаляем..." log_warning "Директория web2-client уже существует, удаляем..."
@ -253,17 +316,24 @@ if [ -d "web2-client" ]; then
fi fi
sudo -u "$SERVICE_USER" git clone "$WEB2_REPO" web2-client sudo -u "$SERVICE_USER" git clone "$WEB2_REPO" web2-client
log_success "web2-client склонирован" log_success "web2-client склонирован"
else
log_info "⏭️ Пропускаем web2-client (обычная нода)"
fi
# Проверка структуры # Проверка структуры
log "Структура проекта:" log "Структура проекта:"
sudo -u "$SERVICE_USER" tree -L 2 "$PROJECT_DIR" || ls -la "$PROJECT_DIR" sudo -u "$SERVICE_USER" tree -L 2 "$PROJECT_DIR" || ls -la "$PROJECT_DIR"
log_progress "repositories_clone"
fi
echo "" echo ""
echo -e "${BLUE}==========================================${NC}" echo -e "${BLUE}==========================================${NC}"
echo -e "${WHITE} ⚙️ ШАГ 7: НАСТРОЙКА ОКРУЖЕНИЯ${NC}" echo -e "${WHITE} ⚙️ ШАГ 7: НАСТРОЙКА ОКРУЖЕНИЯ${NC}"
echo -e "${BLUE}==========================================${NC}" echo -e "${BLUE}==========================================${NC}"
echo "" echo ""
if ! check_and_skip "environment_setup" "Настройка окружения"; then
# Переход в основную директорию uploader-bot # Переход в основную директорию uploader-bot
MAIN_PROJECT_DIR="$PROJECT_DIR/uploader-bot" MAIN_PROJECT_DIR="$PROJECT_DIR/uploader-bot"
cd "$MAIN_PROJECT_DIR" cd "$MAIN_PROJECT_DIR"
@ -275,7 +345,7 @@ SECRET_KEY=$(openssl rand -hex 32)
JWT_SECRET=$(openssl rand -hex 32) JWT_SECRET=$(openssl rand -hex 32)
ENCRYPTION_KEY=$(openssl rand -hex 16) ENCRYPTION_KEY=$(openssl rand -hex 16)
POSTGRES_PASSWORD=$(openssl rand -hex 16) POSTGRES_PASSWORD=$(openssl rand -hex 16)
NODE_ID="production-node-$(date +%s)" NODE_ID="$NODE_TYPE-node-$(date +%s)"
# Создание .env файла # Создание .env файла
cat > "$MAIN_PROJECT_DIR/.env" << EOF cat > "$MAIN_PROJECT_DIR/.env" << EOF
@ -283,6 +353,9 @@ cat > "$MAIN_PROJECT_DIR/.env" << EOF
NODE_ENV=production NODE_ENV=production
DEBUG=false DEBUG=false
# Node Configuration
NODE_TYPE=$NODE_TYPE
# Domain # Domain
MY_NETWORK_DOMAIN=$DOMAIN MY_NETWORK_DOMAIN=$DOMAIN
@ -338,9 +411,14 @@ log_success "Файл .env создан"
log "Создание симлинков для модулей..." log "Создание симлинков для модулей..."
sudo -u "$SERVICE_USER" mkdir -p "$MAIN_PROJECT_DIR/modules" 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/converter-module" "$MAIN_PROJECT_DIR/modules/converter-module"
if [ "$NODE_TYPE" = "main" ]; then
sudo -u "$SERVICE_USER" ln -sf "$PROJECT_DIR/web2-client" "$MAIN_PROJECT_DIR/modules/web2-client" sudo -u "$SERVICE_USER" ln -sf "$PROJECT_DIR/web2-client" "$MAIN_PROJECT_DIR/modules/web2-client"
fi
log_success "Симлинки созданы" log_success "Симлинки созданы"
log_progress "environment_setup"
fi
echo "" echo ""
echo -e "${BLUE}==========================================${NC}" echo -e "${BLUE}==========================================${NC}"
@ -348,12 +426,28 @@ echo -e "${WHITE} 🌐 ШАГ 8: НАСТРОЙКА NGINX${NC}"
echo -e "${BLUE}==========================================${NC}" echo -e "${BLUE}==========================================${NC}"
echo "" echo ""
log "Создание Nginx конфигурации..." if ! check_and_skip "nginx_config" "Настройка Nginx"; then
log "Настройка Nginx конфигурации..."
# Создание базового nginx конфига # Сначала добавляем rate limiting в основной конфиг nginx
log "Добавление rate limiting в nginx.conf..."
# Создаем backup оригинального конфига
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup
# Добавляем rate limiting в блок http
if ! grep -q "limit_req_zone" /etc/nginx/nginx.conf; then
sed -i '/http {/a\\n\t# Rate limiting zones\n\tlimit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;\n\tlimit_req_zone $binary_remote_addr zone=upload:10m rate=5r/s;\n' /etc/nginx/nginx.conf
fi
log "Создание site конфигурации для типа ноды: $NODE_TYPE..."
# Создание базового nginx конфига для сайта
mkdir -p /etc/nginx/sites-available mkdir -p /etc/nginx/sites-available
mkdir -p /etc/nginx/sites-enabled mkdir -p /etc/nginx/sites-enabled
if [ "$NODE_TYPE" = "main" ]; then
# Конфигурация для основной ноды (с web2-client)
cat > "/etc/nginx/sites-available/$DOMAIN" << EOF cat > "/etc/nginx/sites-available/$DOMAIN" << EOF
server { server {
listen 80; listen 80;
@ -375,13 +469,25 @@ server {
add_header X-XSS-Protection "1; mode=block"; add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
# Rate limiting # Web2 Client (main page for main nodes)
limit_req_zone \$binary_remote_addr zone=api:10m rate=10r/s; location / {
limit_req zone=api burst=20 nodelay; limit_req zone=api burst=20 nodelay;
# Main API (uploader-bot) proxy_pass http://127.0.0.1:3000/;
location / { proxy_http_version 1.1;
proxy_pass http://127.0.0.1:15100; 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;
}
# API endpoints
location /api/ {
limit_req zone=api burst=20 nodelay;
proxy_pass http://127.0.0.1:15100/;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade; proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection 'upgrade'; proxy_set_header Connection 'upgrade';
@ -394,27 +500,34 @@ server {
proxy_connect_timeout 75s; proxy_connect_timeout 75s;
} }
# Web2 Client # Upload endpoint with stricter rate limiting
location /web/ { location /api/upload {
proxy_pass http://127.0.0.1:3000/; limit_req zone=upload burst=10 nodelay;
proxy_pass http://127.0.0.1:15100/upload;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host \$host; proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme; proxy_set_header X-Forwarded-Proto \$scheme;
proxy_read_timeout 600s;
proxy_send_timeout 600s;
client_max_body_size 100M;
} }
# Converter API (on-demand, через uploader-bot) # Converter API (on-demand, через uploader-bot)
location /converter/ { location /converter/ {
limit_req zone=upload burst=10 nodelay;
proxy_pass http://127.0.0.1:15100/api/convert/; proxy_pass http://127.0.0.1:15100/api/convert/;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Host \$host; proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme; proxy_set_header X-Forwarded-Proto \$scheme;
proxy_read_timeout 600s; # Увеличенный таймаут для конвертации proxy_read_timeout 600s;
proxy_send_timeout 600s;
client_max_body_size 100M;
} }
# Health check (no rate limiting) # Health check (no rate limiting)
@ -429,8 +542,107 @@ server {
expires 30d; expires 30d;
add_header Cache-Control "public, immutable"; add_header Cache-Control "public, immutable";
} }
# Disable access to hidden files
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
} }
EOF EOF
else
# Конфигурация для обычной ноды (только API)
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";
# Main API (uploader-bot)
location / {
limit_req zone=api burst=20 nodelay;
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;
}
# Upload endpoint with stricter rate limiting
location /upload {
limit_req zone=upload burst=10 nodelay;
proxy_pass http://127.0.0.1:15100/upload;
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;
proxy_send_timeout 600s;
client_max_body_size 100M;
}
# Converter API (on-demand, через uploader-bot)
location /converter/ {
limit_req zone=upload burst=10 nodelay;
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;
proxy_send_timeout 600s;
client_max_body_size 100M;
}
# 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";
}
# Disable access to hidden files
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
}
EOF
fi
# Активация сайта # Активация сайта
ln -sf "/etc/nginx/sites-available/$DOMAIN" "/etc/nginx/sites-enabled/" ln -sf "/etc/nginx/sites-available/$DOMAIN" "/etc/nginx/sites-enabled/"
@ -439,20 +651,27 @@ ln -sf "/etc/nginx/sites-available/$DOMAIN" "/etc/nginx/sites-enabled/"
rm -f /etc/nginx/sites-enabled/default rm -f /etc/nginx/sites-enabled/default
# Проверка конфигурации # Проверка конфигурации
log "Проверка конфигурации Nginx..."
if nginx -t; then if nginx -t; then
systemctl reload nginx systemctl reload nginx
log_success "Nginx конфигурация создана" log_success "Nginx конфигурация создана и применена"
else else
log_error "Ошибка в конфигурации Nginx" log_error "Ошибка в конфигурации Nginx"
# Показываем конкретную ошибку
nginx -t
exit 1 exit 1
fi fi
log_progress "nginx_config"
fi
echo "" echo ""
echo -e "${BLUE}==========================================${NC}" echo -e "${BLUE}==========================================${NC}"
echo -e "${WHITE} 🔐 ШАГ 9: ПОЛУЧЕНИЕ SSL СЕРТИФИКАТА${NC}" echo -e "${WHITE} 🔐 ШАГ 9: ПОЛУЧЕНИЕ SSL СЕРТИФИКАТА${NC}"
echo -e "${BLUE}==========================================${NC}" echo -e "${BLUE}==========================================${NC}"
echo "" echo ""
if ! check_and_skip "ssl_certificate" "Получение SSL сертификата"; then
log "Получение SSL сертификата для $DOMAIN..." log "Получение SSL сертификата для $DOMAIN..."
# Проверка что домен указывает на этот сервер # Проверка что домен указывает на этот сервер
@ -468,11 +687,13 @@ fi
# Получение SSL сертификата # Получение SSL сертификата
if certbot --nginx -d "$DOMAIN" --non-interactive --agree-tos --email "$EMAIL" --redirect; then if certbot --nginx -d "$DOMAIN" --non-interactive --agree-tos --email "$EMAIL" --redirect; then
log_success "SSL сертификат получен" log_success "SSL сертификат получен"
log_progress "ssl_certificate"
else else
log_error "Не удалось получить SSL сертификат" log_error "Не удалось получить SSL сертификат"
log_warning "Можете получить его позже командой:" log_warning "Можете получить его позже командой:"
log_warning "sudo certbot --nginx -d $DOMAIN" log_warning "sudo certbot --nginx -d $DOMAIN"
fi fi
fi
echo "" echo ""
echo -e "${BLUE}==========================================${NC}" echo -e "${BLUE}==========================================${NC}"
@ -480,6 +701,7 @@ echo -e "${WHITE} 🔒 ШАГ 10: НАСТРОЙКА БЕЗОПАСНОСТИ${N
echo -e "${BLUE}==========================================${NC}" echo -e "${BLUE}==========================================${NC}"
echo "" echo ""
if ! check_and_skip "security_setup" "Настройка безопасности"; then
log "Настройка UFW firewall..." log "Настройка UFW firewall..."
# Сброс UFW # Сброс UFW
@ -527,6 +749,8 @@ systemctl restart fail2ban
systemctl enable fail2ban systemctl enable fail2ban
log_success "Безопасность настроена" log_success "Безопасность настроена"
log_progress "security_setup"
fi
echo "" echo ""
echo -e "${BLUE}==========================================${NC}" echo -e "${BLUE}==========================================${NC}"
@ -534,6 +758,8 @@ echo -e "${WHITE} 🐳 ШАГ 11: СБОРКА И ЗАПУСК${NC}"
echo -e "${BLUE}==========================================${NC}" echo -e "${BLUE}==========================================${NC}"
echo "" echo ""
if ! check_and_skip "docker_build" "Сборка и запуск"; then
MAIN_PROJECT_DIR="$PROJECT_DIR/uploader-bot"
cd "$MAIN_PROJECT_DIR" cd "$MAIN_PROJECT_DIR"
log "Сборка Docker образов..." log "Сборка Docker образов..."
@ -561,7 +787,16 @@ sudo -u "$SERVICE_USER" docker-compose -f "$COMPOSE_FILE" build converter 2>/dev
log_warning "Converter build пропущен (нет соответствующего сервиса)" log_warning "Converter build пропущен (нет соответствующего сервиса)"
log "Запуск приложения..." log "Запуск приложения..."
if [ "$NODE_TYPE" = "main" ]; then
# Для основной ноды запускаем все сервисы
sudo -u "$SERVICE_USER" docker-compose -f "$COMPOSE_FILE" up -d sudo -u "$SERVICE_USER" docker-compose -f "$COMPOSE_FILE" up -d
log "🚀 Запущены все сервисы для основной ноды"
else
# Для обычной ноды запускаем только необходимые сервисы
sudo -u "$SERVICE_USER" docker-compose -f "$COMPOSE_FILE" up -d uploader-bot converter-builder watchtower 2>/dev/null || \
sudo -u "$SERVICE_USER" docker-compose -f "$COMPOSE_FILE" up -d
log "🚀 Запущены основные сервисы для обычной ноды"
fi
# Ожидание запуска # Ожидание запуска
log "Ожидание запуска сервисов..." log "Ожидание запуска сервисов..."
@ -572,6 +807,8 @@ log "Проверка статуса контейнеров..."
sudo -u "$SERVICE_USER" docker-compose -f "$COMPOSE_FILE" ps sudo -u "$SERVICE_USER" docker-compose -f "$COMPOSE_FILE" ps
log_success "Приложение запущено" log_success "Приложение запущено"
log_progress "docker_build"
fi
echo "" echo ""
echo -e "${BLUE}==========================================${NC}" echo -e "${BLUE}==========================================${NC}"
@ -579,6 +816,9 @@ echo -e "${WHITE} 🏁 ШАГ 12: ФИНАЛЬНАЯ ПРОВЕРКА${NC}"
echo -e "${BLUE}==========================================${NC}" echo -e "${BLUE}==========================================${NC}"
echo "" echo ""
if ! check_and_skip "final_check" "Финальная проверка"; then
MAIN_PROJECT_DIR="$PROJECT_DIR/uploader-bot"
log "Проверка доступности сервисов..." log "Проверка доступности сервисов..."
# Проверка локального API # Проверка локального API
@ -588,12 +828,14 @@ else
log_error "Локальный API недоступен" log_error "Локальный API недоступен"
fi fi
# Проверка web2-client # Проверка web2-client только для основной ноды
if [ "$NODE_TYPE" = "main" ]; then
if curl -f -s http://localhost:3000/health > /dev/null 2>&1; then if curl -f -s http://localhost:3000/health > /dev/null 2>&1; then
log_success "Web2-client доступен" log_success "Web2-client доступен"
else else
log_warning "Web2-client может быть недоступен" log_warning "Web2-client может быть недоступен"
fi fi
fi
# Проверка HTTPS API # Проверка HTTPS API
if curl -f -s "https://$DOMAIN/health" > /dev/null; then if curl -f -s "https://$DOMAIN/health" > /dev/null; then
@ -605,11 +847,22 @@ fi
# Создание управляющих скриптов # Создание управляющих скриптов
log "Создание управляющих скриптов..." log "Создание управляющих скриптов..."
# Определяем какой compose file использовать
if [ -f "$MAIN_PROJECT_DIR/docker-compose.production.yml" ]; then
COMPOSE_FILE="docker-compose.production.yml"
else
COMPOSE_FILE="docker-compose.yml"
fi
cat > "$MAIN_PROJECT_DIR/start.sh" << EOF cat > "$MAIN_PROJECT_DIR/start.sh" << EOF
#!/bin/bash #!/bin/bash
cd $MAIN_PROJECT_DIR cd $MAIN_PROJECT_DIR
if [ "$NODE_TYPE" = "main" ]; then
docker-compose -f $COMPOSE_FILE up -d docker-compose -f $COMPOSE_FILE up -d
echo "✅ MY Uploader Bot запущен" else
docker-compose -f $COMPOSE_FILE up -d uploader-bot converter-builder watchtower 2>/dev/null || docker-compose -f $COMPOSE_FILE up -d
fi
echo "✅ MY Uploader Bot запущен (тип ноды: $NODE_TYPE)"
docker-compose -f $COMPOSE_FILE ps docker-compose -f $COMPOSE_FILE ps
EOF EOF
@ -623,7 +876,7 @@ EOF
cat > "$MAIN_PROJECT_DIR/status.sh" << EOF cat > "$MAIN_PROJECT_DIR/status.sh" << EOF
#!/bin/bash #!/bin/bash
cd $MAIN_PROJECT_DIR cd $MAIN_PROJECT_DIR
echo "📊 Статус MY Uploader Bot:" echo "📊 Статус MY Uploader Bot (тип ноды: $NODE_TYPE):"
docker-compose -f $COMPOSE_FILE ps docker-compose -f $COMPOSE_FILE ps
echo "" echo ""
echo "🌐 API статус:" echo "🌐 API статус:"
@ -631,6 +884,9 @@ curl -s http://localhost:15100/health | jq . 2>/dev/null || echo "API недос
echo "" echo ""
echo "🔒 SSL сертификат:" echo "🔒 SSL сертификат:"
sudo certbot certificates | grep -A2 -B2 $DOMAIN || echo "Нет SSL сертификата" sudo certbot certificates | grep -A2 -B2 $DOMAIN || echo "Нет SSL сертификата"
echo ""
echo "📈 Прогресс установки:"
cat $PROGRESS_FILE 2>/dev/null || echo "Файл прогресса не найден"
EOF EOF
cat > "$MAIN_PROJECT_DIR/logs.sh" << EOF cat > "$MAIN_PROJECT_DIR/logs.sh" << EOF
@ -645,7 +901,11 @@ cd $MAIN_PROJECT_DIR
echo "🔄 Пересборка и перезапуск..." echo "🔄 Пересборка и перезапуск..."
docker-compose -f $COMPOSE_FILE down docker-compose -f $COMPOSE_FILE down
docker-compose -f $COMPOSE_FILE build docker-compose -f $COMPOSE_FILE build
if [ "$NODE_TYPE" = "main" ]; then
docker-compose -f $COMPOSE_FILE up -d docker-compose -f $COMPOSE_FILE up -d
else
docker-compose -f $COMPOSE_FILE up -d uploader-bot converter-builder watchtower 2>/dev/null || docker-compose -f $COMPOSE_FILE up -d
fi
echo "✅ Пересборка завершена" echo "✅ Пересборка завершена"
docker-compose -f $COMPOSE_FILE ps docker-compose -f $COMPOSE_FILE ps
EOF EOF
@ -656,9 +916,17 @@ chown "$SERVICE_USER:$SERVICE_USER" "$MAIN_PROJECT_DIR"/{start,stop,status,logs,
# Настройка автозапуска # Настройка автозапуска
log "Настройка автозапуска..." log "Настройка автозапуска..."
if [ "$NODE_TYPE" = "main" ]; then
SERVICE_EXEC_START="/usr/local/bin/docker-compose -f $COMPOSE_FILE up -d"
SERVICE_DESCRIPTION="MY Uploader Bot (Main Node)"
else
SERVICE_EXEC_START="/usr/local/bin/docker-compose -f $COMPOSE_FILE up -d uploader-bot converter-builder watchtower"
SERVICE_DESCRIPTION="MY Uploader Bot (Regular Node)"
fi
cat > /etc/systemd/system/my-uploader-bot.service << EOF cat > /etc/systemd/system/my-uploader-bot.service << EOF
[Unit] [Unit]
Description=MY Uploader Bot Description=$SERVICE_DESCRIPTION
Requires=docker.service Requires=docker.service
After=docker.service After=docker.service
@ -668,7 +936,7 @@ RemainAfterExit=yes
User=$SERVICE_USER User=$SERVICE_USER
Group=$SERVICE_USER Group=$SERVICE_USER
WorkingDirectory=$MAIN_PROJECT_DIR WorkingDirectory=$MAIN_PROJECT_DIR
ExecStart=/usr/local/bin/docker-compose -f $COMPOSE_FILE up -d ExecStart=$SERVICE_EXEC_START
ExecStop=/usr/local/bin/docker-compose -f $COMPOSE_FILE down ExecStop=/usr/local/bin/docker-compose -f $COMPOSE_FILE down
TimeoutStartSec=300 TimeoutStartSec=300
@ -680,6 +948,8 @@ systemctl daemon-reload
systemctl enable my-uploader-bot.service systemctl enable my-uploader-bot.service
log_success "Автозапуск настроен" log_success "Автозапуск настроен"
log_progress "final_check"
fi
echo "" echo ""
echo -e "${GREEN}================================================${NC}" echo -e "${GREEN}================================================${NC}"
@ -687,19 +957,37 @@ echo -e "${WHITE}🎉 УСТАНОВКА ЗАВЕРШЕНА УСПЕШНО!${NC}
echo -e "${GREEN}================================================${NC}" echo -e "${GREEN}================================================${NC}"
echo "" echo ""
echo -e "${CYAN}🌐 Домен:${NC} https://$DOMAIN" echo -e "${CYAN}🌐 Домен:${NC} https://$DOMAIN"
echo -e "${CYAN}🏷️ Тип ноды:${NC} $NODE_TYPE"
echo -e "${CYAN}📁 Проект:${NC} $MAIN_PROJECT_DIR" echo -e "${CYAN}📁 Проект:${NC} $MAIN_PROJECT_DIR"
echo -e "${CYAN}👤 Пользователь:${NC} $SERVICE_USER" echo -e "${CYAN}👤 Пользователь:${NC} $SERVICE_USER"
echo -e "${CYAN}📊 Прогресс:${NC} $PROGRESS_FILE"
echo "" echo ""
echo -e "${YELLOW}📦 Установленные модули:${NC}" echo -e "${YELLOW}📦 Установленные модули:${NC}"
echo -e " 🚀 Uploader Bot: $PROJECT_DIR/uploader-bot" echo -e " 🚀 Uploader Bot: $PROJECT_DIR/uploader-bot"
echo -e " 🔄 Converter: $PROJECT_DIR/converter-module" echo -e " 🔄 Converter: $PROJECT_DIR/converter-module"
if [ "$NODE_TYPE" = "main" ]; then
echo -e " 🌐 Web2 Client: $PROJECT_DIR/web2-client" echo -e " 🌐 Web2 Client: $PROJECT_DIR/web2-client"
else
echo -e " 🌐 Web2 Client: ${YELLOW}пропущен (обычная нода)${NC}"
fi
echo "" echo ""
echo -e "${YELLOW}🌍 Доступные endpoints:${NC}"
echo -e " 📊 API: https://$DOMAIN/" # Показываем разные endpoints в зависимости от типа ноды
echo -e " 💻 Web Interface: https://$DOMAIN/web/" if [ "$NODE_TYPE" = "main" ]; then
echo -e "${YELLOW}🌍 Доступные endpoints (основная нода):${NC}"
echo -e " 🌐 Web Interface: https://$DOMAIN/"
echo -e " 📊 API: https://$DOMAIN/api/"
echo -e " 📤 Upload: https://$DOMAIN/api/upload"
echo -e " 🔄 Converter API: https://$DOMAIN/converter/" echo -e " 🔄 Converter API: https://$DOMAIN/converter/"
echo -e " ❤️ Health Check: https://$DOMAIN/health" echo -e " ❤️ Health Check: https://$DOMAIN/health"
else
echo -e "${YELLOW}🌍 Доступные endpoints (обычная нода):${NC}"
echo -e " 📊 API: https://$DOMAIN/"
echo -e " 📤 Upload: https://$DOMAIN/upload"
echo -e " 🔄 Converter API: https://$DOMAIN/converter/"
echo -e " ❤️ Health Check: https://$DOMAIN/health"
fi
echo "" echo ""
echo -e "${YELLOW}📋 Полезные команды:${NC}" echo -e "${YELLOW}📋 Полезные команды:${NC}"
echo -e "${WHITE}# Статус системы${NC}" echo -e "${WHITE}# Статус системы${NC}"
@ -722,6 +1010,12 @@ echo "sudo systemctl start my-uploader-bot"
echo "sudo systemctl stop my-uploader-bot" echo "sudo systemctl stop my-uploader-bot"
echo "sudo systemctl status my-uploader-bot" echo "sudo systemctl status my-uploader-bot"
echo "" echo ""
echo -e "${YELLOW}🔄 Повторная установка:${NC}"
echo "# Для полной переустановки:"
echo "sudo rm -f $PROGRESS_FILE"
echo "# Для сброса определенного этапа отредактируйте:"
echo "sudo nano $PROGRESS_FILE"
echo ""
echo -e "${YELLOW}🌍 MY Network API:${NC}" echo -e "${YELLOW}🌍 MY Network API:${NC}"
echo "curl https://$DOMAIN/api/my/bootstrap/config" echo "curl https://$DOMAIN/api/my/bootstrap/config"
echo "" echo ""
@ -732,6 +1026,9 @@ echo ""
echo -e "${GREEN}✅ MY Uploader Bot готов к работе!${NC}" echo -e "${GREEN}✅ MY Uploader Bot готов к работе!${NC}"
echo "" echo ""
# Отметка полной установки
log_progress "installation_complete"
# Финальная проверка доступности # Финальная проверка доступности
log "Финальная проверка через 5 секунд..." log "Финальная проверка через 5 секунд..."
sleep 5 sleep 5