2dd5ed5877
check / flake-check (pull_request) Has been cancelled
- sops-nix flake input, age + ssh-to-age in devShell, .sops.yaml with per-host recipients (real pubkeys still TODO until lars bootstraps). - nix/modules/gebos-secrets.nix centralises per-host secret subsets and renders /run/secrets/gebos-env via sops.templates. Service modules now read EnvironmentFile= from services.gebos.secrets.envFile instead of the placeholder /etc/gebos/secrets.env. - Falls back to a writeText env file when nix/secrets/secrets.yaml is absent, so `nix flake check` and first-boot eval work pre-bootstrap. - nix/secrets/README.md walks through age key + sops bootstrap. - Dev defaults: ingester binary falls back to local tcp/postgres URLs, process-compose adds mosquitto and wires GEBOS_MQTT_BROKER / GEBOS_POSTGRES_URL / GEBOS_POSTGRES_PASSWORD + VITE_SUPABASE_URL / VITE_SUPABASE_ANON_KEY, frontend defaults to 127.0.0.1:8000 in DEV. Refs #23 (comment #110).
67 lines
2.5 KiB
Markdown
67 lines
2.5 KiB
Markdown
# Gebos
|
|
|
|
IoT telemetry stack on bare-metal NixOS.
|
|
|
|
This repo is a monorepo containing all code, NixOS modules, host configurations,
|
|
and CI/CD pipelines for the project. Everything is one `flake.nix`.
|
|
|
|
## Architecture
|
|
|
|
Three hosts (see issue #21 for the full design discussion):
|
|
|
|
| Host | Role | Public hostname |
|
|
| ------------- | ----------------------------------------- | ---------------------- |
|
|
| `mqtt-ingest` | HiveMQ CE + Go MQTT→Postgres ingester | `ingest.ge-bos.de` |
|
|
| `db-host` | Postgres 17 + TimescaleDB (telemetry+auth)| internal only |
|
|
| `app-host` | Caddy + Kong + Supabase (compose) + SPA | `app.ge-bos.de`, `api.ge-bos.de` |
|
|
|
|
Public REST surface is PostgREST + SQL `/rpc/` functions, fronted by Kong, TLS-terminated by Caddy.
|
|
Supabase Studio is bound to `127.0.0.1` on `app-host` — reach it with `ssh -L 3000:127.0.0.1:3000 app-host`.
|
|
|
|
## Repo layout
|
|
|
|
```
|
|
flake.nix
|
|
frontend/ # Vite + React SPA
|
|
ingester/ # Go MQTT → Postgres
|
|
nix/
|
|
modules/ # NixOS modules (one per service)
|
|
hosts/ # nixosConfigurations: mqtt-ingest, db-host, app-host
|
|
supabase/ # vendored Supabase docker-compose, db init SQL
|
|
dev/ # process-compose for local development
|
|
deploy.nix # deploy-rs node map
|
|
.gitea/workflows/ # CI + CD
|
|
```
|
|
|
|
## Local development
|
|
|
|
```
|
|
nix run .#dev
|
|
```
|
|
|
|
Brings the full stack up on one machine via process-compose-flake (Postgres,
|
|
Supabase compose, Kong, Caddy, ingester, Vite dev server). NixOS required.
|
|
|
|
## Deployment
|
|
|
|
`deploy-rs` from a Gitea Actions runner on push to `main`. Closures are built
|
|
once, copied to each host, activated with auto-rollback. Order: `db-host` →
|
|
`app-host` → `mqtt-ingest`.
|
|
|
|
```
|
|
nix run github:serokell/deploy-rs -- .#db-host # one host
|
|
nix run github:serokell/deploy-rs -- . # all hosts
|
|
```
|
|
|
|
## Secrets
|
|
|
|
[sops-nix](https://github.com/Mic92/sops-nix) + [age](https://github.com/FiloSottile/age).
|
|
Single encrypted file at `nix/secrets/secrets.yaml`; each host decrypts only the
|
|
keys it needs at activation, rendered into a tmpfs env file consumed by systemd
|
|
`EnvironmentFile=`. Plaintext never enters the Nix store. See
|
|
[`nix/secrets/README.md`](nix/secrets/README.md) for bootstrap and rotation.
|
|
|
|
Local dev needs **no** secrets bootstrap — `nix run .#dev`, `go run ./ingester`,
|
|
and `npm --prefix frontend run dev` all default to the local dev stack values
|
|
defined in `nix/dev/process-compose.nix`.
|