feat: Traefik support, optional Let's Encrypt, configurable port bind, hostname-numbered slots, dblink in extensions schema
- Traefik is a first-class ingress controller choice: per-instance Middleware caps uploads at 50 MiB, nginx keeps its proxy-* annotations; picked in setup - Let's Encrypt is optional: off skips the ClusterIssuer and gives each instance a 10-year self-signed certificate instead of a Let's Encrypt one - New port_bind setting: lan (default, LAN IP only), all (LAN + localhost), local (localhost only) - Hostname slots are keyed by the digit in the name (supa4 -> slot 4), so the instance number, ports and hostname stay in step on every machine - The log-retention job installs dblink and its helper into the extensions schema instead of public: in public they break the app's REVOKE ALL ON ALL ROUTINES IN SCHEMA public for the non-superuser postgres role (42501 permission denied for function dblink_connect_u)
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# supaspin
|
||||
|
||||
Version 1.3.4
|
||||
Version 1.6.1
|
||||
|
||||
Create, list, show and delete throwaway [Supabase](https://supabase.com) instances on a
|
||||
single-node [microk8s](https://microk8s.io) server, from a terminal menu.
|
||||
@@ -13,8 +13,8 @@ endangering them. Nothing in it is specific to any one app.
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| Web API | `https://<slot hostname>` (auth, rest, graphql, realtime, storage, functions), with a Let's Encrypt certificate |
|
||||
| Postgres | `<LAN IP>:544N` (instance 1 → 5441, 2 → 5442, …), bound on the LAN address only |
|
||||
| Web API | `https://<slot hostname>` (auth, rest, graphql, realtime, storage, functions); the certificate is from Let's Encrypt when that is enabled, otherwise self-signed |
|
||||
| Postgres | `<LAN IP>:544N` (instance 1 → 5441, 2 → 5442, …); which addresses listen is set by **Port bind** |
|
||||
| Studio (admin UI) | `http://<LAN IP>:300N` (3001, 3002, …), not on the public hostname |
|
||||
| Disk | fixed-size ext4 image files, mounted at boot: **db 2 GB, storage 1 GB, every other volume 256 MB** |
|
||||
| Memory | limits add up to **9 GiB** per instance, requests to 1.875 GiB (table below) |
|
||||
@@ -32,10 +32,14 @@ of instances at once. Numbers are reused: create picks the lowest free one.
|
||||
## Requirements
|
||||
|
||||
- A Debian/Ubuntu server with **microk8s** (or any Kubernetes with `kubectl` and `helm` on the
|
||||
path), with an **ingress-nginx** ingress class and **cert-manager** installed.
|
||||
- DNS `A` records for every hostname slot pointing at the server, and ports 80 and 443 forwarded to
|
||||
it (Let's Encrypt fetches a test file over port 80 to issue each certificate).
|
||||
path), with an ingress controller installed: **ingress-nginx** or **Traefik** (the microk8s
|
||||
`ingress` addon is either, depending on the version).
|
||||
- With **Let's Encrypt** enabled: **cert-manager** installed, DNS `A` records for every hostname
|
||||
slot pointing at the server, and ports 80 and 443 forwarded to it (Let's Encrypt fetches a test
|
||||
file over port 80 to issue each certificate). Without it: no cert-manager, no public DNS — each
|
||||
instance gets a self-signed certificate instead.
|
||||
- Root access on that server. `python3` and `python3-yaml` (the installer adds the latter with `apt`).
|
||||
Self-signed certificates additionally need `openssl` on the server.
|
||||
|
||||
## Install
|
||||
|
||||
@@ -70,17 +74,21 @@ sudo supaspin
|
||||
|---|---|
|
||||
| Storage root | folder that holds every instance's images and `.env` (`<root>/<N>/…`) |
|
||||
| Node name | Kubernetes node the volumes are pinned to (detected) |
|
||||
| Server LAN IP | address the Postgres and Studio ports are bound to (detected) |
|
||||
| Let's Encrypt e-mail | for certificate expiry notices |
|
||||
| Server LAN IP | address shown for the Postgres and Studio ports (detected) |
|
||||
| Port bind | `lan` = LAN IP only (default; keeps Postgres and the login-less Studio off a public interface), `all` = every interface incl. localhost (for a box behind NAT running its own apps), `local` = localhost only |
|
||||
| Ingress class | usually `public` on microk8s |
|
||||
| Hostname slots | comma-separated; the first is instance 1, the second instance 2, … |
|
||||
| Ingress controller | `traefik` or `nginx`; Traefik instances get a Middleware that caps uploads at 50 MiB, nginx gets the equivalent annotations |
|
||||
| Let's Encrypt | `y` fetches a real certificate per hostname (needs public DNS, ports 80/443, cert-manager); `n` gives every instance a self-signed certificate and creates no cert-manager objects |
|
||||
| Let's Encrypt e-mail | for certificate expiry notices (asked only when Let's Encrypt is on) |
|
||||
| Hostname slots | comma-separated; a name with a number in it keys that slot (`supa4.didgibot.com` = slot 4, so instance 4 gets it with ports 5444/3004), a plain name takes its position in the list |
|
||||
| Public SSH host / port / user | only used to print the tunnel command |
|
||||
| Mail settings | default SMTP settings for the auth service (changeable later) |
|
||||
|
||||
Settings live in `/etc/supaspin/config.yaml` (readable by root only). The first run also creates,
|
||||
only if missing: the `supaspin-local-sc` StorageClass, the `supaspin-letsencrypt` ClusterIssuer,
|
||||
the `supaspin-low` PriorityClass and the `supaspin-certs` namespace, and downloads the pinned
|
||||
Supabase Helm chart (0.8.0, Postgres 17.6.1.136) once into `/var/lib/supaspin/charts/`.
|
||||
only if missing: the `supaspin-local-sc` StorageClass, the `supaspin-low` PriorityClass and the
|
||||
`supaspin-certs` namespace; with Let's Encrypt on it also creates the `supaspin-letsencrypt`
|
||||
ClusterIssuer. It then downloads the pinned Supabase Helm chart (0.8.0, Postgres 17.6.1.136) once
|
||||
into `/var/lib/supaspin/charts/`.
|
||||
|
||||
## Using it
|
||||
|
||||
|
||||
Reference in New Issue
Block a user