Ctrl K
ComunidadGuías…

deploy.ps1

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# deploy.ps1 — Deploys this repo to a remote Docker host over SSH.
#
# Reads HOST and SUDO_PASS from .env.deploy (gitignored). Example .env.deploy:
#   HOST=user@1.2.3.4
#   REMOTE_DIR=/home/user/chess
#   SUDO_PASS=...
#   HOST_PORT=8800

param([switch]$NoBuild, [switch]$Logs)

$ErrorActionPreference = 'Stop'

$envFile = Join-Path $PSScriptRoot '.env.deploy'
if (-not (Test-Path $envFile)) {
    throw ".env.deploy not found. Create it with HOST=user@host, REMOTE_DIR=/path, SUDO_PASS=... (optional)"
}

$envVars = @{}
Get-Content $envFile | ForEach-Object {
    if ($_ -match '^\s*([A-Z_][A-Z0-9_]*)\s*=\s*(.*?)\s*$') {
        $envVars[$matches[1]] = $matches[2]
    }
}

$HOST_TARGET = $envVars['HOST']
$REMOTE_DIR  = $envVars['REMOTE_DIR']
$SUDO_PASS   = $envVars['SUDO_PASS']
$HOST_PORT   = if ($envVars['HOST_PORT']) { $envVars['HOST_PORT'] } else { '8800' }

if (-not $HOST_TARGET -or -not $REMOTE_DIR) {
    throw "HOST and REMOTE_DIR must be set in .env.deploy"
}

function Invoke-Remote([string]$cmd) {
    & ssh $HOST_TARGET $cmd
    if ($LASTEXITCODE -ne 0) { throw "Remote command failed: $cmd" }
}

# Run a multi-line bash script on the remote with sudo. Avoids PowerShell quoting
# pitfalls by scp'ing the script first, then executing it.
function Invoke-RemoteSudoScript([string]$script) {
    $localScript = Join-Path $env:TEMP "chess-remote-$(Get-Random).sh"
    $remoteScript = "/tmp/chess-remote-$(Get-Random).sh"
    # Write with LF line endings, no BOM
    [System.IO.File]::WriteAllText($localScript, "#!/usr/bin/env bash`nset -e`n" + $script.Replace("`r`n", "`n"), (New-Object System.Text.UTF8Encoding $false))
    & scp -q $localScript "${HOST_TARGET}:$remoteScript"
    if ($LASTEXITCODE -ne 0) { Remove-Item -Force $localScript; throw "scp script failed" }
    if ($SUDO_PASS) {
        & ssh $HOST_TARGET "chmod +x $remoteScript && echo '$SUDO_PASS' | sudo -S -p '' bash $remoteScript; rc=`$?; rm -f $remoteScript; exit `$rc"
    } else {
        & ssh $HOST_TARGET "chmod +x $remoteScript && sudo bash $remoteScript; rc=`$?; rm -f $remoteScript; exit `$rc"
    }
    $rc = $LASTEXITCODE
    Remove-Item -Force $localScript
    if ($rc -ne 0) { throw "Remote script failed (exit $rc)" }
}

Write-Host "→ Ensuring remote dir $REMOTE_DIR exists" -ForegroundColor Cyan
Invoke-Remote "mkdir -p $REMOTE_DIR"

Write-Host "→ Syncing source to $HOST_TARGET`:$REMOTE_DIR" -ForegroundColor Cyan
# Tar to a local temp file, scp it, extract on remote. PowerShell pipelines mangle
# binary streams, so we cannot pipe tar | ssh directly.
$localTar = Join-Path $env:TEMP "chess-deploy-$(Get-Random).tar.gz"
$remoteTar = "/tmp/chess-deploy-$(Get-Random).tar.gz"
# Prefer Windows native bsdtar — it understands drive letters cleanly. GNU tar (Git Bash)
# treats "R:" as a remote host. Fall back to whatever's on PATH.
$tarExe = Join-Path $env:WINDIR 'System32\tar.exe'
if (-not (Test-Path $tarExe)) { $tarExe = 'tar' }
$tarArgs = @(
    '--exclude=node_modules', '--exclude=.git', '--exclude=dist',
    '--exclude=build',        '--exclude=data', '--exclude=bin',
    '--exclude=.env',         '--exclude=.env.deploy',
    '-czf', $localTar, '-C', $PSScriptRoot, '.'
)
& $tarExe @tarArgs
if ($LASTEXITCODE -ne 0) { throw "tar failed" }
& scp -q $localTar "${HOST_TARGET}:$remoteTar"
if ($LASTEXITCODE -ne 0) { Remove-Item -Force $localTar; throw "scp failed" }
Invoke-Remote "tar -xzf $remoteTar -C $REMOTE_DIR && rm -f $remoteTar"
Remove-Item -Force $localTar

if (-not $NoBuild) {
    Write-Host "→ Building image on remote (this can take a few minutes)" -ForegroundColor Cyan
    Invoke-RemoteSudoScript @"
cd $REMOTE_DIR
HOST_PORT=$HOST_PORT docker compose build
"@
}

Write-Host "→ Starting container" -ForegroundColor Cyan
Invoke-RemoteSudoScript @"
cd $REMOTE_DIR
HOST_PORT=$HOST_PORT docker compose up -d
sleep 2
docker compose ps
"@

if ($Logs) {
    Invoke-RemoteSudoScript @"
cd $REMOTE_DIR
docker compose logs --tail=50
"@
}

$serverIp = ($HOST_TARGET -split '@')[-1]
Write-Host ""
Write-Host "Deployed. Open http://${serverIp}:$HOST_PORT" -ForegroundColor Green