Files
SlpSoftware/aidlc-docs/features/react-frontend/operations/deployment/deployment-instructions.md
T
Sluijsens d71d0636c0
Continuous Integration / config (pull_request) Successful in 10s
Continuous Integration / prepare (pull_request) Successful in 1m13s
Continuous Integration / build (pull_request) Successful in 2m2s
Continuous Integration / test (pull_request) Successful in 1m51s
Continuous Integration / deploy-test (pull_request) Skipped
Split nginx voorbeeldconfigs in pre- en post-certbot varianten, plus access/error logs
De reverse-proxy en analytics nginx-configs toonden al de door certbot beheerde
eindstaat (met SSL-directives), terwijl je die juist nodig hebt vóórdat certbot
draait. Nu is het .example-bestand de kale HTTP-versie om te kopiëren, met een
apart .post-certbot.example ter referentie voor de staat erna. Alle configs
(inclusief webserver-nginx.conf.example) hebben nu ook expliciete error_log/
access_log directives.
2026-07-25 23:45:34 +02:00

7.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 (/html/test/slpsoftware).
    • 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 — 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 (zie 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.