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