Migratie naar 2-container opzet (app + database)
De Express-app serveert nu zelf de gebouwde Vite-frontend op / met een SPA-fallback naar index.html; de aparte nginx-container is vervallen. Bedoeld voor self-hosting op een Raspberry Pi: één image, één origin, geen interne proxy en geen CORS tussen frontend en API. Docker - Nieuwe multi-stage Dockerfile in de root met targets test, development en production; frontend/Dockerfile, frontend/nginx-spa.conf en backend/Dockerfile verwijderd - docker-compose.yml: alleen app + postgres, app publiceert APP_PORT (standaard 3400) naar containerpoort 3001 - docker-compose.dev.yml: dev-container draait API (node --watch) en de Vite dev-server samen via docker/dev-entrypoint.sh, hot reload intact - .dockerignore, .env.example, .gitignore en .gitattributes toegevoegd Backend - express.static + SPA-fallback op STATIC_DIR (default /app/public), met immutable caching voor gehashte assets en no-store voor index.html - Rate limiting alleen nog op /api — statische bestanden liepen anders na 200 requests tegen de limiet aan - Helmet CSP toegespitst op wat de frontend laadt (Google Fonts, inline styles, base64-avatars); upgrade-insecure-requests uit voor intern http - Schema-init verplaatst naar initDb(), niet meer bij import van db.js Tests en CI/CD - backend/test/app.test.js: 11 tests (node --test) voor API-routes, SPA-fallback, cache- en security-headers, zonder database - test.ps1 / test.sh: backend-tests, productiebuild en smoketest op de echte app + postgres stack - azure-pipelines.yml: Test -> Build (incl. smoketest) -> Publish (multi-arch amd64 + arm64, alleen op main/master of een tag) Scripts en documentatie - dev.ps1/dev.sh met targets app en postgres, acties logs en test; dev.ps1 up wist de dev-database niet langer (alleen dev.ps1 down) - release.ps1/release.sh bouwen één image voor amd64 + arm64 en draaien de testsuite vóór het publiceren - README.md en BEHEER.md bijgewerkt voor de nieuwe structuur Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
3c67381de9
commit
bfec3a25f3
+72
-78
@@ -1,24 +1,27 @@
|
||||
# ── VibeFinance release script (PowerShell) ──────────────────────────────
|
||||
# Productie release: bouwt multi-platform, pusht naar registry,
|
||||
# maakt een Git-tag aan en pusht naar origin.
|
||||
# Productie release voor de 2-container opzet: draait de tests, bouwt het
|
||||
# gecombineerde app-image multi-platform, pusht naar de registry, maakt een
|
||||
# Git-tag en publiceert de release in Gitea.
|
||||
#
|
||||
# Gebruik:
|
||||
# .\release.ps1 # bouw + push images + Git-tag
|
||||
# .\release.ps1 -NoBuild # sla docker build over, alleen Git-tag
|
||||
# .\release.ps1 # test + bouw + push + Git-tag + Gitea-release
|
||||
# .\release.ps1 -NoBuild # sla docker build over, alleen tag + release
|
||||
# .\release.ps1 -SkipTests # sla de testsuite over (niet aanbevolen)
|
||||
# .\release.ps1 -DryRun # toon alle commando's zonder iets uit te voeren
|
||||
# .\release.ps1 -Force # sla conflictcontrole over, overschrijf bestaande tags
|
||||
# .\release.ps1 -Force # sla conflictcontrole over, overschrijf tags
|
||||
#
|
||||
# Vereisten:
|
||||
# - Docker Desktop actief
|
||||
# - Ingelogd op de registry: docker login <registry>
|
||||
# - docker buildx builder actief: docker buildx create --use
|
||||
# - Git geïnstalleerd en working directory is de repo root
|
||||
# - Git geinstalleerd en working directory is de repo root
|
||||
# - root package.json bevat een schoon versienummer ZONDER -dev suffix
|
||||
# - $env:GITEA_TOKEN gezet (token met release-rechten) — nodig voor stap 4,
|
||||
# - GITEA_TOKEN in de omgeving (token met release-rechten) voor stap 5,
|
||||
# de Gitea-release waar de update-melding in de app op afgaat
|
||||
|
||||
param(
|
||||
[switch]$NoBuild,
|
||||
[switch]$SkipTests,
|
||||
[switch]$DryRun,
|
||||
[switch]$Force
|
||||
)
|
||||
@@ -28,11 +31,11 @@ $ErrorActionPreference = "Stop"
|
||||
# ════════════════════════════════════════════════════════════════════════════
|
||||
# ── PROJECTCONFIGURATIE — pas alleen dit blok aan voor een nieuw project ──
|
||||
# ════════════════════════════════════════════════════════════════════════════
|
||||
$appName = "VibeFinance"
|
||||
$registry = "vibehoogie.duckdns.org/vibe"
|
||||
$backendImage = "vibefinance-backend"
|
||||
$frontendImage = "vibefinance-frontend"
|
||||
$apiUrl = "/api"
|
||||
$appName = "VibeFinance"
|
||||
$registry = "vibehoogie.duckdns.org/vibe"
|
||||
$appImage = "vibefinance-app"
|
||||
$apiUrl = "/api"
|
||||
$platforms = "linux/amd64,linux/arm64" # arm64 = Raspberry Pi
|
||||
# ════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
# ── Versie uit root package.json ───────────────────────────────────────────
|
||||
@@ -60,14 +63,10 @@ if ($frontendPkg.version -ne $appVersion) {
|
||||
|
||||
$gitTag = "$appVersion"
|
||||
|
||||
# ── Registry tags ──────────────────────────────────────────────────────────
|
||||
$backendBase = "$registry/$backendImage"
|
||||
$frontendBase = "$registry/$frontendImage"
|
||||
|
||||
$backendVersionTag = "$backendBase`:$appVersion"
|
||||
$frontendVersionTag = "$frontendBase`:$appVersion"
|
||||
$backendLatestTag = "$backendBase`:latest"
|
||||
$frontendLatestTag = "$frontendBase`:latest"
|
||||
# ── Registry tags (één image voor frontend + backend) ─────────────────────
|
||||
$appBase = "$registry/$appImage"
|
||||
$appVersionTag = "$appBase`:$appVersion"
|
||||
$appLatestTag = "$appBase`:latest"
|
||||
|
||||
# ── Helpers ────────────────────────────────────────────────────────────────
|
||||
function Invoke-Cmd {
|
||||
@@ -116,14 +115,16 @@ Write-Host "══════════════════════
|
||||
Write-Host " $appName Release" -ForegroundColor Cyan
|
||||
Write-Host " Versie : $appVersion" -ForegroundColor Green
|
||||
Write-Host " Git-tag : $gitTag" -ForegroundColor Green
|
||||
Write-Host " Registry: $registry" -ForegroundColor Green
|
||||
if ($DryRun) { Write-Host " Mode : DRY-RUN (geen wijzigingen)" -ForegroundColor Yellow }
|
||||
if ($NoBuild) { Write-Host " Mode : SKIP BUILD" -ForegroundColor Yellow }
|
||||
if ($Force) { Write-Host " Mode : FORCE (conflictcontrole overgeslagen)" -ForegroundColor Red }
|
||||
Write-Host " Image : $appVersionTag" -ForegroundColor Green
|
||||
Write-Host " Platform: $platforms" -ForegroundColor Green
|
||||
if ($DryRun) { Write-Host " Mode : DRY-RUN (geen wijzigingen)" -ForegroundColor Yellow }
|
||||
if ($NoBuild) { Write-Host " Mode : SKIP BUILD" -ForegroundColor Yellow }
|
||||
if ($SkipTests) { Write-Host " Mode : SKIP TESTS" -ForegroundColor Yellow }
|
||||
if ($Force) { Write-Host " Mode : FORCE (conflictcontrole overgeslagen)" -ForegroundColor Red }
|
||||
Write-Host "════════════════════════════════════════" -ForegroundColor Cyan
|
||||
|
||||
# ── Stap 1: Conflictcontrole ──────────────────────────────────────────────
|
||||
Write-Step "[1/4] Conflictcontrole"
|
||||
Write-Step "[1/5] Conflictcontrole"
|
||||
|
||||
if (-not $DryRun -and -not $Force) {
|
||||
$localTag = git tag --list $gitTag
|
||||
@@ -138,23 +139,13 @@ if (-not $DryRun -and -not $Force) {
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "Controleer registry: $backendVersionTag" -ForegroundColor DarkGray
|
||||
Write-Host "Controleer registry: $appVersionTag" -ForegroundColor DarkGray
|
||||
$ErrorActionPreference = "SilentlyContinue"
|
||||
docker manifest inspect $backendVersionTag 2>$null
|
||||
$backendExists = $LASTEXITCODE -eq 0
|
||||
docker manifest inspect $appVersionTag 2>$null | Out-Null
|
||||
$imageExists = $LASTEXITCODE -eq 0
|
||||
$ErrorActionPreference = "Stop"
|
||||
if ($backendExists) {
|
||||
Write-Error "Registry-tag '$backendVersionTag' bestaat al. Verhoog het versienummer in package.json of gebruik -Force."
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "Controleer registry: $frontendVersionTag" -ForegroundColor DarkGray
|
||||
$ErrorActionPreference = "SilentlyContinue"
|
||||
docker manifest inspect $frontendVersionTag 2>$null
|
||||
$frontendExists = $LASTEXITCODE -eq 0
|
||||
$ErrorActionPreference = "Stop"
|
||||
if ($frontendExists) {
|
||||
Write-Error "Registry-tag '$frontendVersionTag' bestaat al. Verhoog het versienummer in package.json of gebruik -Force."
|
||||
if ($imageExists) {
|
||||
Write-Error "Registry-tag '$appVersionTag' bestaat al. Verhoog het versienummer in package.json of gebruik -Force."
|
||||
exit 1
|
||||
}
|
||||
|
||||
@@ -165,38 +156,44 @@ if (-not $DryRun -and -not $Force) {
|
||||
Write-Host "[DRY-RUN] Conflictcontrole overgeslagen" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
# ── Stap 2: Bouwen en pushen ──────────────────────────────────────────────
|
||||
if (-not $NoBuild) {
|
||||
Write-Step "[2/4] Multi-platform bouwen en pushen"
|
||||
|
||||
Write-Host "Backend bouwen en pushen..." -ForegroundColor White
|
||||
Invoke-Cmd @(
|
||||
"docker", "buildx", "build",
|
||||
"--platform", "linux/amd64,linux/arm64",
|
||||
"--push",
|
||||
"-t", $backendVersionTag,
|
||||
"-t", $backendLatestTag,
|
||||
"--build-arg", "APP_VERSION=$appVersion",
|
||||
(Join-Path $PSScriptRoot "backend")
|
||||
)
|
||||
|
||||
Write-Host "Frontend bouwen en pushen..." -ForegroundColor White
|
||||
Invoke-Cmd @(
|
||||
"docker", "buildx", "build",
|
||||
"--platform", "linux/amd64,linux/arm64",
|
||||
"--push",
|
||||
"-t", $frontendVersionTag,
|
||||
"-t", $frontendLatestTag,
|
||||
"--build-arg", "APP_VERSION=$appVersion",
|
||||
"--build-arg", "VITE_API_URL=$apiUrl",
|
||||
(Join-Path $PSScriptRoot "frontend")
|
||||
)
|
||||
# ── Stap 2: Tests ─────────────────────────────────────────────────────────
|
||||
if (-not $SkipTests) {
|
||||
Write-Step "[2/5] Testsuite"
|
||||
if ($DryRun) {
|
||||
Write-Host "[DRY-RUN] test.ps1 -NoSmoke" -ForegroundColor Yellow
|
||||
} else {
|
||||
& (Join-Path $PSScriptRoot "test.ps1") -NoSmoke
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Error "Tests mislukt — release afgebroken."
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Write-Step "[2/4] Bouwen overgeslagen (-NoBuild)"
|
||||
Write-Step "[2/5] Tests overgeslagen (-SkipTests)"
|
||||
}
|
||||
|
||||
# ── Stap 3: Git-tag aanmaken en pushen ────────────────────────────────────
|
||||
Write-Step "[3/4] Git-tag aanmaken en pushen"
|
||||
# ── Stap 3: Bouwen en pushen ──────────────────────────────────────────────
|
||||
if (-not $NoBuild) {
|
||||
Write-Step "[3/5] Multi-platform bouwen en pushen"
|
||||
|
||||
Invoke-Cmd @(
|
||||
"docker", "buildx", "build",
|
||||
"--platform", $platforms,
|
||||
"--target", "production",
|
||||
"--push",
|
||||
"-t", $appVersionTag,
|
||||
"-t", $appLatestTag,
|
||||
"--build-arg", "APP_VERSION=$appVersion",
|
||||
"--build-arg", "VITE_API_URL=$apiUrl",
|
||||
"--build-arg", "VITE_APP_VERSION=$appVersion",
|
||||
$PSScriptRoot
|
||||
)
|
||||
} else {
|
||||
Write-Step "[3/5] Bouwen overgeslagen (-NoBuild)"
|
||||
}
|
||||
|
||||
# ── Stap 4: Git-tag aanmaken en pushen ────────────────────────────────────
|
||||
Write-Step "[4/5] Git-tag aanmaken en pushen"
|
||||
|
||||
if ($Force) {
|
||||
Write-Host "Bestaande lokale tag verwijderen (indien aanwezig)..." -ForegroundColor Yellow
|
||||
@@ -215,8 +212,8 @@ Invoke-Cmd @("git", "tag", "-a", $gitTag, "-m", "Release $gitTag")
|
||||
Write-Host "Git-tag pushen naar origin" -ForegroundColor White
|
||||
Invoke-Cmd @("git", "push", "origin", "refs/tags/$gitTag")
|
||||
|
||||
# ── Stap 4: Gitea-release aanmaken ────────────────────────────────────────
|
||||
Write-Step "[4/4] Gitea-release aanmaken"
|
||||
# ── Stap 5: Gitea-release aanmaken ────────────────────────────────────────
|
||||
Write-Step "[5/5] Gitea-release aanmaken"
|
||||
|
||||
# De update-melding in de app leest /releases/latest. Een kale Git-tag komt
|
||||
# daar niet in terug, dus er moet een echte release van gemaakt worden.
|
||||
@@ -232,7 +229,6 @@ if (-not $releaseApi) {
|
||||
} elseif (-not $giteaToken) {
|
||||
Write-Host "Geen GITEA_TOKEN in de omgeving — release overgeslagen." -ForegroundColor Yellow
|
||||
Write-Host " Zonder release ziet de app geen update-melding voor $appVersion." -ForegroundColor DarkGray
|
||||
Write-Host ' Token met release-rechten zetten: $env:GITEA_TOKEN = "<token>"' -ForegroundColor DarkGray
|
||||
} else {
|
||||
$notes = Get-ChangelogSection $appVersion
|
||||
if (-not $notes) { $notes = "Release $appVersion" }
|
||||
@@ -260,7 +256,7 @@ if (-not $releaseApi) {
|
||||
Write-Host "Release voor $gitTag bestaat al — overgeslagen." -ForegroundColor Yellow
|
||||
} else {
|
||||
Write-Host "Release aanmaken mislukt ($code): $($_.Exception.Message)" -ForegroundColor Red
|
||||
Write-Host "Tag en images staan al klaar; maak de release eventueel handmatig aan." -ForegroundColor DarkGray
|
||||
Write-Host "Tag en image staan al klaar; maak de release eventueel handmatig aan." -ForegroundColor DarkGray
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -271,11 +267,9 @@ Write-Host ""
|
||||
Write-Host "════════════════════════════════════════" -ForegroundColor Cyan
|
||||
Write-Host " Gepubliceerd: $appVersion" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
Write-Host " Registry images:" -ForegroundColor Green
|
||||
Write-Host " $backendVersionTag" -ForegroundColor White
|
||||
Write-Host " $backendLatestTag" -ForegroundColor White
|
||||
Write-Host " $frontendVersionTag" -ForegroundColor White
|
||||
Write-Host " $frontendLatestTag" -ForegroundColor White
|
||||
Write-Host " Registry image:" -ForegroundColor Green
|
||||
Write-Host " $appVersionTag" -ForegroundColor White
|
||||
Write-Host " $appLatestTag" -ForegroundColor White
|
||||
Write-Host ""
|
||||
Write-Host " Git-tag: $gitTag -> origin" -ForegroundColor Green
|
||||
Write-Host "════════════════════════════════════════" -ForegroundColor Cyan
|
||||
|
||||
Reference in New Issue
Block a user