Ga naar inhoud

Formulieren deployen via GitHub (zonder server-toegang)

Een developer hoeft niet op de server in te loggen. Alles loopt via GitHub. Een self-hosted runner op de server pakt de jobs op (alleen uitgaande verbinding; geen open poorten).

Een nieuw of gewijzigd formulier live zetten

  1. Ontwerp het formulier in de repo. Maak/bewerk config/forms/<slug>/:
  2. form.py — de definitie (kopieer config/forms/skeleton-form.py als startpunt)
  3. objecttype.json — het objecttype dat bij dit formulier hoort
  4. deploy.sh — de deploy-wrapper (kopieer van een bestaand formulier)

Zie ../developer/formulieren-tips.md voor de valkuilen.

  1. Commit op een branch en open een PR. Een commit of merge doet op zichzelf niets op de server — er gaat dus niets automatisch live en er is geen downtime.

  2. Merge de PR naar main (na review).

  3. Deploy met de knop. GitHub → tab Actions → workflow "Formulieren deployen"Run workflow:

  4. laat het veld leeg om alle formulieren te (her)deployen, of
  5. vul de mapnaam in (bv. evenementenvergunning) voor één formulier.

De runner haalt main op, maakt het objecttype aan als het nog niet bestaat, en bouwt het formulier in Open Forms. Dit is zero-downtime: er draait alleen manage.py shell ín de draaiende container, geen herstart.

Idempotent: je kunt de deploy zo vaak draaien als je wilt. Het script is de bron van waarheid — pas het script aan, niet de admin-UI.

Losse objecttypes deployen

Objecttypes die bij een formulier horen (config/forms/<slug>/objecttype.json) gaan automatisch mee met "Formulieren deployen". Voor de standalone objecttypes in config/objecttypes/ (niet form-gebonden) is er een aparte knop:

GitHub → Actions"Objecttypes deployen"Run workflow. Dit is zero-downtime en doet twee dingen: 1. de objecttype-definitie(s) aanmaken/bijwerken (bootstrap-objecttype.sh); 2. de Objects-API-permissies toepassen (objects.yamlsetup_configuration), zodat een nieuw objecttype ook echt beschrijfbaar is (anders krijg je 403).

Voorwaarde voor een nieuw standalone objecttype dat beschreven moet worden: voeg het toe aan config/objects.yaml (permissie-entry) en aan de envsubst- whitelist in scripts/setup-service.sh. Let op: bootstrap-objecttype.sh publiceert alleen versie 1; een schema-wijziging van een bestaand type is een nieuwe objecttype-versie en valt buiten deze knop.

Onderhoud (acties die WEL downtime geven)

Image-updates, migraties en herstarts maken de stack even onbeschikbaar. Die zitten bewust in een aparte handmatige workflow, zodat downtime alleen op een zelfgekozen moment gebeurt — nooit automatisch bij een commit of merge.

GitHub → Actions"Onderhoud (kan downtime geven)"Run workflow: - kies de actie (image-update + herstart / migraties / herstart); - typ JA ter bevestiging (anders breekt de workflow af zonder iets te doen).

De workflow voert deze stappen uit (gebruikers zien een nette pagina, HTTP 503, i.p.v. een fout — zie platform/docs/onderhoud.md):

  1. Onderhoudspagina AAN — vóór de actie.
  2. De gekozen actie — image-update + herstart / migraties / herstart.
  3. Wachten tot Open Forms weer reageert (readiness-stap) — docker compose restart/up keert al terug zodra de containers dráaien, maar Open Forms heeft daarna nog ~15–20s nodig om te serveren. Deze stap pollt OF rechtstreeks op het interne netwerk (langs de onderhoudspagina heen; elke HTTP-statusregel = OF is up) en gaat pas door zodra OF echt antwoordt. Zonder deze stap zou de pagina te vroeg uitgaan en zagen gebruikers alsnog een 502.
  4. Onderhoudspagina UIT — alleen bij succes (dus pas nadat OF weer reageert).

Mislukt een stap (incl. een time-out van de readiness-stap, ~120s), dan blijft de pagina bewust aan — liever de pagina dan een kapotte site. De run-log waarschuwt dat je 'm na herstel handmatig uitzet met cd platform && make onderhoudsmodus-uit.

Onder de motorkap

  • Runner: systemd-service gh-runner-zgw op de server (/opt/actions-runner-zgw), labels self-hosted, zgw. Draait als de aparte deploy-user (niet root), die in de docker-groep zit en via een ACL alleen /root/zgw mag benaderen. Status: GitHub → Settings → Actions → Runners.
  • Secrets: de runner gebruikt de live /root/zgw/.env op de server; er staan geen secrets in GitHub. De git fetch in de workflow authenticeert met de repo-gescopete job-token (github.token), niet met een opgeslagen sleutel.
  • Workflows: .github/workflows/deploy-forms.yml en .github/workflows/onderhoud.yml. Beide draaien git reset --hard origin/main zodat de server exact main volgt (de gegenereerde/gitignorede bestanden zoals .env blijven staan).

Beveiliging: deploy zit in de docker-groep — dat is in de praktijk root-equivalent (docker kan de host-fs mounten). De winst t.o.v. root is procesisolatie, helder eigenaarschap en geen per ongeluk root-geschreven bestanden. Wil je écht minder rechten, dan kan een smalle sudo-regel voor alleen de specifieke compose-commando's i.p.v. docker-groep.