# OpnForm — forms.doc-gen.eu Self-hosted, open-source formulierenbouwer ([OpnForm](https://github.com/OpnForm/OpnForm)) op de Hetzner CX33, voor cursusevaluaties, inschrijvingen, kennistoetsen en bestand-inleveren. EU-soeverein (Hetzner + eigen mailserver), geen Amerikaanse diensten in de draaiende keten. Deze repo is de **ref-kopie / bron van waarheid** van de deploy-configuratie én tegelijk de **git-bron die Coolify klont** om te deployen. ## ⚠️ Uitzondering: dit draait NIET via route B Anders dan casuspositie/doc-gen/transcriber/oefendossiers/joplin/freescout/hedgedoc is OpnForm **multi-image** en wordt het als **Coolify docker-compose-service (git-based)** gedraaid, met **exact gepinde image-tags**: - **Geen** registry-image, **geen** Forgejo Actions/CI (er wordt niets gebouwd). - **Geen** host-watcher-entry — voeg OpnForm dus **niet** toe aan `deploy-watcher/watch.sh`. - Coolify klont deze repo en draait `docker compose up`. - **Nginx-ingress-config staat INLINE in de compose** (top-level `configs:` → `content:`), niet als los bestand: Coolify materialiseert bij een git-compose alleen de compose + `.env` in de app-map, niet de overige repo-bestanden — een `./docker/nginx.conf`-bind-mount wordt dan een lege map. Inline is self-contained. De nginx-`$`-variabelen zijn als `$$` geschreven (docker compose zet `$$`→`$`). Zie ook de infra-skill `forgejo-coolify-pipeline` (§ OpnForm) en runbook `runbooks/opnform-cx33.md`. ## Componenten (compose) | service | image (gepind) | rol | |---|---|---| | `api` | `jhumanj/opnform-api:1.13.2` | Laravel API (php-fpm :9000) — draait zelf de migraties bij boot | | `api-worker` | idem | queue-worker (mail, exports) | | `api-scheduler` | idem | cron/scheduler | | `ui` | `jhumanj/opnform-client:1.13.2` | Nuxt SSR frontend (:3000) | | `redis` | `redis:7.4.11` | sessies, cache, queue | | `db` | `postgres:16.15` | database | | `ingress` | `nginx:1.30.4` | HTTP↔FastCGI + `/`-routing → het enige web-endpoint (poort 80) | Persistente volumes: `postgres-data`, `opnform_storage` (geüploade formulier-bestanden, lokaal — **geen S3**), `redis-data`. Domein/Traefik/LE: via de Coolify-magie `SERVICE_FQDN_INGRESS_80` op de `ingress`-service. `APP_URL`/`FRONT_URL`/`NUXT_PUBLIC_*` volgen automatisch `${SERVICE_URL_INGRESS}`. ## Updaten naar een nieuwe OpnForm-versie 1. Kijk de nieuwe tag na op Docker Hub (`jhumanj/opnform-api`, `jhumanj/opnform-client`) en de bijbehorende [release notes](https://github.com/OpnForm/OpnForm/releases). Controleer of `docker-compose.yml`/`docker/nginx.conf`/de env-variabelen in die release zijn gewijzigd (vergelijk met `OpnForm/OpnForm` op de tag) en neem wijzigingen hier over. 2. Bump de twee `jhumanj/opnform-*`-tags (en evt. postgres/redis/nginx) in `docker-compose.yml`. 3. `git commit` + `git push` naar `main`. 4. In Coolify (tunnel `ssh deploy@46.224.126.208 -L 8000:localhost:8000` → `http://localhost:8000`, óf via de API met de Mac-Mini-`COOLIFY_TOKEN`): de OpnForm-resource **Redeploy**. De api-container draait bij boot zelf `php artisan migrate --force`. 5. Verifieer: `curl -sL -o /dev/null -w '%{http_code} %{ssl_verify_result}\n' https://forms.doc-gen.eu/` → `200 0`. ## Secrets & env Staan **niet** in deze repo. Ze leven in de **Coolify-env** van de resource en in `~/.config/doc-gen-deploy/opnform.env` (0600) op de Mac Mini: `APP_KEY`, `JWT_SECRET`, `FRONT_API_SECRET`, `DB_PASSWORD`, `DB_DATABASE`, `DB_USERNAME`, `MAIL_USERNAME`, `MAIL_PASSWORD`, `MAIL_FROM_ADDRESS`, en `SERVICE_FQDN_INGRESS_80`. Mail loopt via `mail.2487.eu:465` (SSL). Beheerdersaccounts: gratis self-hosted OpnForm staat **max. 2 gebruikers** toe (formulier-invullers tellen niet mee — die zijn anoniem/ongelimiteerd). ## Coolify-object - Resource-type: **Docker Compose (git)**, project `My first project` / env `production`, server `localhost` (CX33). - App-uuid: _zie infra-issue en `runbooks/opnform-cx33.md`._ ## Beheer, backup & health - **Backup**: `pg_dump` van de OpnForm-Postgres + het `opnform_storage`-volume in de off-site restic-backup (`/usr/local/bin/docgen-backup.sh`, niet-fataal). - **Health**: `opnform-health.timer` (5 min, `curl .../` → 200, ntfy `docgen-backup` bij 2× niet-200). - **Eerste admin**: ga naar `https://forms.doc-gen.eu/` → `/setup` en maak het beheerdersaccount (e-mail + wachtwoord). Publieke registratie staat daarna uit; extra gebruikers via uitnodiging. Volledige onboarding + verificaties: infra-runbook `runbooks/opnform-cx33.md`.