Files
Sluijsens 6c08d0a842
Continuous Integration / config (pull_request) Successful in 10s
Continuous Integration / prepare (pull_request) Successful in 1m33s
Continuous Integration / build-production (pull_request) Skipped
Continuous Integration / build (pull_request) Successful in 2m13s
Continuous Integration / test (pull_request) Successful in 2m3s
Continuous Integration / deploy-test (pull_request) Skipped
Continuous Integration / deploy-production (pull_request) Skipped
Hernoem PI_MAIN_HOST secret naar PI_MAIN_ADDRESS
2026-07-30 13:32:42 +02:00

7.0 KiB

Deployment Plan

Chosen Method

Gitea Actions, opgesplitst in twee workflow-bestanden:

  • .gitea/workflows/continuous_integration.yaml — draait de build/test/lint-gate, automatisch bij elke pull request (ongeacht branch) en bij elke push/merge naar master, of handmatig via workflow_dispatch. De deploy-test-job zelf blijft daarnaast ook beperkt tot master/workflow_dispatch via een eigen if-check.
  • .gitea/workflows/deploy.yaml — een herbruikbare (workflow_call) job die de dist/ build via SCP (over SSH) uploadt naar de webroot van een omgeving.

Sinds deze stap is er een echte, geautomatiseerde upload naar een testomgeving: een Raspberry Pi die de statische site serveert via nginx, achter een tweede Raspberry Pi die als nginx reverse proxy fungeert.

How It Works

  1. Bij elke pull request draait automatisch de build/test/lint-gate (preparebuildtest), zodat merge requests direct gevalideerd worden.
  2. Zodra een pull request naar master gemerged wordt (of de workflow handmatig via workflow_dispatch gestart wordt), draait aanvullend de deploy-test job.
  3. deploy-test roept de herbruikbare deploy.yaml workflow aan met artifact_name/environment/deploy_path, en geeft via secrets: inherit de Pi-inloggegevens door. Deze drie waarden (samen met de artifact-naam/pad die de build-job gebruikt) staan als variabelen in het env:-blok bovenaan continuous_integration.yaml (ARTIFACT_NAME, ARTIFACT_PATH, DEPLOY_ENVIRONMENT, DEPLOY_PATH), en worden via een kleine config-job als job-outputs doorgegeven aan deploy-test (nodig omdat de env-context zelf niet werkt in de with:-sectie van een reusable-workflow-aanroep). DEPLOY_PATH zelf is geen hardcoded waarde meer, maar wordt gelezen uit de Gitea repository variable DEPLOY_PATH_TEST (Repository → Settings → Actions → Variables), zodat het uploadpad aangepast kan worden zonder de workflow te wijzigen — zie deployment-instructions.md.
  4. deploy.yaml downloadt de artifact en uploadt de inhoud via een scp-commando (met sshpass voor het wachtwoord) in een gewone shell-stap naar de webserver-Pi op het interne netwerk (192.168.1.103, poort 2224). Dit vervangt de eerdere appleboy/scp-action (Docker-container-action), die faalde op de zelf-gehoste Podman-runner (failed to attach to container: unable to upgrade to tcp, received 409).
  5. nginx op de webserver-Pi serveert de bestanden vanaf /mnt/storage1/www/html/test/slpsoftware; de reverse-proxy-Pi stuurt binnenkomend verkeer door naar deze webserver-Pi. Voorbeeldconfiguraties staan in operations/deployment/nginx/ en zijn de daadwerkelijk in gebruik zijnde configuraties (niet langer illustratieve concepten).
  6. De reverse-proxy-Pi is ook verantwoordelijk voor SSL: certificaten worden net als voorheen aangevraagd via certbot (Let's Encrypt) en HTTP-verkeer wordt doorverwezen naar HTTPS.

Environments

  • Test (geautomatiseerd, altijd): zoals hierboven beschreven. Draait automatisch bij elke merge naar master en bij elke handmatige workflow_dispatch-run. Domeinnaam: test.slpsoftware.nl (SSL via certbot op de reverse-proxy-Pi).
  • Productie (geautomatiseerd, opt-in): via een eigen build-production- en deploy-production-job in continuous_integration.yaml, die deploy.yaml aanroepen met environment: production. In tegenstelling tot de testdeploy draait dit niet automatisch bij een push naar master — alleen wanneer je de workflow handmatig start via workflow_dispatch mét het deploy_production-vinkje aangevinkt. Dit is bewust: zo kan niemand per ongeluk productie deployen door simpelweg naar master te pushen. Reden voor een aparte build-production-job (in plaats van hetzelfde artifact als de testbuild te hergebruiken): VITE_APP_ENV is een build-time Vite-variabele, dus één bundel kan niet tegelijk als test én production getagd zijn in Sentry/analytics. Domeinnaam: slpsoftware.nl (SSL eveneens via certbot). Productie-nginx-voorbeeldconfiguratie: nginx/production-nginx.conf.example (vóór certbot) en nginx/production-nginx.conf.post-certbot.example (referentie, hoe het bestand er na certbot uitziet) — dekt alléén de react-frontend-site; de daadwerkelijke productieserver regelt op hetzelfde domein ook mail/iRedAdmin-proxying, wat buiten de scope van deze feature valt. Vereist eenmalig de Gitea-variable DEPLOY_PATH_PRODUCTION (zie deployment-instructions.md) — zonder deze faalt de upload.

Automation Level

Volledig geautomatiseerd voor de testomgeving: build, test, lint én upload naar de test-Pi gebeuren zonder handmatige tussenstap, zodra er gemerged wordt naar master (of handmatig getriggerd wordt). Productie is ook geautomatiseerd, maar alleen als bewuste, expliciete actie (handmatige workflow_dispatch met het deploy_production-vinkje) — nooit automatisch bij een push.

Rollback Strategy

Zie rollback-plan.md — voor de testomgeving kan een eerdere commit/branch opnieuw gebouwd en geüpload worden door de workflow opnieuw te triggeren.

Secrets & Configuration

Voor de testomgeving zijn de volgende Gitea Actions Secrets (repository-niveau) vereist:

  • PI_MAIN_ADDRESS192.168.1.103 (intern IP van de webserver-Pi)
  • PI_MAIN_PORT2224
  • PI_MAIN_USERNAMEwebadmin
  • PI_MAIN_PASSWORD — het SSH-wachtwoord van deze gebruiker

Deze secrets heten bewust PI_MAIN_* in plaats van PI_TEST_*: alle webhosts gebruiken op dit moment dezelfde inloggegevens (dezelfde Pi), dus de naam is niet omgeving-specifiek. Mocht dat in de toekomst veranderen, dan worden alsnog omgeving-specifieke secrets geïntroduceerd.

Dit is bewust wachtwoord-authenticatie (voor nu, zoals gekozen), zodat de testomgeving snel werkend is. Zie "Future Work" in deployment-instructions.md voor de overstap naar SSH-key-authenticatie.

Resolved Item — Productie-deploy Geautomatiseerd

continuous_integration.yaml bevat nu een build-production- en deploy-production-job, alleen actief bij een handmatige workflow_dispatch-run met het deploy_production-vinkje aangevinkt (zie "Environments" hierboven). Aangezien de webhost (Pi Main) dezelfde blijft als de testomgeving, worden de bestaande PI_MAIN_* secrets hergebruikt — pas dit pas aan naar omgeving-specifieke secrets als productie daadwerkelijk op een andere host komt. Domeinnaam (slpsoftware.nl) en SSL-aanpak (certbot/Let's Encrypt op de reverse-proxy-Pi) liggen al vast; zie nginx/production-nginx.conf.example / nginx/production-nginx.conf.post-certbot.example voor de voorbeeldconfiguratie (react-frontend-only, geen mail/iRedAdmin). Voordat dit voor het eerst gebruikt wordt, moet de Gitea-variable DEPLOY_PATH_PRODUCTION nog worden aangemaakt (zie deployment-instructions.md) — zonder deze faalt de upload.

Verified Build Prerequisite

Dit plan bouwt voort op de Build and Test-stage (construction/build-and-test/build-and-test-summary.md): pnpm run build produceert een statische dist/-bundel zonder server-side vereisten, geschikt om direct door nginx geserveerd te worden.