change domains, ips and make flake check work
This commit is contained in:
@@ -13,7 +13,7 @@ jobs:
|
||||
run: |
|
||||
mkdir -p ~/.ssh
|
||||
install -m 600 /dev/stdin ~/.ssh/id_ed25519 <<< "${{ secrets.DEPLOY_SSH_KEY }}"
|
||||
ssh-keyscan -H db-host.gebos.internal app-host.gebos.internal ingest.ge-bos.de >> ~/.ssh/known_hosts 2>/dev/null || true
|
||||
ssh-keyscan -H db.gebos.online app.gebos.online ingest.gebos.online >> ~/.ssh/known_hosts 2>/dev/null || true
|
||||
|
||||
- name: Build all closures
|
||||
run: nix flake check --no-build
|
||||
|
||||
@@ -9,15 +9,28 @@ and CI/CD pipelines for the project. Everything is one `flake.nix`.
|
||||
|
||||
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` |
|
||||
| Host | Role | Public hostname | Private IP |
|
||||
| ------------- | ----------------------------------------- | ---------------------- | ---------- |
|
||||
| `mqtt-ingest` | HiveMQ CE + Go MQTT→Postgres ingester | `ingest.gebos.online` | `10.0.0.4` |
|
||||
| `db-host` | Postgres 17 + TimescaleDB (telemetry+auth)| `db.gebos.online` (SSH only) | `10.0.0.2` |
|
||||
| `app-host` | Caddy + Kong + Supabase (compose) + SPA | `app.gebos.online`, `api.gebos.online` | `10.0.0.3` |
|
||||
|
||||
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`.
|
||||
|
||||
### Networking
|
||||
|
||||
There is no private DNS. Each host has a public hostname (used for `deploy-rs`
|
||||
SSH access from the Gitea runner, which is **not** on the private network, plus
|
||||
TLS ingress where applicable), and a static `10.0.0.0/8` IP used for all
|
||||
host-to-host traffic:
|
||||
|
||||
- `db.gebos.online` is for SSH/deploy only — Postgres is never exposed publicly.
|
||||
- `app-host` and `mqtt-ingest` reach Postgres at `10.0.0.2:5432` over the private
|
||||
network.
|
||||
- `db-host` only accepts Postgres (port 5432) from `10.0.0.0/8` (firewall rule
|
||||
in `nix/hosts/db-host.nix`).
|
||||
|
||||
## Repo layout
|
||||
|
||||
```
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
{ buildNpmPackage, lib }:
|
||||
{ buildNpmPackage }:
|
||||
|
||||
buildNpmPackage {
|
||||
pname = "gebos-frontend";
|
||||
version = "0.0.0";
|
||||
src = ./.;
|
||||
|
||||
# Filled in once package-lock.json exists.
|
||||
npmDepsHash = lib.fakeHash;
|
||||
npmDepsHash = "sha256-GeXgNbf94QRLNaZP8ma2vx19Vzm8jDWPeOTvE9exwm0=";
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
|
||||
@@ -11,7 +11,7 @@ const DEV_SUPABASE_ANON_KEY =
|
||||
|
||||
const SUPABASE_URL =
|
||||
import.meta.env.VITE_SUPABASE_URL ??
|
||||
(import.meta.env.DEV ? DEV_SUPABASE_URL : "https://api.ge-bos.de");
|
||||
(import.meta.env.DEV ? DEV_SUPABASE_URL : "https://api.gebos.online");
|
||||
|
||||
const SUPABASE_ANON_KEY =
|
||||
import.meta.env.VITE_SUPABASE_ANON_KEY ??
|
||||
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
/// <reference types="vite/client" />
|
||||
+6
-3
@@ -18,8 +18,11 @@ in
|
||||
|
||||
nodes = {
|
||||
# Order matters: the Gitea Actions workflow invokes them in this sequence.
|
||||
db-host = mkNode "db-host" "db-host.gebos.internal"; # TODO: real address
|
||||
app-host = mkNode "app-host" "app-host.gebos.internal"; # TODO: real address
|
||||
mqtt-ingest = mkNode "mqtt-ingest" "ingest.ge-bos.de";
|
||||
# SSH/deploy targets use public hostnames because the Gitea runner is not on
|
||||
# the private network. Host-to-host traffic still uses the 10.0.0.0/8 IPs.
|
||||
# See the host address table in README.md.
|
||||
db-host = mkNode "db-host" "db.gebos.online";
|
||||
app-host = mkNode "app-host" "app.gebos.online";
|
||||
mqtt-ingest = mkNode "mqtt-ingest" "ingest.gebos.online";
|
||||
};
|
||||
}
|
||||
|
||||
@@ -38,6 +38,13 @@ let
|
||||
VITE_SUPABASE_URL = dev.supabaseUrl;
|
||||
VITE_SUPABASE_ANON_KEY = dev.anonKey;
|
||||
};
|
||||
|
||||
# services-flake ships no MQTT broker, so run mosquitto as a plain
|
||||
# process-compose process. Anonymous access on the dev listener only.
|
||||
mosquittoConf = pkgs.writeText "mosquitto-dev.conf" ''
|
||||
listener ${toString dev.mqttPort} ${dev.mqttHost}
|
||||
allow_anonymous true
|
||||
'';
|
||||
in
|
||||
{
|
||||
imports = [ services-flake.processComposeModules.default ];
|
||||
@@ -48,14 +55,18 @@ in
|
||||
port = dev.pgPort;
|
||||
initialDatabases = [{ name = dev.pgDB; }];
|
||||
};
|
||||
|
||||
mosquitto."broker" = {
|
||||
enable = true;
|
||||
port = dev.mqttPort;
|
||||
};
|
||||
};
|
||||
|
||||
settings.processes = {
|
||||
broker = {
|
||||
command = "${pkgs.mosquitto}/bin/mosquitto -c ${mosquittoConf}";
|
||||
readiness_probe = {
|
||||
exec.command = "${pkgs.mosquitto}/bin/mosquitto_sub -h ${dev.mqttHost} -p ${toString dev.mqttPort} -t '$$SYS/#' -C 1 -W 2";
|
||||
initial_delay_seconds = 1;
|
||||
period_seconds = 2;
|
||||
};
|
||||
};
|
||||
|
||||
ingester = {
|
||||
command = "${pkgs.go}/bin/go run ./ingester";
|
||||
environment = ingesterEnv;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
services.gebos.supabase = {
|
||||
enable = true;
|
||||
# Compose stack points at external db-host instead of the bundled `db` service.
|
||||
postgresHost = "db-host.gebos.internal"; # TODO: real internal hostname
|
||||
postgresHost = "10.0.0.2"; # db-host on the private network
|
||||
postgresPort = 5432;
|
||||
# Studio bound to loopback only — reach via `ssh -L 3000:127.0.0.1:3000 app-host`.
|
||||
studioBindAddress = "127.0.0.1";
|
||||
@@ -18,8 +18,8 @@
|
||||
enable = true;
|
||||
# Caddy terminates TLS, proxies to Kong on 127.0.0.1:8000.
|
||||
sites = {
|
||||
"api.ge-bos.de" = { upstream = "127.0.0.1:8000"; }; # → Kong → PostgREST/GoTrue
|
||||
"app.ge-bos.de" = { staticRoot = "${config.services.gebos.frontend.package}/share/frontend"; };
|
||||
"api.gebos.online" = { upstream = "127.0.0.1:8000"; }; # → Kong → PostgREST/GoTrue
|
||||
"app.gebos.online" = { staticRoot = "${config.services.gebos.frontend.package}/share/frontend"; };
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
enable = true;
|
||||
settings.PasswordAuthentication = false;
|
||||
};
|
||||
# TODO: restrict inbound SSH (port 22) to the Gitea deployment runner's IP
|
||||
# only, instead of leaving it open to the world. Likely via
|
||||
# services.openssh.openFirewall = false + a firewall.extraInputRules rule
|
||||
# accepting tcp dport 22 from the runner's source address.
|
||||
|
||||
networking.firewall.enable = true;
|
||||
|
||||
|
||||
@@ -15,15 +15,15 @@
|
||||
services.gebos.ingester = {
|
||||
enable = true;
|
||||
# mqttBroker defaults to tcp://127.0.0.1:1883 (the local HiveMQ).
|
||||
postgresUrl = "postgres://gebos_ingest@db-host.gebos.internal:5432/postgres?sslmode=require";
|
||||
postgresUrl = "postgres://gebos_ingest@10.0.0.2:5432/postgres?sslmode=require";
|
||||
# GEBOS_POSTGRES_PASSWORD sourced from /run/secrets/gebos-env (sops-nix).
|
||||
};
|
||||
|
||||
# Caddy fronts TLS for `ingest.ge-bos.de` and forwards to HiveMQ.
|
||||
# Caddy fronts TLS for `ingest.gebos.online` and forwards to HiveMQ.
|
||||
services.gebos.caddy = {
|
||||
enable = true;
|
||||
sites = {
|
||||
"ingest.ge-bos.de" = { tcpProxy = "127.0.0.1:8883"; };
|
||||
"ingest.gebos.online" = { tcpProxy = "127.0.0.1:8883"; };
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ in
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.caddy = {
|
||||
enable = true;
|
||||
email = "ops@ge-bos.de"; # TODO: confirm ACME contact
|
||||
email = "ops@gebos.online"; # TODO: confirm ACME contact
|
||||
extraConfig = lib.concatStringsSep "\n"
|
||||
(lib.mapAttrsToList siteBlock cfg.sites);
|
||||
};
|
||||
|
||||
@@ -16,7 +16,7 @@ services:
|
||||
image: kong:2.8.1
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "127.0.0.1:8000:8000/tcp" # Caddy proxies api.ge-bos.de here
|
||||
- "127.0.0.1:8000:8000/tcp" # Caddy proxies api.gebos.online here
|
||||
environment:
|
||||
KONG_DATABASE: "off"
|
||||
KONG_DECLARATIVE_CONFIG: /home/kong/kong.yml
|
||||
@@ -29,10 +29,10 @@ services:
|
||||
environment:
|
||||
GOTRUE_DB_DRIVER: postgres
|
||||
GOTRUE_DB_DATABASE_URL: postgres://supabase_auth_admin:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}
|
||||
GOTRUE_SITE_URL: https://app.ge-bos.de
|
||||
GOTRUE_SITE_URL: https://app.gebos.online
|
||||
GOTRUE_JWT_SECRET: ${JWT_SECRET}
|
||||
GOTRUE_JWT_EXP: "3600"
|
||||
API_EXTERNAL_URL: https://api.ge-bos.de
|
||||
API_EXTERNAL_URL: https://api.gebos.online
|
||||
|
||||
rest:
|
||||
image: postgrest/postgrest:v12.0.2
|
||||
@@ -52,7 +52,7 @@ services:
|
||||
STUDIO_PG_META_URL: http://meta:8080
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
DEFAULT_ORGANIZATION_NAME: Gebos
|
||||
SUPABASE_URL: https://api.ge-bos.de
|
||||
SUPABASE_URL: https://api.gebos.online
|
||||
DASHBOARD_USERNAME: gebos
|
||||
DASHBOARD_PASSWORD: ${DASHBOARD_PASSWORD}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user