edit script

This commit is contained in:
user 2025-07-03 00:34:15 +03:00
parent 444b5af31a
commit a3e99d6e62
1 changed files with 613 additions and 215 deletions

View File

@ -1,17 +1,12 @@
#!/bin/bash #!/bin/bash
# ============================================================================= # =============================================================================
# MY UPLOADER BOT - PRODUCTION SERVER SETUP SCRIPT # MY UPLOADER BOT - ПОЛНАЯ АВТОМАТИЧЕСКАЯ УСТАНОВКА НА PRODUCTION СЕРВЕР
# ============================================================================= # =============================================================================
# Полная автоматическая установка на чистом Ubuntu/Debian сервере # Клонирует все модули из projscale.dev и настраивает полную систему
#
# Использование:
# ./setup_production_server.sh yourdomain.com your@email.com
#
# Автор: MY Network Team
# ============================================================================= # =============================================================================
set -e # Выход при любой ошибке set -euo pipefail # Выход при любой ошибке
# Цвета для вывода # Цвета для вывода
RED='\033[0;31m' RED='\033[0;31m'
@ -19,330 +14,733 @@ GREEN='\033[0;32m'
YELLOW='\033[1;33m' YELLOW='\033[1;33m'
BLUE='\033[0;34m' BLUE='\033[0;34m'
PURPLE='\033[0;35m' PURPLE='\033[0;35m'
CYAN='\033[0;36m'
WHITE='\033[1;37m'
NC='\033[0m' # No Color NC='\033[0m' # No Color
# Логирование # Функция логирования
log() { 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() { log_error() {
echo -e "${YELLOW}[$(date +'%Y-%m-%d %H:%M:%S')] WARNING: $1${NC}" echo -e "${RED}[ERROR]${NC} $1" >&2
} }
error() { log_success() {
echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: $1${NC}" echo -e "${GREEN}[SUCCESS]${NC} $1"
exit 1
} }
info() { log_warning() {
echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')] $1${NC}" echo -e "${YELLOW}[WARNING]${NC} $1"
} }
header() { log_info() {
echo -e "${PURPLE}" echo -e "${BLUE}[INFO]${NC} $1"
echo "=============================================="
echo " $1"
echo "=============================================="
echo -e "${NC}"
} }
# Проверка аргументов # Проверка аргументов
if [ $# -lt 2 ]; then if [ $# -lt 1 ]; then
error "Usage: $0 <domain> <email>" echo -e "${RED}Использование: $0 <domain> [email]${NC}"
echo "Example: $0 mydomain.com admin@mydomain.com" echo "Примеры:"
echo " $0 my-uploader.example.com"
echo " $0 my-uploader.example.com admin@example.com"
exit 1 exit 1
fi fi
DOMAIN="$1" DOMAIN="$1"
EMAIL="$2" EMAIL="${2:-admin@${DOMAIN}}"
PROJECT_DIR="/opt/my-uploader-bot" PROJECT_DIR="/home/myuploader"
NGINX_CONFIG="/etc/nginx/sites-available/my-uploader-bot"
SERVICE_USER="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" echo ""
log "Email: $EMAIL" echo -e "${PURPLE}================================================${NC}"
log "Проект будет установлен в: $PROJECT_DIR" 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 прав # Проверка прав root
if [[ $EUID -ne 0 ]]; then if [ "$EUID" -ne 0 ]; then
error "Этот скрипт должен запускаться с правами root (sudo)" log_error "Этот скрипт должен запускаться с правами root"
exit 1
fi fi
# Проверка операционной системы # Проверка интернет соединения
if ! command -v apt-get &> /dev/null; then if ! ping -c 1 google.com &> /dev/null; then
error "Этот скрипт поддерживает только Ubuntu/Debian системы" log_error "Нет интернет соединения"
exit 1
fi fi
header "📦 ШАГ 1: ОБНОВЛЕНИЕ СИСТЕМЫ" echo ""
echo -e "${BLUE}==========================================${NC}"
echo -e "${WHITE} 🔄 ШАГ 1: ОБНОВЛЕНИЕ СИСТЕМЫ${NC}"
echo -e "${BLUE}==========================================${NC}"
echo ""
log "Обновление списка пакетов..." log "Обновление списка пакетов..."
apt-get update -y apt update -y
log "Обновление установленных пакетов..." log "Обновление системы..."
apt-get upgrade -y apt upgrade -y
log "Установка базовых пакетов..." log "Установка базовых пакетов..."
apt-get install -y \ apt install -y \
curl \ curl \
wget \ wget \
git \ git \
unzip \ unzip \
htop \
nano \
vim \
tree \
jq \
software-properties-common \ software-properties-common \
apt-transport-https \ apt-transport-https \
ca-certificates \ ca-certificates \
gnupg \ gnupg \
lsb-release \ lsb-release \
htop \ ufw \
nano \ fail2ban \
vim \ netstat-nat \
net-tools \ python3 \
ufw 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 # Удаление старых версий Docker
log "Удаление старых версий Docker..." log "Удаление старых версий Docker..."
apt-get remove -y docker docker-engine docker.io containerd runc || true apt remove -y docker docker-engine docker.io containerd runc 2>/dev/null || 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
# Установка Docker # Установка 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..." log "Установка Docker..."
apt-get update apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# Установка Docker Compose standalone # Установка Docker Compose standalone
log "Установка Docker Compose..." 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 chmod +x /usr/local/bin/docker-compose
ln -sf /usr/local/bin/docker-compose /usr/bin/docker-compose
# Запуск и включение Docker # Запуск Docker
systemctl enable docker log "Запуск Docker..."
systemctl start docker systemctl start docker
systemctl enable docker
log "Docker версия: $(docker --version)" # Проверка Docker
log "Docker Compose версия: $(docker-compose --version)" 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 log "Установка Nginx..."
ufw --force reset apt install -y nginx
# Базовая политика log "Запуск Nginx..."
ufw default deny incoming systemctl start nginx
ufw default allow outgoing systemctl enable nginx
# Разрешение SSH (важно для сохранения доступа) log "Nginx версия: $(nginx -v 2>&1)"
ufw allow 22/tcp comment "SSH" log_success "Nginx установлен"
# Разрешение HTTP и HTTPS echo ""
ufw allow 80/tcp comment "HTTP" echo -e "${BLUE}==========================================${NC}"
ufw allow 443/tcp comment "HTTPS" echo -e "${WHITE} 🔐 ШАГ 4: УСТАНОВКА CERTBOT${NC}"
echo -e "${BLUE}==========================================${NC}"
echo ""
# Включение firewall log "Установка snapd (если нужно)..."
ufw --force enable apt install -y snapd
log "Статус firewall:"
ufw status verbose
header "🔒 ШАГ 4: УСТАНОВКА CERTBOT"
log "Установка snapd..."
apt-get install -y snapd
log "Установка Certbot через snap..." log "Установка Certbot через snap..."
snap install core snap install core; snap refresh core
snap refresh core
snap install --classic certbot snap install --classic certbot
# Создание symlink 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 установлен"
header "👤 ШАГ 5: СОЗДАНИЕ ПОЛЬЗОВАТЕЛЯ СЕРВИСА" echo ""
echo -e "${BLUE}==========================================${NC}"
echo -e "${WHITE} 👤 ШАГ 5: СОЗДАНИЕ ПОЛЬЗОВАТЕЛЯ СЕРВИСА${NC}"
echo -e "${BLUE}==========================================${NC}"
echo ""
log "Создание пользователя $SERVICE_USER..." log "Создание пользователя $SERVICE_USER..."
if ! id "$SERVICE_USER" &>/dev/null; then if ! id "$SERVICE_USER" &>/dev/null; then
useradd -r -s /bin/bash -d /home/$SERVICE_USER -m $SERVICE_USER useradd -m -s /bin/bash "$SERVICE_USER"
usermod -aG docker $SERVICE_USER usermod -aG sudo "$SERVICE_USER"
log "Пользователь $SERVICE_USER создан" usermod -aG docker "$SERVICE_USER"
log_success "Пользователь $SERVICE_USER создан"
else else
log "Пользователь $SERVICE_USER уже существует" usermod -aG docker "$SERVICE_USER"
log_info "Пользователь $SERVICE_USER уже существует"
fi fi
header "📂 ШАГ 6: ПОДГОТОВКА ПРОЕКТА" echo ""
echo -e "${BLUE}==========================================${NC}"
echo -e "${WHITE} 📂 ШАГ 6: КЛОНИРОВАНИЕ РЕПОЗИТОРИЕВ${NC}"
echo -e "${BLUE}==========================================${NC}"
echo ""
log "Создание директории проекта..." log "Создание директории проекта..."
mkdir -p $PROJECT_DIR mkdir -p "$PROJECT_DIR"
cd $PROJECT_DIR chown "$SERVICE_USER:$SERVICE_USER" "$PROJECT_DIR"
# Если это git репозиторий, клонируем. Иначе копируем текущую директорию # Переключение на пользователя myuploader для клонирования
if [ -d "$(dirname $0)/.git" ]; then cd "$PROJECT_DIR"
log "Клонирование из Git репозитория..."
# Определяем URL репозитория log "Клонирование uploader-bot..."
REPO_URL=$(cd "$(dirname $0)" && git config --get remote.origin.url || echo "") if [ -d "uploader-bot" ]; then
if [ -n "$REPO_URL" ]; then log_warning "Директория uploader-bot уже существует, удаляем..."
git clone "$REPO_URL" . rm -rf uploader-bot
else
warn "Git репозиторий не найден, копирую файлы локально..."
cp -r "$(dirname $0)"/* .
fi
else
log "Копирование файлов проекта..."
cp -r "$(dirname $0)"/* .
fi fi
sudo -u "$SERVICE_USER" git clone "$UPLOADER_REPO" uploader-bot
log_success "uploader-bot склонирован"
# Установка владельца log "Клонирование converter-module..."
chown -R $SERVICE_USER:$SERVICE_USER $PROJECT_DIR 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 для получения сертификатов echo ""
systemctl stop nginx echo -e "${BLUE}==========================================${NC}"
echo -e "${WHITE} ⚙️ ШАГ 7: НАСТРОЙКА ОКРУЖЕНИЯ${NC}"
echo -e "${BLUE}==========================================${NC}"
echo ""
log "Создание конфигурации Nginx..." # Переход в основную директорию uploader-bot
./scripts/create_nginx_config.sh $DOMAIN $PROJECT_DIR 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 # Создание .env файла
fuser -k 80/tcp 2>/dev/null || true cat > "$MAIN_PROJECT_DIR/.env" << EOF
fuser -k 443/tcp 2>/dev/null || true # MY UPLOADER BOT - PRODUCTION CONFIGURATION
NODE_ENV=production
DEBUG=false
# Получение сертификатов # Domain
certbot certonly \ MY_NETWORK_DOMAIN=$DOMAIN
--standalone \
--non-interactive \
--agree-tos \
--email "$EMAIL" \
--domains "$DOMAIN,www.$DOMAIN" \
--no-eff-email
log "Настройка автообновления сертификатов..." # Database
systemctl enable certbot.timer DATABASE_URL=postgresql://my_user:$POSTGRES_PASSWORD@postgres:5432/my_uploader_db
systemctl start certbot.timer POSTGRES_HOST=postgres
POSTGRES_PORT=5432
POSTGRES_DB=my_uploader_db
POSTGRES_USER=my_user
POSTGRES_PASSWORD=$POSTGRES_PASSWORD
# Проверка автообновления # Redis
certbot renew --dry-run 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 конфигурации..." # MY Network Settings
./scripts/setup_production_env.sh $DOMAIN $EMAIL 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 "Настройка дополнительных модулей..." # Converter Settings (On-Demand)
./scripts/setup_modules.sh $PROJECT_DIR 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 режиме..." # Monitoring
cd $PROJECT_DIR GRAFANA_PASSWORD=admin123
EOF
# Запуск от имени пользователя сервиса chown "$SERVICE_USER:$SERVICE_USER" "$MAIN_PROJECT_DIR/.env"
sudo -u $SERVICE_USER docker-compose -f docker-compose.production.yml pull log_success "Файл .env создан"
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
log "Ожидание запуска сервисов..." # Создание симлинков для модулей в uploader-bot
sleep 30 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_success "Симлинки созданы"
log "Статус Docker сервисов:"
sudo -u $SERVICE_USER docker-compose -f docker-compose.production.yml ps
header "🌐 ШАГ 12: ЗАПУСК NGINX" echo ""
echo -e "${BLUE}==========================================${NC}"
echo -e "${WHITE} 🌐 ШАГ 8: НАСТРОЙКА NGINX${NC}"
echo -e "${BLUE}==========================================${NC}"
echo ""
log "Включение конфигурации Nginx..." log "Создание Nginx конфигурации..."
ln -sf $NGINX_CONFIG /etc/nginx/sites-enabled/my-uploader-bot
# Создание базового 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 rm -f /etc/nginx/sites-enabled/default
log "Проверка конфигурации Nginx..." # Проверка конфигурации
nginx -t if nginx -t; then
systemctl reload nginx
log "Запуск Nginx..." log_success "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 сервисы: Работают"
else else
error "❌ Docker сервисы: Не запущены" log_error "Ошибка в конфигурации Nginx"
exit 1
fi fi
# Проверка Nginx echo ""
if systemctl is-active --quiet nginx; then echo -e "${BLUE}==========================================${NC}"
log "✅ Nginx: Работает" echo -e "${WHITE} 🔐 ШАГ 9: ПОЛУЧЕНИЕ SSL СЕРТИФИКАТА${NC}"
else echo -e "${BLUE}==========================================${NC}"
error "❌ Nginx: Не запущен" 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 fi
# Проверка SSL # Получение SSL сертификата
if curl -sf "https://$DOMAIN/health" > /dev/null; then if certbot --nginx -d "$DOMAIN" --non-interactive --agree-tos --email "$EMAIL" --redirect; then
log "✅ SSL сертификат: Работает" log_success "SSL сертификат получен"
else else
warn "⚠️ SSL проверка не прошла (сервис может еще запускаться)" log_error "Не удалось получить SSL сертификат"
log_warning "Можете получить его позже командой:"
log_warning "sudo certbot --nginx -d $DOMAIN"
fi fi
# Проверка API echo ""
log "Ожидание полного запуска API..." echo -e "${BLUE}==========================================${NC}"
sleep 60 echo -e "${WHITE} 🔒 ШАГ 10: НАСТРОЙКА БЕЗОПАСНОСТИ${NC}"
echo -e "${BLUE}==========================================${NC}"
echo ""
if curl -sf "https://$DOMAIN/api/my/health" > /dev/null; then log "Настройка UFW firewall..."
log "✅ MY Network API: Работает"
# Сброс 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 = ^<HOST> -.*"(GET|POST|HEAD).*" (4\d\d|5\d\d) .*$
^<HOST> -.*".*" (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 else
warn "⚠️ MY Network API пока не доступен" log_error "Не найден docker-compose файл"
exit 1
fi fi
header "🎉 УСТАНОВКА ЗАВЕРШЕНА!" log "Используется $COMPOSE_FILE"
info "=== ИНФОРМАЦИЯ О РАЗВЕРТЫВАНИИ ===" # Сборка образов от имени пользователя сервиса
info "Домен: https://$DOMAIN" log "Сборка основного приложения..."
info "API: https://$DOMAIN/api/" sudo -u "$SERVICE_USER" docker-compose -f "$COMPOSE_FILE" build
info "Мониторинг: https://$DOMAIN/api/my/monitor/"
info "Health Check: https://$DOMAIN/health"
info "Директория проекта: $PROJECT_DIR"
info "Пользователь: $SERVICE_USER"
info "Nginx конфиг: $NGINX_CONFIG"
info "=== ПОЛЕЗНЫЕ КОМАНДЫ ===" # Сборка converter image (если есть профиль build-only)
info "Просмотр логов: cd $PROJECT_DIR && sudo -u $SERVICE_USER docker-compose -f docker-compose.production.yml logs -f" log "Сборка converter image..."
info "Перезапуск: cd $PROJECT_DIR && sudo -u $SERVICE_USER docker-compose -f docker-compose.production.yml restart" sudo -u "$SERVICE_USER" docker-compose -f "$COMPOSE_FILE" --profile build-only build converter-build 2>/dev/null || \
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" sudo -u "$SERVICE_USER" docker-compose -f "$COMPOSE_FILE" build converter 2>/dev/null || \
log_warning "Converter build пропущен (нет соответствующего сервиса)"
info "=== БЕЗОПАСНОСТЬ ===" log "Запуск приложения..."
info "Firewall: ufw status" sudo -u "$SERVICE_USER" docker-compose -f "$COMPOSE_FILE" up -d
info "SSL сертификаты: ls -la /etc/letsencrypt/live/$DOMAIN/"
info "Автообновление SSL: systemctl status certbot.timer"
log "🚀 Проект успешно развернут на https://$DOMAIN" # Ожидание запуска
log "📝 Не забудьте настроить Telegram токены в $PROJECT_DIR/.env.production" log "Ожидание запуска сервисов..."
sleep 15
exit 0 # Проверка статуса
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}"