vignette/scripts/start-tailscale-runtime.ps1
2026-06-27 11:20:24 +09:00

137 lines
3.6 KiB
PowerShell

<#
.SYNOPSIS
Tailnet 전용 Vignette 접속점을 켠다.
.DESCRIPTION
- 현재 Tailscale 노드의 MagicDNS URL을 읽는다.
- dev 스택(API 8000 + web 5173 + gateway 9099)을 기동하면서 Tailnet URL에서 dev-login을 허용한다.
- tailscale serve 루트 HTTPS를 로컬 web 포트로 연결한다.
공개 인터넷 노출이 아니라 같은 Tailnet에 로그인한 PC/모바일 전용이다.
#>
param(
[string]$Workspace = "D:\workspace\vignette",
[int]$ApiPort = 8010,
[int]$WebPort = 5173,
[switch]$SkipStackRestart,
[switch]$SkipServeUpdate
)
$ErrorActionPreference = "Stop"
function Get-TailnetOrigin {
$raw = & tailscale status --json
if ($LASTEXITCODE -ne 0) {
throw "tailscale status failed"
}
$status = $raw | ConvertFrom-Json
$dnsName = [string]$status.Self.DNSName
if (!$dnsName) {
throw "Tailscale MagicDNS name was not reported. Enable MagicDNS or check tailscale status."
}
"https://$($dnsName.TrimEnd('.'))"
}
function Wait-HttpOk {
param(
[string]$Uri,
[int]$TimeoutSec = 45
)
$deadline = (Get-Date).AddSeconds($TimeoutSec)
do {
try {
$response = Invoke-WebRequest -UseBasicParsing -Uri $Uri -TimeoutSec 8
if ($response.StatusCode -ge 200 -and $response.StatusCode -lt 500) {
return $response
}
} catch {
Start-Sleep -Seconds 1
}
} while ((Get-Date) -lt $deadline)
throw "Timed out waiting for $Uri"
}
function Set-EnvFileValue {
param(
[string]$EnvPath,
[string]$Key,
[string]$Value
)
$line = "$Key=$Value"
if (Test-Path -LiteralPath $EnvPath) {
$lines = Get-Content -LiteralPath $EnvPath -Encoding UTF8
} else {
$lines = @()
}
$updated = $false
$next = foreach ($existing in $lines) {
if ($existing -match "^$([regex]::Escape($Key))=") {
$updated = $true
$line
} else {
$existing
}
}
if (!$updated) {
$next += $line
}
Set-Content -LiteralPath $EnvPath -Encoding UTF8 -Value $next
}
if (!(Get-Command tailscale -ErrorAction SilentlyContinue)) {
throw "tailscale CLI not found"
}
if (!(Test-Path -LiteralPath $Workspace)) {
throw "Workspace not found: $Workspace"
}
$tailnetOrigin = Get-TailnetOrigin
$tailnetHost = ([uri]$tailnetOrigin).Host
$env:AUTH_DEV_LOGIN_EXTRA_ORIGINS = ConvertTo-Json -InputObject @($tailnetOrigin) -Compress
$env:VITE_ALLOWED_HOSTS = $tailnetHost
$env:VITE_API_PROXY_TARGET = "http://127.0.0.1:$ApiPort"
Set-EnvFileValue `
-EnvPath (Join-Path $Workspace "apps\api\.env") `
-Key "AUTH_DEV_LOGIN_EXTRA_ORIGINS" `
-Value $env:AUTH_DEV_LOGIN_EXTRA_ORIGINS
Write-Output "Tailnet origin: $tailnetOrigin"
Write-Output "AUTH_DEV_LOGIN_EXTRA_ORIGINS=$env:AUTH_DEV_LOGIN_EXTRA_ORIGINS"
Write-Output "VITE_ALLOWED_HOSTS=$env:VITE_ALLOWED_HOSTS"
Write-Output "VITE_API_PROXY_TARGET=$env:VITE_API_PROXY_TARGET"
if (!$SkipStackRestart) {
$devUp = Join-Path $Workspace "scripts\dev-up.ps1"
if (!(Test-Path -LiteralPath $devUp)) {
throw "dev-up script not found: $devUp"
}
& $devUp -ApiPort $ApiPort
}
if (!$SkipServeUpdate) {
$target = "http://127.0.0.1:$WebPort"
Write-Output "Updating tailscale serve root -> $target"
& tailscale serve --bg --yes $target
if ($LASTEXITCODE -ne 0) {
throw "tailscale serve update failed"
}
}
Wait-HttpOk -Uri $tailnetOrigin | Out-Null
$authConfig = Invoke-RestMethod -Uri "$tailnetOrigin/api/auth/config" -TimeoutSec 15
if ($authConfig.dev_login_enabled -ne $true) {
throw "Tailnet auth config is reachable, but dev_login_enabled is not true"
}
Write-Output "Tailscale Vignette URL: $tailnetOrigin"
Write-Output "Login path: $tailnetOrigin/login"
Write-Output "Serve status:"
& tailscale serve status