Skip to content

Commit 66aa960

Browse files
committed
feat(container): bundel FastAPI-host met statische site
1 parent feefb21 commit 66aa960

File tree

6 files changed

+76
-85
lines changed

6 files changed

+76
-85
lines changed

README.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,38 @@ Bij het gebruik van `npm run dev` worden design tokens automatisch opnieuw gebou
111111

112112
---
113113

114+
## Digitale Assistent (backend)
115+
116+
De [Digitale Assistent](services/README.md) draait op een Python-host (FastAPI) die twee LLM-backends (VLAM en Claude) combineert met overheidsbronnen via MCP of CLI.
117+
118+
### Lokaal draaien met `uv`
119+
120+
Bouw eerst de statische site (`npx @11ty/eleventy`), start dan de host — deze serveert zowel de API als de statische site op dezelfde poort:
121+
122+
``` bash
123+
cd services/host
124+
uv run --with-requirements requirements.txt \
125+
uvicorn api:app --host 0.0.0.0 --port 8090
126+
```
127+
128+
De Digitale Assistent is dan bereikbaar op [`localhost:8090/moza/digitale-assistent/`](http://localhost:8090/moza/digitale-assistent/).
129+
130+
API-sleutels kunnen op twee manieren worden gezet:
131+
132+
- via `services/host/.env` (zie `services/host/.env.example`)
133+
- via het feature-flags paneel rechtsonder in de site — deze worden per request als header meegestuurd en overrulen de `.env`
134+
135+
### Containerisatie
136+
137+
De `container/Containerfile` bouwt een single-image deployment: een Node-builder genereert de Eleventy-site, een Python-release-image installeert de host-dependencies en serveert alles via `uvicorn` op poort 8080. Dezelfde image wordt gebruikt voor preview- en productiedeploys (ZAD).
138+
139+
``` bash
140+
docker build -f container/Containerfile -t moza .
141+
docker run --rm -p 8080:8080 --env-file services/host/.env moza
142+
```
143+
144+
---
145+
114146
## Storybook
115147

116148
[Storybook](https://storybook.js.org/) is de omgeving om afzonderlijke componenten te bekijken, testen en documenteren.
@@ -172,7 +204,12 @@ npm install
172204
📁 fonts Rijkslettertype webfonts
173205
📁 icons iconen
174206
📁 images afbeeldingen
207+
📂 container Containerfile voor de gebundelde deployment (site + host)
175208
📂 moza prototype voor MijnOverheid Zakelijk, gebaseerd op deze omgeving
209+
📂 services Digitale Assistent — FastAPI-host, MCP-servers en CLI-tools
210+
📁 host FastAPI-host die statische site én chat-API serveert
211+
📁 mcp MCP-servers (kvk, koop, regelrecht, rvo)
212+
📁 cli Bash-CLI's als alternatief transport
176213
📂 stories ‘stories’ om componenten weer te geven in Storybook
177214
📂 style
178215
📄 _reset.css cross-browser stijl normalisatie

container/Containerfile

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM node:20-alpine AS builder
1+
FROM node:20-alpine AS site_builder
22

33
WORKDIR /app
44
COPY package.json package-lock.json ./
@@ -8,10 +8,32 @@ RUN cd style-dictionary && npm ci && npm run build
88
RUN npx @11ty/eleventy
99
RUN npx storybook build -o _site/storybook
1010

11-
FROM nginxinc/nginx-unprivileged:stable-alpine-slim
1211

13-
COPY --from=builder /app/_site /usr/share/nginx/html
14-
COPY container/nginx.conf /etc/nginx/nginx.conf
15-
COPY container/default.conf /etc/nginx/conf.d/default.conf
12+
FROM python:3.12-slim
1613

14+
WORKDIR /app
15+
16+
RUN apt-get update \
17+
&& apt-get install -y --no-install-recommends bash jq curl \
18+
&& rm -rf /var/lib/apt/lists/*
19+
20+
COPY services/host/requirements.txt /tmp/requirements.txt
21+
RUN pip install --no-cache-dir -r /tmp/requirements.txt
22+
23+
COPY services /app/services
24+
COPY --from=site_builder /app/_site /app/_site
25+
26+
RUN adduser --disabled-password --gecos "" --uid 1001 app \
27+
&& chown -R app:app /app
28+
USER app
29+
30+
ENV PYTHONUNBUFFERED=1 \
31+
PYTHONPATH=/app/services/host \
32+
STATIC_DIR=/app/_site \
33+
VLAM_HOST=0.0.0.0 \
34+
VLAM_PORT=8080
35+
36+
WORKDIR /app/services/host
1737
EXPOSE 8080
38+
39+
CMD ["uvicorn", "api:app", "--host", "0.0.0.0", "--port", "8080"]

container/default.conf

Lines changed: 0 additions & 29 deletions
This file was deleted.

container/nginx.conf

Lines changed: 0 additions & 29 deletions
This file was deleted.

container/supervisord.conf

Lines changed: 0 additions & 22 deletions
This file was deleted.

services/host/api.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,15 @@
66

77
import json
88
import logging
9+
import os
910
import uuid
1011
from contextlib import asynccontextmanager
12+
from pathlib import Path
1113

1214
from fastapi import FastAPI, Request
1315
from fastapi.middleware.cors import CORSMiddleware
1416
from fastapi.responses import StreamingResponse
17+
from fastapi.staticfiles import StaticFiles
1518
from pydantic import BaseModel
1619

1720
from config import VLAM_HOST, VLAM_PORT
@@ -169,6 +172,15 @@ async def health():
169172
}
170173

171174

175+
_default_static = Path(__file__).resolve().parent.parent.parent / "_site"
176+
_static_dir = Path(os.getenv("STATIC_DIR") or _default_static)
177+
if _static_dir.is_dir():
178+
app.mount("/", StaticFiles(directory=_static_dir, html=True), name="site")
179+
logging.getLogger("vlam.api").info("Statische site gemount vanuit %s", _static_dir)
180+
else:
181+
logging.getLogger("vlam.api").warning("Geen statische site gevonden op %s", _static_dir)
182+
183+
172184
if __name__ == "__main__":
173185
import uvicorn
174186

0 commit comments

Comments
 (0)