diff --git a/nixos/CLAUDE.md b/nixos/CLAUDE.md index 5b60abd..826b39c 100644 --- a/nixos/CLAUDE.md +++ b/nixos/CLAUDE.md @@ -76,6 +76,8 @@ Note: `secrets/default.nix` is the agenix recipients file. Agenix looks for `sec | `gitea-runner-ubuntu.service` | Forgejo (Gitea) Actions CI runner, uses docker images | | `forgejo-arion.service` | Forgejo itself, run via Arion/Podman | | `riverside-arion.service` | Riverside app, run via Arion/Docker | +| `podman-coldairnetworks-postgres.service` | PostgreSQL 16 on port 5432 (publicly exposed) | +| `podman-coldairnetworks-pgadmin.service` | pgAdmin 4 on port 5050 (localhost only) | | `podman-navidrome.service` | Navidrome music server on port 4533 | | `podman-nextcloud.service` | Nextcloud/SSH container on port 8087 | | `podman-sync.io.service` | sync.io app on port 9090 | @@ -92,6 +94,36 @@ Note: `secrets/default.nix` is the agenix recipients file. Agenix looks for `sec - `DOCKER_HOST` for the gitea-runner is set to `unix:///run/podman/podman.sock`. - The gitea-runner runs docker images for CI jobs, so the `gitea-runner` user is in the `docker` and `podman` supplementary groups. +## PostgreSQL / pgAdmin (coldairnetworks) + +Two Podman containers defined in `linux.nix` under `virtualisation.oci-containers`. + +| Container | Image | Port | Role | +|---|---|---|---| +| `coldairnetworks-postgres` | `postgres:16` | 5432 (public) | PostgreSQL database | +| `coldairnetworks-pgadmin` | `dpage/pgadmin4` | 5050 (localhost) | pgAdmin 4 web UI | + +### Credential files (not in git — create manually on server) + +| Path | Contents | +|---|---| +| `/var/coldairnetworks-db/postgres.env` | `POSTGRES_USER`, `POSTGRES_PASSWORD`, `POSTGRES_DB` | +| `/var/coldairnetworks-db/pgadmin.env` | `PGADMIN_DEFAULT_EMAIL`, `PGADMIN_DEFAULT_PASSWORD` | +| `/var/coldairnetworks-db/htpasswd` | nginx basic auth — generate with `htpasswd -c /var/coldairnetworks-db/htpasswd ` | + +### Data directories + +| Host path | Purpose | +|---|---| +| `/var/coldairnetworks-db/postgres` | PostgreSQL data (owned root:root) | +| `/var/coldairnetworks-db/pgadmin` | pgAdmin state (owned uid 5050 — the pgAdmin container user) | + +### Access + +- **Web UI**: `https://db.coldairnetworks.com` — nginx basic auth first, then pgAdmin login +- **Direct connection**: `psql -h mainframe.philippeterson.com -U admin -d coldairnetworks` (port 5432 open in firewall) +- **pgAdmin → PostgreSQL**: when adding a server in pgAdmin, use `host.containers.internal` as the hostname (Podman host gateway), port 5432 + ## VNC desktop `podman-vnc-desktop.service` runs a KDE Plasma desktop inside a container, accessible via noVNC at `localhost:6080` (reverse-proxied by nginx). The image is built locally — no registry involved. diff --git a/nixos/firewall.nix b/nixos/firewall.nix index aeb679b..add3da9 100644 --- a/nixos/firewall.nix +++ b/nixos/firewall.nix @@ -11,6 +11,7 @@ 8082 #webdav 8087 #nextcloud + 5432 #coldairnetworks postgres 9090 #sync.io ]; diff --git a/nixos/linux.nix b/nixos/linux.nix index 8bfa761..0491e48 100644 --- a/nixos/linux.nix +++ b/nixos/linux.nix @@ -91,6 +91,16 @@ in { file = ./secrets/openai-api-key.age; owner = "root"; }; + + coldairnetworks-db-postgres = { + file = ./secrets/coldairnetworks-db-postgres.age; + owner = "root"; + }; + + coldairnetworks-db-pgadmin = { + file = ./secrets/coldairnetworks-db-pgadmin.age; + owner = "root"; + }; }; environment.systemPackages = [ @@ -251,6 +261,8 @@ in { "d /var/riverside/files 0755 root root" "d /var/riverside/postgres 0755 root root" "d /var/lib/gitea-runner/ubuntu 0755 gitea-runner gitea-runner" + "d /var/coldairnetworks-db/postgres 0755 root root" + "d /var/coldairnetworks-db/pgadmin 0700 5050 5050" ]; networking.hostName = "${hostname}"; @@ -301,6 +313,22 @@ in { # ports = ["8081:80"]; # }; + "coldairnetworks-postgres" = { + autoStart = true; + image = "postgres:16"; + ports = [ "5432:5432" ]; + volumes = [ "/var/coldairnetworks-db/postgres:/var/lib/postgresql/data" ]; + environmentFiles = [ config.age.secrets.coldairnetworks-db-postgres.path ]; + }; + + "coldairnetworks-pgadmin" = { + autoStart = true; + image = "dpage/pgadmin4"; + ports = [ "127.0.0.1:5050:80" ]; + volumes = [ "/var/coldairnetworks-db/pgadmin:/var/lib/pgadmin" ]; + environmentFiles = [ config.age.secrets.coldairnetworks-db-pgadmin.path ]; + }; + "navidrome" = { autoStart = true; environment = { @@ -465,5 +493,6 @@ in { "acme-selfsigned-webdav.philippeterson.com.service" "acme-selfsigned-pluto.philippeterson.com.service" "acme-selfsigned-paperless.philippeterson.com.service" + "acme-selfsigned-db.coldairnetworks.com.service" ]; } diff --git a/nixos/nginx.nix b/nixos/nginx.nix index 3f5a32a..ac2b5a9 100644 --- a/nixos/nginx.nix +++ b/nixos/nginx.nix @@ -89,6 +89,27 @@ proxyPass = "http://127.0.0.1:3011/"; }; }; + + "db.coldairnetworks.com" = { + enableACME = true; + forceSSL = true; + basicAuthFile = "/var/coldairnetworks-db/htpasswd"; + + locations."/" = { + proxyPass = "http://127.0.0.1:5050/"; + extraConfig = '' + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_read_timeout 86400; + client_max_body_size 100M; + ''; + }; + }; "quineglobal.com" = { enableACME = false; forceSSL = false; diff --git a/nixos/secrets/coldairnetworks-db-pgadmin.age b/nixos/secrets/coldairnetworks-db-pgadmin.age new file mode 100644 index 0000000..351b9f3 --- /dev/null +++ b/nixos/secrets/coldairnetworks-db-pgadmin.age @@ -0,0 +1,5 @@ +age-encryption.org/v1 +-> ssh-ed25519 NFD/vg J4wIMQPFUPgrZ0Nc7jzXP2+iyBWAf3nuGtTEsqo3pF0 +tjt1/xOiC9FIDDMjBSMpCNtqOKCkTmy0lsUl0jk6mLs +--- H8bQNc9LNjqhCUCMPP0hx/L74tFeo4cNf1s/kvn0Vqk +}Yl@Pb,4Su ͻuh0r?Pڐ dwnŴ] u1_bn1*䘂R:W+@'.w#ݔ=%'e48 tnn׬ \ No newline at end of file diff --git a/nixos/secrets/coldairnetworks-db-postgres.age b/nixos/secrets/coldairnetworks-db-postgres.age new file mode 100644 index 0000000..c3e1523 Binary files /dev/null and b/nixos/secrets/coldairnetworks-db-postgres.age differ diff --git a/nixos/secrets/default.nix b/nixos/secrets/default.nix index 5ce3dfc..fc66a9f 100644 --- a/nixos/secrets/default.nix +++ b/nixos/secrets/default.nix @@ -37,4 +37,10 @@ in { # OPENAI_API_KEY "./openai-api-key.age".publicKeys = [mainframePublicKey]; + + # POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB + "./coldairnetworks-db-postgres.age".publicKeys = [mainframePublicKey]; + + # PGADMIN_DEFAULT_EMAIL, PGADMIN_DEFAULT_PASSWORD + "./coldairnetworks-db-pgadmin.age".publicKeys = [mainframePublicKey]; }