Nieuw: scripts/install.sh — installeert de stack in zeven zichtbare stappen
met drie vragen, standaard in /srv/server-up (aan te passen met
ROOSTERWIJS_DIR). Het script:
- controleert git, docker, de compose-plugin en of de daemon bereikbaar is;
- maakt de doelmap aan, of legt uit welk commando daarvoor nodig is als de
rechten ontbreken (roept zelf geen sudo aan);
- kloont of werkt de checkout bij;
- laat kiezen waar de gegevens komen (zie hieronder);
- genereert .env met een willekeurige DJANGO_SECRET_KEY en een sterk
databasewachtwoord, en zet hostnaam, CSRF-origin en DJANGO_SECURE op basis
van twee vragen; een bestaande .env wordt nooit zomaar overschreven;
- bouwt en start de containers;
- meldt of er een account is en biedt aan er een aan te maken.
Opslagkeuze bij de installatie:
- docker-compose.yml gebruikt nu ${DATA_DB}, ${DATA_MEDIA} en ${DATA_STATIC}.
Een naam = Docker-volume, een pad = gewone map naast de code.
- De standaardwaarden zijn de bestaande named volumes, dus installaties die
al draaien veranderen niet en er gaan geen gegevens verloren.
- Kies je voor mappen, dan komt alles onder /srv/server-up/data/.
Verder:
- .gitignore: /data/ uitgesloten. Zonder dat zou de gegevensmap als lokale
wijziging gelden en zou deploy.sh weigeren te draaien.
- deploy.sh maakt de gegevensmappen aan als de opslagkeuze paden gebruikt,
zodat Docker ze niet als root aanmaakt.
- DEPLOY.md en README: installatie via het script, de opslagkeuze in een
tabel, en de dump/restore-stappen die nodig zijn bij het omzetten van
volumes naar mappen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FAQ4Np13v8fwbTtKHKnwDz
De installatiestappen in de README waren niet uitvoerbaar en het
deploy-script kon stilzwijgend werk vernietigen.
README:
- `python manage.py migrate` liep vast op `RuntimeError: DJANGO_SECRET_KEY
ontbreekt`. DEBUG staat standaard uit en dan is die sleutel verplicht;
de instructies noemden `DJANGO_DEBUG` nergens. Nu toegevoegd, met uitleg.
- `createsuperuser` stond als "optioneel, voor /admin/". Dat klopt niet: de
hele API staat op `IsAuthenticated`, dus zonder account kom je de app
helemaal niet in. Nu gemarkeerd als verplichte stap.
- Stap voor een virtual environment toegevoegd (pip installeerde anders in
de systeem-Python, wat op recente distributies afketst op PEP 668).
- Node-eis vermeld: Vite 8 vereist 20.19+ of 22.12+.
- Verouderde beschrijvingen bijgewerkt: de tabs van het roosterscherm
(Week/Genereren/Instellingen in plaats van Weekrooster/Conflicten/
Schooljaar/Instellingen), Groepsindeling is een eigen scherm en geen tab,
en er zijn twaalf modules in plaats van "twee voorbeeldmodules".
DEPLOY.md:
- `git clone .../Roostersoftware.git` + `cd Roostersoftware` gebruikte de
verkeerde repo-naam; dat is `roosterwijs`.
- CSRF-origin en FRONTEND_BASE_URL stonden als http-voorbeeld; achter TLS
moet dat https zijn.
- Rechtgezet: `DJANGO_CSRF_TRUSTED_ORIGINS` blokkeert het inloggen in de app
niet (DRF-views zijn `csrf_exempt`), maar wel de Django-admin.
- Vermeld dat er nergens automatisch een account wordt aangemaakt.
scripts/deploy.sh:
- Stopt nu als `.env` ontbreekt; anders start de stack met lege variabelen
en faalt de backend met een onduidelijke fout.
- Stopt bij lokale wijzigingen in plaats van ze met `git reset --hard`
weg te gooien; bewust overschrijven kan met `--force`.
- Controleert vooraf of Docker en de compose-plugin er zijn.
- Toont welke commits erbij komen (oud -> nieuw) in plaats van alleen de
nieuwe HEAD.
- Controleert na afloop of de backend antwoordt en of er een actief account
bestaat, met het createsuperuser-commando als dat er niet is.
frontend/Dockerfile:
- Bouwt op node:22-alpine in plaats van node:20-alpine, gelijk aan de CI en
ruim binnen de Node-eis van Vite 8.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FAQ4Np13v8fwbTtKHKnwDz
Inloggen mislukte met DJANGO_SECURE=1 achter een reverse proxy die TLS
afhandelt, terwijl het inlogscherm zelf wel laadde.
- nginx.conf gaf `X-Forwarded-Proto $scheme` door. Achter een TLS-proxy
komt het verzoek als http binnen, dus overschreef nginx de `https` van
de proxy met `http`. Django zag de verbinding daardoor als onveilig en
stuurde elk verzoek naar /api en /admin door naar https, waarna de
proxy het weer als http aanleverde: een oneindige redirect-lus.
- nginx neemt nu de X-Forwarded-Proto van de proxy over via een map, en
valt alleen terug op $scheme als die header ontbreekt. Werkt daardoor
zowel achter een externe proxy als bij TLS op nginx zelf.
- .env.example: voorbeelden voor CSRF-origin en frontend-URL op https
gezet, DJANGO_SECURE standaard op 1, met uitleg waarom een http-origin
het inloggen met een CSRF-fout laat stranden.
- DEPLOY.md: checklist "Draaien achter TLS" toegevoegd met de drie
vereisten (proxy-header, CSRF-origin, allowed hosts), commando's om te
controleren of de header aankomt, en het advies poort 8080 aan de
loopback te binden zodat de app niet buiten TLS om bereikbaar is.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FAQ4Np13v8fwbTtKHKnwDz