# ========================================== # 🐳 VPN-PROXY DOCKER INSTALLER ДЛЯ WINDOWS # ========================================== # Устанавливает VPN-прокси через Docker Compose # и опционально настраивает Discord/Vesktop # ========================================== param( [switch]$SkipDockerCheck, [switch]$SkipDiscord, [switch]$Force # Принудительная переустановка ) # Цвета для красивого вывода function Write-Step { param($msg) Write-Host "`n📦 $msg" -ForegroundColor Cyan } function Write-Success { param($msg) Write-Host " ✅ $msg" -ForegroundColor Green } function Write-Warning { param($msg) Write-Host " ⚠️ $msg" -ForegroundColor Yellow } function Write-Error { param($msg) Write-Host " ❌ $msg" -ForegroundColor Red } function Write-Info { param($msg) Write-Host " ℹ️ $msg" -ForegroundColor Gray } Clear-Host Write-Host "==========================================" -ForegroundColor Cyan Write-Host " 🐳 VPN-PROXY DOCKER INSTALLER " -ForegroundColor Cyan Write-Host "==========================================" -ForegroundColor Cyan # Определяем директорию скрипта $ScriptDir = if ($PSScriptRoot) { $PSScriptRoot } else { Split-Path -Parent $MyInvocation.MyCommand.Path } if (-not $ScriptDir) { $ScriptDir = Get-Location } Write-Info "Директория проекта: $ScriptDir" # ========================================== # ШАГ 0: ПРОВЕРКА СУЩЕСТВУЮЩЕЙ УСТАНОВКИ # ========================================== Write-Step "Проверка существующей установки..." $existingContainer = docker ps -a --filter "name=sing-proxy" --format "{{.Names}}" 2>$null $containerRunning = docker ps --filter "name=sing-proxy" --format "{{.Status}}" 2>$null if ($existingContainer -and -not $Force) { Write-Host "" Write-Host "==========================================" -ForegroundColor Green Write-Host " ✅ VPN-PROXY УЖЕ УСТАНОВЛЕН! " -ForegroundColor Green Write-Host "==========================================" -ForegroundColor Green Write-Host "" # Статус контейнера if ($containerRunning -match "Up") { Write-Host "📊 Статус: " -NoNewline -ForegroundColor Yellow Write-Host "РАБОТАЕТ" -ForegroundColor Green Write-Host " Контейнер: sing-proxy" -ForegroundColor Gray Write-Host " Uptime: $containerRunning" -ForegroundColor Gray } else { Write-Host "📊 Статус: " -NoNewline -ForegroundColor Yellow Write-Host "ОСТАНОВЛЕН" -ForegroundColor Red $containerStatus = docker ps -a --filter "name=sing-proxy" --format "{{.Status}}" 2>$null Write-Host " Контейнер: sing-proxy ($containerStatus)" -ForegroundColor Gray } Write-Host "" Write-Host "📡 Адреса подключения:" -ForegroundColor Yellow Write-Host " Веб-интерфейс: http://localhost:3456" -ForegroundColor White Write-Host " HTTP/SOCKS Прокси: 127.0.0.1:8080" -ForegroundColor White Write-Host "" Write-Host "📁 Расположение:" -ForegroundColor Yellow Write-Host " Проект: $ScriptDir" -ForegroundColor White Write-Host " Данные: $ScriptDir\data" -ForegroundColor White Write-Host "" # Проверяем ProxiFyre $proxifyreInstalled = Test-Path "C:\Tools\ProxiFyre\ProxiFyre.exe" if ($proxifyreInstalled) { $proxifyreService = Get-Service -Name "ProxiFyreService" -ErrorAction SilentlyContinue Write-Host "🛡️ ProxiFyre:" -ForegroundColor Yellow Write-Host " Путь: C:\Tools\ProxiFyre" -ForegroundColor White Write-Host " Статус: $($proxifyreService.Status)" -ForegroundColor White # Показываем настроенные приложения из конфига $configPath = "C:\Tools\ProxiFyre\app-config.json" if (Test-Path $configPath) { try { $config = Get-Content $configPath -Raw | ConvertFrom-Json $apps = $config.proxies[0].appNames -join ", " $proxy = $config.proxies[0].socks5ProxyEndpoint Write-Host " Прокси: $proxy" -ForegroundColor White Write-Host " Приложения: $apps" -ForegroundColor White } catch {} } Write-Host "" } Write-Host "==========================================" -ForegroundColor Cyan Write-Host "" Write-Host "Что вы хотите сделать?" -ForegroundColor Yellow Write-Host " [1] Запустить контейнер (если остановлен)" -ForegroundColor White Write-Host " [2] Перезапустить контейнер" -ForegroundColor White Write-Host " [3] Переустановить (пересобрать)" -ForegroundColor White Write-Host " [4] Показать логи" -ForegroundColor White Write-Host " [5] Открыть веб-интерфейс" -ForegroundColor White Write-Host " [q] Выход" -ForegroundColor White Write-Host "" $choice = Read-Host "👉 Выбор (1-5/q)" switch ($choice) { "1" { Write-Step "Запуск контейнера..." Push-Location $ScriptDir docker compose start Pop-Location Write-Success "Контейнер запущен!" Write-Host " Веб-интерфейс: http://localhost:3456" -ForegroundColor Green exit 0 } "2" { Write-Step "Перезапуск контейнера..." Push-Location $ScriptDir docker compose restart Pop-Location Write-Success "Контейнер перезапущен!" exit 0 } "3" { Write-Info "Переустановка..." # Продолжаем выполнение скрипта } "4" { Write-Step "Логи контейнера (последние 50 строк):" docker logs --tail 50 sing-proxy exit 0 } "5" { Start-Process "http://localhost:3456" exit 0 } default { Write-Info "Выход" exit 0 } } } # ========================================== # ШАГ 1: ПРОВЕРКА DOCKER # ========================================== Write-Step "Проверка Docker..." $DockerInstalled = $false $DockerRunning = $false $DockerComposeAvailable = $false # Проверяем, установлен ли Docker try { $dockerVersion = docker --version 2>&1 if ($LASTEXITCODE -eq 0 -and $dockerVersion -match "Docker version") { Write-Success "Docker установлен: $dockerVersion" $DockerInstalled = $true } } catch { $DockerInstalled = $false } if (-not $DockerInstalled -and -not $SkipDockerCheck) { Write-Error "Docker не найден!" Write-Host "" Write-Host "📥 Установите Docker Desktop:" -ForegroundColor Yellow Write-Host " https://www.docker.com/products/docker-desktop/" -ForegroundColor White Write-Host "" Write-Host "После установки:" -ForegroundColor Yellow Write-Host " 1. Запустите Docker Desktop" -ForegroundColor White Write-Host " 2. Дождитесь, пока появится зелёная иконка 🐳 в трее" -ForegroundColor White Write-Host " 3. Запустите этот скрипт заново" -ForegroundColor White Write-Host "" $openUrl = Read-Host "Открыть страницу загрузки Docker? (y/n)" if ($openUrl -eq "y" -or $openUrl -eq "Y") { Start-Process "https://www.docker.com/products/docker-desktop/" } exit 1 } # Проверяем, запущен ли Docker if ($DockerInstalled) { try { $dockerInfo = docker info 2>&1 if ($LASTEXITCODE -eq 0) { Write-Success "Docker daemon запущен" $DockerRunning = $true } } catch { $DockerRunning = $false } if (-not $DockerRunning -and -not $SkipDockerCheck) { Write-Warning "Docker установлен, но не запущен!" Write-Host "" Write-Host "🚀 Запустите Docker Desktop и дождитесь, пока:" -ForegroundColor Yellow Write-Host " - Появится зелёная иконка 🐳 в трее" -ForegroundColor White Write-Host " - Или надпись 'Docker Desktop is running'" -ForegroundColor White Write-Host "" $waitForDocker = Read-Host "Ожидать запуска Docker? (y/n)" if ($waitForDocker -eq "y" -or $waitForDocker -eq "Y") { Write-Info "Ожидание запуска Docker..." $attempts = 0 $maxAttempts = 60 # 5 минут макс while (-not $DockerRunning -and $attempts -lt $maxAttempts) { Start-Sleep -Seconds 5 $attempts++ Write-Host "." -NoNewline try { $dockerInfo = docker info 2>&1 if ($LASTEXITCODE -eq 0) { $DockerRunning = $true } } catch {} } Write-Host "" if ($DockerRunning) { Write-Success "Docker запустился!" } else { Write-Error "Таймаут ожидания Docker. Запустите Docker Desktop вручную." exit 1 } } else { exit 1 } } } # Проверяем Docker Compose if ($DockerRunning) { try { $composeVersion = docker compose version 2>&1 if ($LASTEXITCODE -eq 0) { Write-Success "Docker Compose доступен: $composeVersion" $DockerComposeAvailable = $true } } catch {} if (-not $DockerComposeAvailable) { # Пробуем старый формат docker-compose try { $composeVersion = docker-compose --version 2>&1 if ($LASTEXITCODE -eq 0) { Write-Success "Docker Compose (legacy) доступен: $composeVersion" $DockerComposeAvailable = $true } } catch {} } if (-not $DockerComposeAvailable -and -not $SkipDockerCheck) { Write-Error "Docker Compose не найден!" Write-Host "" Write-Host "Docker Compose обычно входит в Docker Desktop." -ForegroundColor Yellow Write-Host "Попробуйте переустановить Docker Desktop." -ForegroundColor Yellow exit 1 } } # ========================================== # ШАГ 2: ПРОВЕРКА ФАЙЛОВ ПРОЕКТА # ========================================== Write-Step "Проверка файлов проекта..." $dockerComposeFile = Join-Path $ScriptDir "docker-compose.yml" $dockerDir = Join-Path $ScriptDir "docker" $dockerFile = Join-Path $dockerDir "Dockerfile.singbox" if (-not (Test-Path $dockerComposeFile)) { Write-Error "Не найден docker-compose.yml в $ScriptDir" exit 1 } Write-Success "docker-compose.yml найден" if (-not (Test-Path $dockerFile)) { Write-Error "Не найден docker/Dockerfile.singbox" exit 1 } Write-Success "Dockerfile.singbox найден" # ========================================== # ШАГ 3: СБОРКА И ЗАПУСК # ========================================== Write-Step "Сборка Docker-контейнера..." # Переходим в директорию проекта Push-Location $ScriptDir try { # Останавливаем старый контейнер если есть Write-Info "Останавливаем старый контейнер (если есть)..." docker compose down 2>&1 | Out-Null # Собираем образ Write-Info "Сборка образа (может занять 1-2 минуты)..." $buildOutput = docker compose build 2>&1 if ($LASTEXITCODE -ne 0) { Write-Error "Ошибка сборки Docker образа!" Write-Host $buildOutput -ForegroundColor Red Pop-Location exit 1 } Write-Success "Образ собран" # Запускаем контейнер Write-Info "Запуск контейнера..." $upOutput = docker compose up -d 2>&1 if ($LASTEXITCODE -ne 0) { Write-Error "Ошибка запуска контейнера!" Write-Host $upOutput -ForegroundColor Red Pop-Location exit 1 } Write-Success "Контейнер запущен" } finally { Pop-Location } # Ждём немного, чтобы контейнер инициализировался Start-Sleep -Seconds 3 # Проверяем статус Write-Step "Проверка статуса..." $containerStatus = docker ps --filter "name=sing-proxy" --format "{{.Status}}" 2>&1 if ($containerStatus -match "Up") { Write-Success "Контейнер sing-proxy работает: $containerStatus" } else { Write-Warning "Контейнер может ещё запускаться. Проверьте через: docker ps" } # ========================================== # ШАГ 4: ИНФОРМАЦИЯ О ПОДКЛЮЧЕНИИ # ========================================== Write-Host "" Write-Host "==========================================" -ForegroundColor Green Write-Host " 🎉 УСТАНОВКА ЗАВЕРШЕНА! " -ForegroundColor Green Write-Host "==========================================" -ForegroundColor Green Write-Host "" Write-Host "📡 Адреса подключения:" -ForegroundColor Yellow Write-Host " Веб-интерфейс: http://localhost:3456" -ForegroundColor White Write-Host " HTTP/SOCKS Прокси: 127.0.0.1:8080" -ForegroundColor White Write-Host "" Write-Host "📋 Следующие шаги:" -ForegroundColor Yellow Write-Host " 1. Откройте http://localhost:3456 в браузере" -ForegroundColor White Write-Host " 2. Вставьте VLESS ссылку или URL подписки" -ForegroundColor White Write-Host " 3. Нажмите 'Применить'" -ForegroundColor White Write-Host "" # ========================================== # ШАГ 5: УСТАНОВКА СКРИПТА ДЛЯ DISCORD # ========================================== if (-not $SkipDiscord) { Write-Host "==========================================" -ForegroundColor Cyan Write-Host "" Write-Host "🎮 Хотите установить ProxiFyre для Discord/Vesktop?" -ForegroundColor Yellow Write-Host " Это позволит направить трафик Discord через прокси" -ForegroundColor Gray Write-Host "" Write-Host " [1] Да, установить для Discord" -ForegroundColor White Write-Host " [2] Да, установить для Vesktop" -ForegroundColor White Write-Host " [3] Да, установить для Discord + Vesktop" -ForegroundColor White Write-Host " [n] Нет, пропустить" -ForegroundColor White Write-Host "" $discordChoice = Read-Host "👉 Выбор (1-3/n)" if ($discordChoice -match "^[123]$") { # Проверяем права администратора $isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator") if (-not $isAdmin) { Write-Warning "Для установки ProxiFyre нужны права администратора!" Write-Host "" Write-Host "Запустите этот скрипт от имени администратора," -ForegroundColor Yellow Write-Host "или запустите discord-windows-hack.ps1 отдельно:" -ForegroundColor Yellow Write-Host "" Write-Host " 1. Откройте PowerShell от имени Администратора" -ForegroundColor White Write-Host " 2. Выполните:" -ForegroundColor White Write-Host " cd `"$ScriptDir`"" -ForegroundColor Cyan Write-Host " .\discord-windows-hack.ps1" -ForegroundColor Cyan Write-Host "" } else { # Запускаем скрипт с параметрами для неинтерактивного режима $discordScript = Join-Path $ScriptDir "discord-windows-hack.ps1" if (Test-Path $discordScript) { Write-Step "Запуск установки ProxiFyre для Discord..." # Определяем целевые приложения $targetApps = switch ($discordChoice) { "1" { @("Discord") } "2" { @("Vesktop") } "3" { @("Vesktop", "Discord") } } # Вызываем discord-windows-hack.ps1 с параметрами (без дублирования кода) & $discordScript -Proxy "127.0.0.1:8080" -Apps $targetApps -Force # Предупреждение о UDP Write-Host "" Write-Host "==========================================" -ForegroundColor Yellow Write-Host " ⚠️ ВАЖНО: ГОЛОСОВЫЕ ЗВОНКИ DISCORD " -ForegroundColor Yellow Write-Host "==========================================" -ForegroundColor Yellow Write-Host "" Write-Host "Docker Desktop на Windows НЕ ПОДДЕРЖИВАЕТ UDP!" -ForegroundColor Red Write-Host "Голосовые звонки Discord могут не работать." -ForegroundColor Red Write-Host "" Write-Host "Для полной поддержки голоса запустите:" -ForegroundColor Cyan Write-Host " .\setup-singbox-native.ps1" -ForegroundColor White Write-Host "" Write-Host "Этот скрипт установит нативный sing-box," -ForegroundColor Gray Write-Host "который поддерживает UDP трафик." -ForegroundColor Gray } else { Write-Warning "Скрипт discord-windows-hack.ps1 не найден" Write-Info "Скачайте его или создайте вручную" } } } else { Write-Info "Установка Discord прокси пропущена" } } # ========================================== # ФИНАЛЬНЫЕ ИНСТРУКЦИИ # ========================================== Write-Host "" Write-Host "==========================================" -ForegroundColor Cyan Write-Host " 📋 ПОЛЕЗНЫЕ КОМАНДЫ " -ForegroundColor Cyan Write-Host "==========================================" -ForegroundColor Cyan Write-Host "" Write-Host "🐳 Docker:" -ForegroundColor Yellow Write-Host " docker ps - статус контейнера" -ForegroundColor Gray Write-Host " docker logs --tail 50 sing-proxy - логи VPN-прокси" -ForegroundColor Gray Write-Host " docker compose restart - перезапуск" -ForegroundColor Gray Write-Host " docker compose down - остановка" -ForegroundColor Gray Write-Host "" Write-Host "🛡️ ProxiFyre (если установлен):" -ForegroundColor Yellow Write-Host " Get-Content C:\Tools\ProxiFyre\app-config.json - конфиг" -ForegroundColor Gray Write-Host " Get-ChildItem C:\Tools\ProxiFyre\logs - список логов" -ForegroundColor Gray Write-Host " Get-Content C:\Tools\ProxiFyre\logs\*.log -Tail 50 - последние логи" -ForegroundColor Gray Write-Host " Get-Service ProxiFyreService - статус службы" -ForegroundColor Gray Write-Host " Restart-Service ProxiFyreService - перезапуск службы" -ForegroundColor Gray Write-Host ""