Files
Josh Rogers 4adfc9d0bf Fix dev-db.ps1 status to exit cleanly when container is absent
docker inspect exits non-zero when the container is missing; under
$ErrorActionPreference='Stop' that propagated and made `dev-db.ps1
status` exit 1 even though the script printed the right output. Swallow
the inner exit code locally so callers see exit 0.
2026-05-08 23:13:57 -05:00

118 lines
3.7 KiB
PowerShell

#!/usr/bin/env pwsh
<#
.SYNOPSIS
Manage the local Postgres container used by the YesChef backend in dev.
.DESCRIPTION
Spins up a postgres:17 container named "yeschef-pg" on localhost:5432 with
the database/user/password the API's appsettings.json expects. Persists
data in a Docker volume so restarts retain state until reset is run.
.PARAMETER Command
start - Create + start the container (no-op if already running).
stop - Stop the container, leaving the volume intact.
reset - Stop and remove the container AND its data volume. Next start is
a fresh DB; the API will run all migrations from scratch.
status - Print the container state and connection string.
logs - Tail the container logs.
.EXAMPLE
./scripts/dev-db.ps1 start
./scripts/dev-db.ps1 reset
#>
param(
[Parameter(Position = 0)]
[ValidateSet('start', 'stop', 'reset', 'status', 'logs')]
[string]$Command = 'status'
)
$ErrorActionPreference = 'Stop'
$Name = 'yeschef-pg'
$Volume = 'yeschef-pgdata-dev'
$Image = 'postgres:17'
$ConnectionString = 'Host=localhost;Database=yeschef;Username=yeschef;Password=yeschef'
function Get-ContainerState {
# docker inspect exits non-zero when the container is missing; swallow
# that so $ErrorActionPreference='Stop' doesn't abort the script and
# so the caller's exit code stays clean.
$state = & docker inspect --format '{{.State.Status}}' $Name 2>$null
$code = $LASTEXITCODE
$global:LASTEXITCODE = 0
if ($code -ne 0) { return 'absent' }
return $state
}
function Start-DevDb {
$state = Get-ContainerState
if ($state -eq 'running') {
Write-Host "Container '$Name' already running." -ForegroundColor Green
return
}
if ($state -ne 'absent') {
Write-Host "Starting existing container '$Name'..."
docker start $Name | Out-Null
} else {
Write-Host "Creating new container '$Name'..."
docker run -d `
--name $Name `
-p 5432:5432 `
-e POSTGRES_DB=yeschef `
-e POSTGRES_USER=yeschef `
-e POSTGRES_PASSWORD=yeschef `
-v "${Volume}:/var/lib/postgresql/data" `
$Image | Out-Null
}
# Wait until pg_isready returns healthy so the caller can immediately
# start the API without racing on the listener.
Write-Host "Waiting for Postgres to accept connections..."
for ($i = 0; $i -lt 30; $i++) {
docker exec $Name pg_isready -U yeschef -d yeschef -q 2>$null
if ($LASTEXITCODE -eq 0) {
Write-Host "Ready. Connection string:" -ForegroundColor Green
Write-Host " $ConnectionString"
return
}
Start-Sleep -Seconds 1
}
Write-Warning "Postgres did not become ready within 30s. Check 'docker logs $Name'."
}
function Stop-DevDb {
$state = Get-ContainerState
if ($state -eq 'absent') {
Write-Host "Container '$Name' is not present."
return
}
docker stop $Name | Out-Null
Write-Host "Stopped '$Name'." -ForegroundColor Yellow
}
function Reset-DevDb {
$state = Get-ContainerState
if ($state -ne 'absent') {
docker rm -f $Name | Out-Null
Write-Host "Removed container '$Name'."
}
docker volume rm $Volume 2>$null | Out-Null
Write-Host "Removed volume '$Volume'. Next 'start' will create a fresh database." -ForegroundColor Yellow
}
function Show-Status {
$state = Get-ContainerState
Write-Host "Container: $Name"
Write-Host " State : $state"
Write-Host " Volume: $Volume"
Write-Host " Conn : $ConnectionString"
}
switch ($Command) {
'start' { Start-DevDb }
'stop' { Stop-DevDb }
'reset' { Reset-DevDb }
'status' { Show-Status }
'logs' { docker logs -f $Name }
}