# Manual ops helper for the management plane + Caddyfile + Vault. # # Post-split topology: every application stack lives under stacks// and # is deployed by Portainer's git poll — there is no monolithic root compose any # more, so this script no longer pushes one. The runner workflow (deploy.yml) # handles Caddyfile reload on push automatically; -Caddy here is for ad-hoc # pushes when you don't want to wait for the runner. # # Usage (flags combine; no flags = .env + Caddyfile): # powershell -File apply-compose.ps1 # .env + Caddyfile # powershell -File apply-compose.ps1 -EnvFile # .env only (mgmt plane / vault unseal) # powershell -File apply-compose.ps1 -Caddy # Caddyfile only + hot-reload Caddy # powershell -File apply-compose.ps1 -Portainer # portainer-compose.yml + vault.hcl + up -d # powershell -File apply-compose.ps1 -VaultUnseal # unseal vault after restart (keys from .env) param( [switch]$Caddy, [switch]$EnvFile, [switch]$Portainer, [switch]$VaultUnseal ) $ErrorActionPreference = "Stop" # Make a non-zero exit from scp/ssh abort the script instead of silently continuing. $PSNativeCommandUseErrorActionPreference = $true $server = "ginnoir@valhalla" $caddyLocal = Join-Path $PSScriptRoot "Caddyfile" $envLocal = Join-Path $PSScriptRoot ".env" $portainerLocal = Join-Path $PSScriptRoot "portainer-compose.yml" $vaultConfigLocal = Join-Path $PSScriptRoot "vault.hcl" # Default (no flags): push .env + Caddyfile. if (-not $Caddy -and -not $EnvFile -and -not $Portainer -and -not $VaultUnseal) { $EnvFile = $true; $Caddy = $true } if ($EnvFile) { Write-Host "Pushing .env ..." scp $envLocal "${server}:~/valhalla-lab/.env" } if ($Caddy) { Write-Host "Pushing Caddyfile ..." scp $caddyLocal "${server}:/config/caddy/Caddyfile" Write-Host "Reloading Caddy ..." ssh $server "docker exec caddy caddy reload --config /etc/caddy/Caddyfile" } if ($Portainer) { Write-Host "Pushing portainer-compose.yml ..." scp $portainerLocal "${server}:~/valhalla-lab/portainer-compose.yml" Write-Host "Pushing vault.hcl (Vault lives in the management plane) ..." ssh $server "mkdir -p /config/vault/config /config/vault/data /config/vault/logs" scp $vaultConfigLocal "${server}:/config/vault/config/vault.hcl" Write-Host "Applying management plane (portainer, vault, gitea, registry, watchtower) ..." ssh $server "docker compose -f ~/valhalla-lab/portainer-compose.yml --env-file ~/valhalla-lab/.env up -d" } if ($VaultUnseal) { # Load the three unseal keys from .env $envContent = Get-Content $envLocal | Where-Object { $_ -match "^VAULT_UNSEAL_KEY_[123]=" } $keys = $envContent | ForEach-Object { ($_ -split "=", 2)[1] } if ($keys.Count -lt 3) { Write-Error "Could not find VAULT_UNSEAL_KEY_1/2/3 in .env" exit 1 } Write-Host "Unsealing Vault (3 of 5 keys) ..." foreach ($key in $keys) { ssh $server "docker exec vault vault operator unseal $key 2>&1 | grep -E 'Sealed|Error'" } } Write-Host "Done."