Files
SlpSoftware/aidlc-docs/features/react-frontend/operations/deployment/deployment-instructions.md
T
SluijsensandClaude Sonnet 5 78f68d52f7
Continuous Integration / config (pull_request) Successful in 10s
Continuous Integration / prepare (pull_request) Successful in 1m18s
Continuous Integration / build (pull_request) Successful in 1m55s
Continuous Integration / test (pull_request) Successful in 1m50s
Continuous Integration / deploy-test (pull_request) Skipped
Maak DEPLOY_PATH configureerbaar via Gitea Actions variable i.p.v. hardcoded
Vervangt het hardcoded testpad in continuous_integration.yaml door de
Gitea repository variable DEPLOY_PATH_TEST, zodat het uploadpad aan te
passen is zonder de workflow zelf te wijzigen. Documentatie bijgewerkt
met de vereiste eenmalige Gitea-variable-setup.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-27 11:59:16 +02:00

8.7 KiB

Deployment Instructions

Overview

Deployment gebeurt via Gitea Actions, opgesplitst in twee bestanden:

  • .gitea/workflows/continuous_integration.yaml — build/test/lint-gate, plus de deploy-test job.
  • .gitea/workflows/deploy.yaml — herbruikbare workflow die dist/ via SCP naar een omgeving uploadt.

Sinds deze stap wordt er automatisch gedeployed naar een testomgeving: een Raspberry Pi die de site serveert via nginx, bereikbaar achter een tweede Raspberry Pi met een nginx reverse proxy.

Pipeline Files

  • continuous_integration.yaml — getriggerd door pull_request (build/test/lint-gate, ongeacht branch), push naar master (build/test/lint-gate + deploy-test), en handmatig via workflow_dispatch.
    • Heeft bovenaan een env:-blok met alle aanpasbare waarden op één plek: NODE_VERSION, PNPM_VERSION, ARTIFACT_NAME (dist), ARTIFACT_PATH (dist/), DEPLOY_ENVIRONMENT (test) en DEPLOY_PATH (gelezen uit de Gitea repository variable DEPLOY_PATH_TEST, zie hieronder — bewust geen hardcoded pad, zodat het aan te passen is zonder de workflow zelf te wijzigen).
    • preparebuild (uploadt de artifact, naam/pad uit env.ARTIFACT_NAME/env.ARTIFACT_PATH) → test (lint + unit tests)
    • Een losse config-job zet deze env-waarden om in job-outputs (zie hieronder waarom dat nodig is).
    • deploy-test (alleen bij workflow_dispatch of een push naar master) roept deploy.yaml aan met artifact_name/environment/deploy_path afkomstig van needs.config.outputs.* (dus indirect uit het env:-blok).
  • deploy.yaml — download de artifact (naam/lokaal pad = inputs.artifact_name) en upload de inhoud via een scp-commando (met sshpass voor het wachtwoord) in een gewone shell-stap naar de opgegeven deploy_path op de host uit de meegegeven secrets.

Waarom sshpass/scp in een shell-stap in plaats van de appleboy/scp-action Docker-action?

De oorspronkelijke aanpak gebruikte de appleboy/scp-action (een Docker-container-action). Dit werkte niet op deze zelf-gehoste Gitea-runner: de stap faalde met failed to attach to container: unable to upgrade to tcp, received 409, een bekende beperking van Podman's Docker-compatibele API, die het attach/log-streaming-mechanisme voor container-based actions niet volledig ondersteunt. De huidige aanpak (een normale run:-stap die sshpass installeert en zelf scp aanroept) heeft geen geneste container nodig en werkt daardoor wel.

Waarom een aparte config-job in plaats van rechtstreeks het env:-blok?

Gitea/GitHub Actions ondersteunt geen env-context in de with:-sectie waarmee een reusable workflow wordt aangeroepen (jobs.<job_id>.with) — dat werkt alléén binnen jobs.<job_id>.steps. De oplossing is een klein voorloop-job (config) dat de gewenste env-waarden via $GITHUB_OUTPUT naar job-outputs schrijft; die outputs (needs.config.outputs.*) zijn wél bruikbaar in jobs.<job_id>.with. Zo hoef je, om de artifact-naam/pad of de testdeploy-bestemming te wijzigen, alléén het env:-blok bovenaan continuous_integration.yaml aan te passen — niet de deploy-test-job zelf.

Eenmalige Setup — Gitea Secrets

Voeg deze secrets toe in Gitea: Repository → Settings → Actions → Secrets:

Secret Waarde
PI_MAIN_HOST Intern IP-adres van de webserver-Pi (192.168.1.103)
PI_MAIN_PORT SSH-poort (2224)
PI_MAIN_USERNAME SSH-gebruikersnaam (webadmin)
PI_MAIN_PASSWORD Het SSH-wachtwoord van deze gebruiker

Deze secrets heten PI_MAIN_* (niet PI_TEST_*), omdat dezelfde Pi (Pi Main) en dezelfde inloggegevens naar verwachting ook voor toekomstige omgevingen/webhosts gebruikt worden. Mocht dat later veranderen, dan worden hiervoor alsnog omgeving-specifieke secrets geïntroduceerd.

Eenmalige Setup — Gitea Variables

Voeg deze variable toe in Gitea: Repository → Settings → Actions → Variables (geen secret — het is geen gevoelige waarde, net als VITE_UMAMI_SCRIPT_URL/VITE_SENTRY_DSN):

Variable Waarde
DEPLOY_PATH_TEST /html/test/slpsoftware

Dit vervangt het eerder hardcoded DEPLOY_PATH in het env:-blok van continuous_integration.yaml, zodat het upload-pad aangepast kan worden zonder de workflow zelf te wijzigen. Zonder deze variable is DEPLOY_PATH leeg en faalt de deploy-test-job bij de SCP-upload — deze variable moet dus vóór de eerste deploy zijn ingesteld. Wanneer later een productie-job wordt toegevoegd, hoort daar een eigen variable bij (bijv. DEPLOY_PATH_PRODUCTION), analoog aan dit patroon.

Eenmalige Setup — Domeinnaam & DNS

  • Test: test.slpsoftware.nl → moet als DNS A-record wijzen naar het publieke IP van de reverse-proxy-Pi.
  • Productie (nog niet automatisch gedeployed, maar domein al bekend): slpsoftware.nl (en www.slpsoftware.nl) → zelfde reverse-proxy-Pi, zodra productie wordt opgezet.

Eenmalige Setup — nginx & SSL op de Raspberry Pi's

  1. Kopieer operations/deployment/nginx/webserver-nginx.conf.example naar /etc/nginx/sites-available/ op de webserver-Pi, maak een symlink in sites-enabled/, en herlaad nginx. Dit bestand is de daadwerkelijk in gebruik zijnde configuratie (server_name test.slpsoftware.nl, luistert op poort 80, serveert vanaf /mnt/storage1/www/html/test/slpsoftware).
  2. Kopieer operations/deployment/nginx/reverse-proxy-nginx.conf.example naar /etc/nginx/sites-available/slpsoftware-test.conf op de reverse-proxy-Pi, maak een symlink in sites-enabled/, en herlaad nginx. Dit is de versie van vóór certbot (alleen poort 80, geen SSL), met server_name test.slpsoftware.nl.
  3. Vraag op de reverse-proxy-Pi een SSL-certificaat aan met certbot (Let's Encrypt), nadat het DNS-record klopt: sudo certbot --nginx -d test.slpsoftware.nl. Certbot herschrijft dit bestand automatisch met de HTTPS-configuratie en de HTTP→HTTPS-redirect — zie operations/deployment/nginx/reverse-proxy-nginx.conf.post-certbot.example voor hoe het er dan uitziet (referentie, niet zelf kopiëren).
  4. Zorg dat de map /mnt/storage1/www/html/test/slpsoftware bestaat op de webserver-Pi en schrijfbaar is voor de gebruiker webadmin (bijv. sudo mkdir -p /mnt/storage1/www/html/test/slpsoftware && sudo chown webadmin:webadmin /mnt/storage1/www/html/test/slpsoftware).

Waarom deploy_path en de nginx root niet hetzelfde pad zijn: de pipeline uploadt via SCP naar deploy_path = /html/test/slpsoftware (de waarde van de Gitea variable DEPLOY_PATH_TEST, ingelezen via env.DEPLOY_PATH in continuous_integration.yaml), terwijl de nginx root in webserver-nginx.conf.example het volledige pad /mnt/storage1/www/html/test/slpsoftware is. Dit is geen fout of inconsistentie: de SSH/SCP-gebruiker (webadmin) heeft /mnt/storage1/www als root (vergelijkbaar met een FTP-chroot), dus vanuit het perspectief van deze gebruiker is /html/test/slpsoftware het juiste (relatieve) pad, terwijl dat op het bestandssysteem van de Pi zelf overeenkomt met het volledige pad /mnt/storage1/www/html/test/slpsoftware dat nginx als root gebruikt. Kortom: deploy_path (/html/test/slpsoftware) + de root van de webadmin-gebruiker (/mnt/storage1/www) = de nginx root (/mnt/storage1/www/html/test/slpsoftware).

How to Deploy to Test

Automatisch

Merge een pull request naar master — de deploy-test job draait dan automatisch na een groene build/test-run.

Handmatig

  1. In Gitea, open de repository's Actions tab.
  2. Selecteer de Continuous Integration workflow.
  3. Klik Run workflow, kies de gewenste branch/ref, en start.

Verifying a Deployment

  1. Bevestig dat de Gitea Actions run succesvol is (alle jobs groen, inclusief deploy-test).
  2. Open de testomgeving in de browser (via het adres/IP dat je bij de reverse-proxy hebt ingesteld) en controleer dat de site correct laadt (check de browserconsole op fouten, zoals in de handmatige smoke test in construction/build-and-test/integration-test-instructions.md).

Future Work

  • Van wachtwoord naar SSH-key: vervang sshpass -p "${{ secrets.PI_MAIN_PASSWORD }}" scp ... in deploy.yaml door een scp-commando met -i <key-bestand> (een nieuwe secret PI_MAIN_SSH_KEY die je eerst als bestand wegschrijft in de run-stap), en zet de bijbehorende public key in ~/.ssh/authorized_keys van de webadmin-gebruiker op de webserver-Pi. Verwijder daarna het wachtwoord-secret.
  • Productie-omgeving: voeg een deploy-production-job toe zodra de definitieve productiehosting bekend is (zie deployment-plan.md's "Open Item"). De productie-nginx-voorbeeldconfiguratie is op verzoek van de gebruiker verwijderd totdat er een goed-werkende versie is; die kan later opnieuw opgebouwd worden naar analogie van nginx/webserver-nginx.conf.example en nginx/reverse-proxy-nginx.conf.example, met domein slpsoftware.nl.