67b37b9b2a06cf8566e73bbb8ff18602b82a4c5b
Bring up portainer first as the operator console — before nginx-proxy + TLS are wired. Self-signed UI on tcp/9443, edge-agent tunnel on tcp/8000. Once nginx-proxy lands, ports get commented out and access shifts to https://portainer.wbd-rd.nl/ behind the wildcard cert. The :9443 direct access remains as commented config for emergency ops if nginx is down. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
infra
R&D infrastructure stacks for Waterschap Brabantse Delta. Hub-and-spoke deployment: one cloud central hub + per-plant edge sites.
Layout
infra/
├── stacks/ # reusable, runnable stack defs (kebab-case)
├── cloud/ # the single central hub
├── sites/ # per-plant edge deployments
└── docs/ # architecture + conventions
Stacks are pulled into the cloud and site composes via the Compose Spec include: directive. Each stack is also runnable standalone for testing.
Quick start
# Cloud hub (run on the central server)
cd cloud
cp .env.example .env # fill in real secrets
docker compose up -d
# A plant edge (run on the edge gateway at the plant)
cd sites/<plant>
cp .env.example .env
docker compose up -d
Stacks
| Stack | Purpose | Cloud | Edge |
|---|---|---|---|
| node-red | Flow-based automation | ✓ | ✓ |
| influxdb | Time-series database | ✓ | ✓ |
| grafana | Dashboards / SCADA | ✓ | ✓ |
| keycloak | Identity / SSO | ✓ | ✓ |
| portainer | Container management UI | ✓ | ✓ |
| nginx-proxy | Stock nginx + certbot sidecar | ✓ | ✓ |
| rabbitmq | General-purpose broker (AMQP + MQTT plugin) | ✓ | ✓ |
| postfix | Outbound mail relay | ✓ | ✓ |
| wireguard-server | VPN server | ✓ | — |
| wireguard-client | VPN client | — | ✓ |
| gitea | Git server (HTTPS-only) | ✓ | — |
| jenkins | CI/CD | ✓ | — |
| sql | Config DB (postgres 16) | ✓ | — |
| mlflow | ML experiment tracking + registry | ✓ | — |
| jupyterhub | Multi-user notebook server | ✓ | — |
| mosquitto | MQTT broker for FROST stack only | ✓ | — |
Sites
| Site | Status |
|---|---|
| gemaal1 | Scaffolded — awaiting hardware provisioning |
Design
See docs/architecture.md for the hub-and-spoke topology, 4-network model, ingress table, and the reasoning behind each choice.
Conventions
- kebab-case folder names
compose.yml(Compose Spec), notdocker-compose.yml- Stack composes pulled into cloud/site via
include: - Secrets in
.envfiles (gitignored);.env.examplecommitted with placeholders - OT layer (OPCUA, PLCs) is out of scope for this repo
Description
Languages
Shell
56.5%
JavaScript
26.8%
Python
13.4%
Dockerfile
3.3%