From d37ecf6071aae7f0b1a1d845cfb3aeeeed47c8c0 Mon Sep 17 00:00:00 2001 From: onysd Date: Mon, 27 Jul 2026 23:35:20 +0300 Subject: [PATCH] updated to docker containers new name --- .docker_naming | 1 + deploy/docker-compose.yml | 14 +- deploy/migrate-docker-naming.ps1 | 122 +++++++++++ scripts/check-local-runtime.ps1 | 2 +- scripts/validate-android-big-video-upload.ps1 | 2 +- ...alidate-android-offline-media-recovery.ps1 | 2 +- scripts/validate-android-video-upload.ps1 | 2 +- start-server.bat | 196 ++++++------------ start-server.sh | 124 ++--------- 9 files changed, 216 insertions(+), 249 deletions(-) create mode 100644 .docker_naming create mode 100644 deploy/migrate-docker-naming.ps1 diff --git a/.docker_naming b/.docker_naming new file mode 100644 index 00000000..5a4f26ae --- /dev/null +++ b/.docker_naming @@ -0,0 +1 @@ +owpengram \ No newline at end of file diff --git a/deploy/docker-compose.yml b/deploy/docker-compose.yml index eb339fee..610ad6d8 100644 --- a/deploy/docker-compose.yml +++ b/deploy/docker-compose.yml @@ -6,16 +6,20 @@ # 清空: docker compose down -v (连数据卷一起删,重置 schema/数据) # # server 端连接串见 internal/config/config.go 的默认值(localhost:5432 / localhost:6399)。 -name: telesrv +# +# 容器/卷命名可通过 TELESRV_DOCKER_PROJECT / TELESRV_DOCKER_PREFIX 覆盖(默认 owpengram): +# start-server.sh 对已存在 telesrv_* 卷、且用户拒绝一次性改名迁移的安装,会把这两个变量 +# 固定设为 telesrv,从而永久保留旧命名,不动用户现有的 telesrv_pgdata / telesrv_redisdata。 +name: ${TELESRV_DOCKER_PROJECT:-owpengram} services: postgres: image: postgres:17-alpine - container_name: telesrv-postgres + container_name: ${TELESRV_DOCKER_PREFIX:-owpengram}-postgres # 全库已去分区(普通表),max_locks_per_transaction 默认 64 已够;512 仅留余量,对内存近乎零开销。 # pg_stat_statements:聚合各 SQL 的累计/平均耗时与调用次数,用于定位 postgres 容器 CPU 热点 # (telesrv 是宿主进程,docker stats 里的 CPU 尖峰是本容器)。需 CREATE EXTENSION 后才有视图: - # docker exec -i telesrv-postgres psql -U telesrv -d telesrv -c "CREATE EXTENSION IF NOT EXISTS pg_stat_statements;" + # docker exec -i owpengram-postgres psql -U telesrv -d telesrv -c "CREATE EXTENSION IF NOT EXISTS pg_stat_statements;" command: - "postgres" - "-c" @@ -44,7 +48,7 @@ services: redis: image: redis:7-alpine - container_name: telesrv-redis + container_name: ${TELESRV_DOCKER_PREFIX:-owpengram}-redis command: ["redis-server", "--appendonly", "yes"] ports: - "6399:6379" # 宿主 6379 常被其他项目占用,telesrv 对外用 6399(容器内仍 6379) @@ -59,4 +63,6 @@ services: volumes: pgdata: + name: ${TELESRV_DOCKER_PREFIX:-owpengram}_pgdata redisdata: + name: ${TELESRV_DOCKER_PREFIX:-owpengram}_redisdata diff --git a/deploy/migrate-docker-naming.ps1 b/deploy/migrate-docker-naming.ps1 new file mode 100644 index 00000000..9594c0dd --- /dev/null +++ b/deploy/migrate-docker-naming.ps1 @@ -0,0 +1,122 @@ +<# +Resolves (and, once, offers to migrate) the Docker project/container/volume +naming used by deploy/docker-compose.yml. + +The project used to be named "telesrv" in Docker (containers telesrv-postgres / +telesrv-redis, volumes telesrv_pgdata / telesrv_redisdata). It's now +"owpengram" by default, so a gramsrv instance running on the same machine +can't be confused with this one at a glance in `docker ps` / Docker Desktop. + +Existing installs may still have telesrv_* volumes with real data in them. +This script asks, at most once, whether to copy that data over to owpengram_* +naming. The answer is cached in a state file next to .secrets/.public_ip: + - accepted -> volumes are copied (old telesrv_* volumes are left in place, + untouched, as a backup), state becomes "owpengram", never asked again. + - declined -> state becomes "telesrv", the install keeps the old naming + forever, never asked again. + - fresh install (no telesrv_* volumes found) -> silently uses "owpengram", + nothing to migrate. + +Prints exactly two lines to stdout: the resolved project name, then the +resolved container/volume prefix. Everything else (prompts, progress) goes to +stderr, so a caller can safely capture just stdout. +#> +[CmdletBinding()] +param( + [string]$ComposeFile = "deploy\docker-compose.yml", + [string]$StateFile = ".docker_naming" +) + +function Write-Info([string]$Message) { + [Console]::Error.WriteLine($Message) +} + +function Write-Result([string]$Project, [string]$Prefix) { + [Console]::Out.WriteLine($Project) + [Console]::Out.WriteLine($Prefix) +} + +function Test-DockerVolume([string]$Name) { + docker volume inspect $Name *> $null + return $LASTEXITCODE -eq 0 +} + +$state = $null +if (Test-Path $StateFile) { + $state = (Get-Content $StateFile -Raw -ErrorAction SilentlyContinue) + if ($state) { $state = $state.Trim() } +} + +if ($state -eq "owpengram") { + Write-Result "owpengram" "owpengram" + exit 0 +} +if ($state -eq "telesrv") { + Write-Result "telesrv" "telesrv" + exit 0 +} + +$oldPg = Test-DockerVolume "telesrv_pgdata" +$oldRedis = Test-DockerVolume "telesrv_redisdata" + +if (-not $oldPg -and -not $oldRedis) { + # Fresh install: nothing to migrate, just adopt the new naming. + Set-Content -Path $StateFile -Value "owpengram" -NoNewline + Write-Result "owpengram" "owpengram" + exit 0 +} + +if ([Console]::IsInputRedirected) { + # Can't prompt right now (piped/non-interactive run). Keep old naming for + # this run only — don't cache a decision nobody actually made. + Write-Info "[cfg] old 'telesrv_*' Docker volumes found but running non-interactively; keeping old naming for now" + Write-Result "telesrv" "telesrv" + exit 0 +} + +Write-Info "" +Write-Info "== Docker container/volume naming ==" +Write-Info "Found existing Docker volumes named 'telesrv_*' (from before the project was" +Write-Info "renamed to OwpenGram). Renaming them to 'owpengram_*' avoids confusing this" +Write-Info "server with a gramsrv instance running on the same machine. Recommended." +$reply = Read-Host "Migrate Docker containers/volumes from 'telesrv' to 'owpengram' naming now? [Y/n]" + +if ($reply -match '^[Nn]') { + Set-Content -Path $StateFile -Value "telesrv" -NoNewline + Write-Info "[cfg] keeping 'telesrv' Docker naming (won't ask again)" + Write-Result "telesrv" "telesrv" + exit 0 +} + +Write-Info "[cfg] migrating Docker volumes: telesrv_* -> owpengram_*" + +$env:TELESRV_DOCKER_PROJECT = "telesrv" +$env:TELESRV_DOCKER_PREFIX = "telesrv" +docker compose -f $ComposeFile -p telesrv stop postgres redis *> $null +Remove-Item Env:\TELESRV_DOCKER_PROJECT, Env:\TELESRV_DOCKER_PREFIX -ErrorAction SilentlyContinue + +if ($oldPg) { + docker volume create owpengram_pgdata *> $null + docker run --rm -v telesrv_pgdata:/from -v owpengram_pgdata:/to alpine sh -c "cp -a /from/. /to/" + if ($LASTEXITCODE -ne 0) { + Write-Info "[ERROR] failed to copy pgdata volume" + exit 1 + } +} +if ($oldRedis) { + docker volume create owpengram_redisdata *> $null + docker run --rm -v telesrv_redisdata:/from -v owpengram_redisdata:/to alpine sh -c "cp -a /from/. /to/" + if ($LASTEXITCODE -ne 0) { + Write-Info "[ERROR] failed to copy redisdata volume" + exit 1 + } +} + +$env:TELESRV_DOCKER_PROJECT = "telesrv" +$env:TELESRV_DOCKER_PREFIX = "telesrv" +docker compose -f $ComposeFile -p telesrv down *> $null +Remove-Item Env:\TELESRV_DOCKER_PROJECT, Env:\TELESRV_DOCKER_PREFIX -ErrorAction SilentlyContinue + +Set-Content -Path $StateFile -Value "owpengram" -NoNewline +Write-Info "[ok] migration complete - old 'telesrv_*' volumes were left in place, untouched, as a backup" +Write-Result "owpengram" "owpengram" diff --git a/scripts/check-local-runtime.ps1 b/scripts/check-local-runtime.ps1 index 933e4353..c9063caf 100644 --- a/scripts/check-local-runtime.ps1 +++ b/scripts/check-local-runtime.ps1 @@ -13,7 +13,7 @@ param( [string]$ServerLogPath, [string]$AndroidPackage = "org.telegram.messenger.beta", [string]$DeviceSerial, - [string]$PostgresContainer = "telesrv-postgres", + [string]$PostgresContainer = "owpengram-postgres", [string]$Database = "telesrv", [string]$DbUser = "telesrv", [int]$RecentLogLines = 1200, diff --git a/scripts/validate-android-big-video-upload.ps1 b/scripts/validate-android-big-video-upload.ps1 index 857620e6..f49deb2d 100644 --- a/scripts/validate-android-big-video-upload.ps1 +++ b/scripts/validate-android-big-video-upload.ps1 @@ -19,7 +19,7 @@ param( [string]$AndroidPackage = "org.telegram.messenger.beta", [string]$DeviceSerial, - [string]$PostgresContainer = "telesrv-postgres", + [string]$PostgresContainer = "owpengram-postgres", [string]$Database = "telesrv", [string]$DbUser = "telesrv", diff --git a/scripts/validate-android-offline-media-recovery.ps1 b/scripts/validate-android-offline-media-recovery.ps1 index b8ed02ef..a605fc9e 100644 --- a/scripts/validate-android-offline-media-recovery.ps1 +++ b/scripts/validate-android-offline-media-recovery.ps1 @@ -31,7 +31,7 @@ param( [string]$AndroidPackage = "org.telegram.messenger.beta", [string]$DeviceSerial, - [string]$PostgresContainer = "telesrv-postgres", + [string]$PostgresContainer = "owpengram-postgres", [string]$Database = "telesrv", [string]$DbUser = "telesrv", diff --git a/scripts/validate-android-video-upload.ps1 b/scripts/validate-android-video-upload.ps1 index b8e67c55..c96f2f77 100644 --- a/scripts/validate-android-video-upload.ps1 +++ b/scripts/validate-android-video-upload.ps1 @@ -22,7 +22,7 @@ param( [string]$AndroidPackage = "org.telegram.messenger.beta", [string]$DeviceSerial, - [string]$PostgresContainer = "telesrv-postgres", + [string]$PostgresContainer = "owpengram-postgres", [string]$Database = "telesrv", [string]$DbUser = "telesrv", diff --git a/start-server.bat b/start-server.bat index 41077bbd..bb90a96e 100644 --- a/start-server.bat +++ b/start-server.bat @@ -2,11 +2,7 @@ setlocal enabledelayedexpansion cd /d "%~dp0" -set "ENV_EXAMPLE=.env.example" set "ENV_FILE=.env" -set "IP_FILE=.public_ip" -set "PREFIX_FILE=.link_prefix" -set "SECRETS_FILE=.secrets" set "COMPOSE_FILE=deploy\docker-compose.yml" set "LOG_DIR=logs" @@ -20,127 +16,31 @@ goto parse_args echo [cfg] script started, NO_BUILD=%NO_BUILD% -rem --- Public address (interactive) ----------------------------------------- -set "DEFAULT_IP=" -if exist "%IP_FILE%" ( - set /p DEFAULT_IP=<"%IP_FILE%" - echo [cfg] loaded saved IP: !DEFAULT_IP! -) - -if not defined DEFAULT_IP ( - echo [cfg] detecting public IP... - for /f "usebackq delims=" %%i in (`powershell -NoProfile -Command "(Invoke-WebRequest -Uri 'https://api.ipify.org' -TimeoutSec 5 -UseBasicParsing).Content" 2^>nul`) do set "DEFAULT_IP=%%i" - if defined DEFAULT_IP echo [cfg] detected IP: !DEFAULT_IP! -) - -if defined DEFAULT_IP ( - set /p "PUBLIC_IP=Public server IP/host [!DEFAULT_IP!]: " -) else ( - set /p "PUBLIC_IP=Public server IP/host: " -) -if not defined PUBLIC_IP set "PUBLIC_IP=!DEFAULT_IP!" -if not defined PUBLIC_IP ( - echo [ERROR] public IP/host is required. +rem This script only starts the server -- it never writes or edits .env. Set +rem up .env yourself (from .env.example) before running it. +if not exist "%ENV_FILE%" ( + echo [ERROR] %ENV_FILE% not found - copy .env.example to %ENV_FILE% and configure it first pause exit /b 1 ) -> "%IP_FILE%" echo !PUBLIC_IP! -echo [cfg] public address = !PUBLIC_IP! -rem --- Link prefix / me_url_prefix (interactive) ---------------------------- -set "DEFAULT_PREFIX=!PUBLIC_IP!" -if exist "%PREFIX_FILE%" set /p DEFAULT_PREFIX=<"%PREFIX_FILE%" -set /p "LINK_PREFIX=Link prefix [!DEFAULT_PREFIX!]: " -if not defined LINK_PREFIX set "LINK_PREFIX=!DEFAULT_PREFIX!" -for /f "usebackq delims=" %%i in (`powershell -NoProfile -Command "$p='!LINK_PREFIX!'; $p=$p -replace '^https?://','' -replace '/+$',''; Write-Output $p"`) do set "LINK_PREFIX=%%i" -if not defined LINK_PREFIX ( - echo [ERROR] link prefix is required. +rem --- Docker container/volume naming (telesrv -> owpengram), one-time, opt-in +rem Resolves whether this install uses the new "owpengram" Docker naming or +rem (if telesrv_* volumes exist and the user declined migrating them) keeps +rem the old "telesrv" naming permanently. See deploy\migrate-docker-naming.ps1. +set "DOCKER_PROJECT=" +set "DOCKER_PREFIX=" +for /f "usebackq delims=" %%i in (`powershell -NoProfile -ExecutionPolicy Bypass -File deploy\migrate-docker-naming.ps1`) do ( + if not defined DOCKER_PROJECT (set "DOCKER_PROJECT=%%i") else if not defined DOCKER_PREFIX (set "DOCKER_PREFIX=%%i") +) +if not defined DOCKER_PROJECT ( + echo [ERROR] docker naming resolution failed pause exit /b 1 ) -> "%PREFIX_FILE%" echo !LINK_PREFIX! -echo [cfg] link prefix = !LINK_PREFIX! - -rem --- Secrets (generated once, cached) ------------------------------------- -set "ADMIN_TOKEN=" -set "ADMIN_PASSWORD=" -set "SESSION_KEY=" -set "SECRETS_CHANGED=" -if exist "%SECRETS_FILE%" ( - echo [cfg] loading secrets from %SECRETS_FILE% - for /f "usebackq tokens=1,* delims==" %%A in (`type "%SECRETS_FILE%"`) do ( - if "%%A"=="ADMIN_TOKEN" set "ADMIN_TOKEN=%%B" - if "%%A"=="ADMIN_PASSWORD" set "ADMIN_PASSWORD=%%B" - if "%%A"=="SESSION_KEY" set "SESSION_KEY=%%B" - ) -) -if not defined ADMIN_TOKEN ( - echo [cfg] generating ADMIN_TOKEN... - for /f "usebackq delims=" %%i in (`powershell -NoProfile -Command "$bytes=New-Object byte[] 32; [System.Security.Cryptography.RandomNumberGenerator]::Fill($bytes); ($bytes | ForEach-Object { $_.ToString('x2') }) -join ''"`) do set "ADMIN_TOKEN=%%i" - set "SECRETS_CHANGED=1" -) -if not defined ADMIN_PASSWORD ( - echo [cfg] generating ADMIN_PASSWORD... - for /f "usebackq delims=" %%i in (`powershell -NoProfile -Command "$chars='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; -join (1..24 | ForEach-Object { $chars[(Get-Random -Maximum $chars.Length)] })"`) do set "ADMIN_PASSWORD=%%i" - set "SECRETS_CHANGED=1" -) -if not defined SESSION_KEY ( - echo [cfg] generating SESSION_KEY... - for /f "usebackq delims=" %%i in (`powershell -NoProfile -Command "$chars='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; -join (1..48 | ForEach-Object { $chars[(Get-Random -Maximum $chars.Length)] })"`) do set "SESSION_KEY=%%i" - set "SECRETS_CHANGED=1" -) -if defined SECRETS_CHANGED ( - > "%SECRETS_FILE%" echo ADMIN_TOKEN=!ADMIN_TOKEN! - >> "%SECRETS_FILE%" echo ADMIN_PASSWORD=!ADMIN_PASSWORD! - >> "%SECRETS_FILE%" echo SESSION_KEY=!SESSION_KEY! - echo [cfg] secrets written to %SECRETS_FILE% -) else ( - echo [cfg] secrets loaded from %SECRETS_FILE% -) - -rem --- Generate .env from .env.example -------------------------------------- -if not exist "%ENV_EXAMPLE%" ( - echo [ERROR] template file %ENV_EXAMPLE% not found - pause - exit /b 1 -) -copy /Y "%ENV_EXAMPLE%" "%ENV_FILE%" >nul -echo [cfg] copied %ENV_EXAMPLE% to %ENV_FILE% - -echo [cfg] patching .env values... -powershell -NoProfile -ExecutionPolicy Bypass -Command ^ - "$f='%ENV_FILE%'; " ^ - "$enc=New-Object System.Text.UTF8Encoding($false); " ^ - "$t=[System.IO.File]::ReadAllText($f,$enc); " ^ - "$map=[ordered]@{ " ^ - " 'TELESRV_ADVERTISE_IP'='!PUBLIC_IP!'; " ^ - " 'TELESRV_TURN_ADVERTISE_IP'='!PUBLIC_IP!'; " ^ - " 'TELESRV_SFU_ADVERTISE_IP'='!PUBLIC_IP!'; " ^ - " 'TELESRV_PUBLIC_BASE_URL'='https://!LINK_PREFIX!'; " ^ - " 'TELESRV_PASSKEY_RP_ID'='!LINK_PREFIX!'; " ^ - " 'TELESRV_PUBLIC_APP_SCHEME'='owpg'; " ^ - " 'TELESRV_PUBLIC_APP_NAME'='OwpenGram'; " ^ - " 'TELESRV_ADMIN_API_TOKEN'='!ADMIN_TOKEN!'; " ^ - " 'TELESRV_ADMIN_UI_PASSWORD'='!ADMIN_PASSWORD!'; " ^ - " 'TELESRV_ADMIN_SESSION_KEY'='!SESSION_KEY!'; " ^ - " 'TELESRV_ADMIN_UI_ADDR'='127.0.0.1:2600'; " ^ - " 'TELESRV_ADMIN_API_ADDR'='127.0.0.1:2399'; " ^ - " 'TELESRV_PUBLIC_LINK_WEB_ADDR'='127.0.0.1:2401' " ^ - "}; " ^ - "foreach ($k in $map.Keys) { " ^ - " $pat='(?m)^' + [regex]::Escape($k) + '=.*$'; " ^ - " $rep=$k + '=' + $map[$k]; " ^ - " if ($t -match $pat) { $t=[regex]::Replace($t,$pat,$rep) } " ^ - " else { $t+=\"`r`n\"+$rep } " ^ - "}; " ^ - "[System.IO.File]::WriteAllText($f,$t,$enc); " ^ - "Write-Output 'ok'" -if %ERRORLEVEL% neq 0 ( - echo [ERROR] failed to patch .env - pause - exit /b 1 -) -echo [cfg] .env written +set "TELESRV_DOCKER_PROJECT=%DOCKER_PROJECT%" +set "TELESRV_DOCKER_PREFIX=%DOCKER_PREFIX%" +echo [cfg] docker naming = %DOCKER_PREFIX% (project %DOCKER_PROJECT%) rem --- Start infrastructure (PostgreSQL + Redis) ---------------------------- echo. @@ -157,7 +57,7 @@ echo. echo == [2/4] Waiting for PostgreSQL == set /a "_pgw=0" :wait_pg -docker exec telesrv-postgres pg_isready -U telesrv -d telesrv >nul 2>&1 +docker exec %DOCKER_PREFIX%-postgres pg_isready -U telesrv -d telesrv >nul 2>&1 if not errorlevel 1 goto pg_ready set /a "_pgw+=1" if !_pgw! gtr 30 ( @@ -175,7 +75,7 @@ rem --- Build ------------------------------------------------------------------ echo. echo == [3/4] Building server binaries == if /i "%NO_BUILD%"=="true" ( - echo [cfg] skipping build (--no-build) + echo [cfg] skipping build, --no-build set if not exist "bin\telesrv.exe" ( if not exist "bin\telesrv-admin.exe" ( echo [ERROR] no binaries found in bin\ - run without --no-build first @@ -210,23 +110,38 @@ if not exist "%LOG_DIR%" mkdir "%LOG_DIR%" set "TELESRV_LOG=%LOG_DIR%\telesrv.log" set "ADMIN_LOG=%LOG_DIR%\telesrv-admin.log" -start "telesrv" /B cmd /c "bin\telesrv.exe >> "%TELESRV_LOG%" 2>&1" -echo [ok] telesrv started, logs -^> %TELESRV_LOG% +rem "start /B cmd /c ..." creates no window, so the earlier WINDOWTITLE-based +rem taskkill in stop_server below never matched anything and silently killed +rem nothing. Launch via Start-Process -PassThru instead and track the real +rem PID. Still routed through cmd.exe /c so ">>log 2>&1" can merge stdout and +rem stderr into one file the way the bash script does (telesrv's own zap +rem logger writes to stderr, so splitting the streams would leave the "main" +rem log file nearly empty); "taskkill /T" below kills the whole cmd+exe tree, +rem not just the cmd.exe wrapper, so this still actually stops the process. +set "TELESRV_PID=" +for /f "usebackq delims=" %%i in (`powershell -NoProfile -Command "(Start-Process -FilePath 'cmd.exe' -ArgumentList '/c bin\telesrv.exe >> \"%TELESRV_LOG%\" 2>&1' -WindowStyle Hidden -PassThru).Id"`) do set "TELESRV_PID=%%i" +if not defined TELESRV_PID ( + echo [ERROR] failed to start telesrv + pause + exit /b 1 +) +echo [ok] telesrv started (PID %TELESRV_PID%), logs -^> %TELESRV_LOG% -start "telesrv-admin" /B cmd /c "bin\telesrv-admin.exe >> "%ADMIN_LOG%" 2>&1" -echo [ok] telesrv-admin started, logs -^> %ADMIN_LOG% +set "ADMIN_PID=" +for /f "usebackq delims=" %%i in (`powershell -NoProfile -Command "(Start-Process -FilePath 'cmd.exe' -ArgumentList '/c bin\telesrv-admin.exe >> \"%ADMIN_LOG%\" 2>&1' -WindowStyle Hidden -PassThru).Id"`) do set "ADMIN_PID=%%i" +if not defined ADMIN_PID ( + echo [ERROR] failed to start telesrv-admin + taskkill /PID %TELESRV_PID% /T /F >nul 2>&1 + pause + exit /b 1 +) +echo [ok] telesrv-admin started (PID %ADMIN_PID%), logs -^> %ADMIN_LOG% echo. echo ============================================ echo OwpenGram server is running echo ============================================ echo. -echo MTProto: !PUBLIC_IP!:2398 -echo Admin UI: http://127.0.0.1:2600 -echo Admin API: http://127.0.0.1:2399 -echo. -echo Admin login password: !ADMIN_PASSWORD! -echo. echo Logs: echo telesrv: type %TELESRV_LOG% echo telesrv-admin: type %ADMIN_LOG% @@ -235,6 +150,23 @@ echo ============================================ rem --- Interactive menu ------------------------------------------------------ :menu +tasklist /FI "PID eq %TELESRV_PID%" 2>nul | find "%TELESRV_PID%" >nul +if errorlevel 1 ( + echo [WARN] telesrv PID %TELESRV_PID% exited unexpectedly + echo Check %TELESRV_LOG% for details + taskkill /PID %ADMIN_PID% /T /F >nul 2>&1 + pause + exit /b 1 +) +tasklist /FI "PID eq %ADMIN_PID%" 2>nul | find "%ADMIN_PID%" >nul +if errorlevel 1 ( + echo [WARN] telesrv-admin PID %ADMIN_PID% exited unexpectedly + echo Check %ADMIN_LOG% for details + taskkill /PID %TELESRV_PID% /T /F >nul 2>&1 + pause + exit /b 1 +) + echo. echo [1] View telesrv logs (last 50 lines) echo [2] View telesrv-admin logs (last 50 lines) @@ -277,7 +209,7 @@ goto menu :stop_server echo. echo [stop] stopping telesrv and telesrv-admin ... -taskkill /FI "WINDOWTITLE eq telesrv*" /F >nul 2>&1 -taskkill /FI "WINDOWTITLE eq telesrv-admin*" /F >nul 2>&1 +if defined TELESRV_PID taskkill /PID %TELESRV_PID% /T /F >nul 2>&1 +if defined ADMIN_PID taskkill /PID %ADMIN_PID% /T /F >nul 2>&1 echo [ok] stopped. exit /b 0 diff --git a/start-server.sh b/start-server.sh index 7d56f452..1172f0fc 100644 --- a/start-server.sh +++ b/start-server.sh @@ -2,11 +2,7 @@ set -euo pipefail cd "$(dirname "$0")" -ENV_EXAMPLE=".env.example" ENV_FILE=".env" -IP_FILE=".public_ip" -PREFIX_FILE=".link_prefix" -SECRETS_FILE=".secrets" COMPOSE_FILE="deploy/docker-compose.yml" LOG_DIR="logs" @@ -28,105 +24,21 @@ log() { echo "[cfg] $*"; } step() { echo; echo "== $* =="; } die() { echo "[ERROR] $*" >&2; exit 1; } -random_hex() { - local bytes="${1:-32}" - openssl rand -hex "$bytes" 2>/dev/null || head -c "$bytes" /dev/urandom | xxd -p | tr -d '\n' | head -c $((bytes * 2)) -} +# This script only starts the server — it never writes or edits .env. Set up +# .env yourself (from .env.example) before running it. +[[ -f "$ENV_FILE" ]] || die "${ENV_FILE} not found — copy .env.example to ${ENV_FILE} and configure it first" -random_string() { - local len="${1:-24}" - openssl rand -base64 "$((len * 2))" 2>/dev/null | tr -dc 'a-zA-Z0-9' | head -c "$len" \ - || head -c 256 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c "$len" -} - -# --- Public address (interactive) ------------------------------------------ -DEFAULT_IP="" -[[ -f "$IP_FILE" ]] && DEFAULT_IP="$(tr -d '[:space:]' < "$IP_FILE")" -if [[ -z "$DEFAULT_IP" ]]; then - DEFAULT_IP="$(curl -fsS --max-time 3 https://api.ipify.org 2>/dev/null || true)" -fi - -if [[ -n "$DEFAULT_IP" ]]; then - read -rp "Public server IP/host [${DEFAULT_IP}]: " PUBLIC_IP -else - read -rp "Public server IP/host: " PUBLIC_IP -fi -PUBLIC_IP="${PUBLIC_IP:-$DEFAULT_IP}" -[[ -z "$PUBLIC_IP" ]] && die "public IP/host is required." -echo "$PUBLIC_IP" > "$IP_FILE" -log "public address = ${PUBLIC_IP}" - -# --- Link prefix / me_url_prefix (interactive) ----------------------------- -DEFAULT_PREFIX="$PUBLIC_IP" -[[ -f "$PREFIX_FILE" ]] && DEFAULT_PREFIX="$(tr -d '[:space:]' < "$PREFIX_FILE")" -read -rp "Link prefix (me_url_prefix, e.g. ${PUBLIC_IP} or chat.example.com) [${DEFAULT_PREFIX}]: " LINK_PREFIX -LINK_PREFIX="${LINK_PREFIX:-$DEFAULT_PREFIX}" -LINK_PREFIX="$(printf '%s' "$LINK_PREFIX" | sed -E 's#^https?://##; s#/+$##')" -[[ -z "$LINK_PREFIX" ]] && die "link prefix is required." -echo "$LINK_PREFIX" > "$PREFIX_FILE" -log "link prefix (me_url_prefix) = ${LINK_PREFIX}" - -# --- Secrets (generated once, cached) -------------------------------------- -load_or_gen_secrets() { - local admin_token="" admin_password="" session_key="" - - if [[ -f "$SECRETS_FILE" ]]; then - # shellcheck disable=SC1090 - source "$SECRETS_FILE" 2>/dev/null || true - fi - - if [[ -z "${ADMIN_TOKEN:-}" ]]; then - ADMIN_TOKEN="$(random_hex 32)" - fi - if [[ -z "${ADMIN_PASSWORD:-}" ]]; then - ADMIN_PASSWORD="$(random_string 24)" - fi - if [[ -z "${SESSION_KEY:-}" ]]; then - SESSION_KEY="$(random_string 48)" - fi - - cat > "$SECRETS_FILE" <> "$ENV_FILE" - fi -} - -set_env "TELESRV_ADVERTISE_IP" "$PUBLIC_IP" -set_env "TELESRV_TURN_ADVERTISE_IP" "$PUBLIC_IP" -set_env "TELESRV_SFU_ADVERTISE_IP" "$PUBLIC_IP" -set_env "TELESRV_PUBLIC_BASE_URL" "https://${LINK_PREFIX}" -set_env "TELESRV_PASSKEY_RP_ID" "$LINK_PREFIX" -set_env "TELESRV_PUBLIC_APP_SCHEME" "owpg" -set_env "TELESRV_PUBLIC_APP_NAME" "OwpenGram" -set_env "TELESRV_ADMIN_API_TOKEN" "$ADMIN_TOKEN" -set_env "TELESRV_ADMIN_UI_PASSWORD" "$ADMIN_PASSWORD" -set_env "TELESRV_ADMIN_SESSION_KEY" "$SESSION_KEY" -set_env "TELESRV_ADMIN_UI_ADDR" "127.0.0.1:2600" -set_env "TELESRV_ADMIN_API_ADDR" "127.0.0.1:2399" -set_env "TELESRV_PUBLIC_LINK_WEB_ADDR" "127.0.0.1:2401" - -log ".env written (${ENV_FILE})" +# --- Docker container/volume naming (telesrv -> owpengram), one-time, opt-in +# Resolves whether this install uses the new "owpengram" Docker naming or (if +# telesrv_* volumes exist and the user declined migrating them) keeps the old +# "telesrv" naming permanently. See deploy/migrate-docker-naming.ps1. +NAMING_OUT="$(powershell -NoProfile -ExecutionPolicy Bypass -File deploy/migrate-docker-naming.ps1)" \ + || die "docker naming resolution failed" +DOCKER_PROJECT="$(sed -n '1p' <<<"$NAMING_OUT")" +DOCKER_PREFIX="$(sed -n '2p' <<<"$NAMING_OUT")" +export TELESRV_DOCKER_PROJECT="$DOCKER_PROJECT" +export TELESRV_DOCKER_PREFIX="$DOCKER_PREFIX" +log "docker naming = ${DOCKER_PREFIX} (project ${DOCKER_PROJECT})" # --- Start infrastructure (PostgreSQL + Redis) ----------------------------- step "[1/4] Starting infrastructure (PostgreSQL + Redis)" @@ -135,7 +47,7 @@ docker compose -f "$COMPOSE_FILE" up -d # --- Wait for PostgreSQL --------------------------------------------------- step "[2/4] Waiting for PostgreSQL" for i in $(seq 1 30); do - if docker exec telesrv-postgres pg_isready -U telesrv -d telesrv >/dev/null 2>&1; then + if docker exec "${DOCKER_PREFIX}-postgres" pg_isready -U telesrv -d telesrv >/dev/null 2>&1; then echo "[ok] PostgreSQL is ready" break fi @@ -198,12 +110,6 @@ echo "============================================" echo " OwpenGram server is running" echo "============================================" echo "" -echo " MTProto: ${PUBLIC_IP}:2398" -echo " Admin UI: http://127.0.0.1:2600" -echo " Admin API: http://127.0.0.1:2399" -echo "" -echo " Admin login password: ${ADMIN_PASSWORD}" -echo "" echo " Logs:" echo " telesrv: tail -f ${TELESRV_LOG}" echo " telesrv-admin: tail -f ${ADMIN_LOG}"