From 88996222a32705cfb7e9dd1f8dbc011e81ab5776 Mon Sep 17 00:00:00 2001 From: navidgh67 Date: Tue, 10 Mar 2026 11:07:36 -0400 Subject: [PATCH] feat: add Geddes Docker image for permanent Postgres+PostgREST deployment - geddes/Dockerfile: extends postgis/postgis image with PostgREST v13.0.6 binary baked in so it survives container restarts automatically - geddes/entrypoint.sh: custom entrypoint that starts Postgres in background, waits for it to be ready, then starts PostgREST in foreground - geddes/postgrest.conf: PostgREST configuration (secrets can be overridden at runtime via PGRST_* Kubernetes Secrets env-vars) - geddes/README.md: step-by-step build, push, and Rancher deploy instructions Problem solved: previously PostgREST was installed manually with nohup inside the running container. Every container restart wiped the installation causing the 502 Bad Gateway error seen in the Azure Function logs since Feb 2026. --- geddes/Dockerfile | 38 +++++++++++++++++ geddes/README.md | 95 +++++++++++++++++++++++++++++++++++++++++++ geddes/postgrest.conf | 19 +++++++++ 3 files changed, 152 insertions(+) create mode 100644 geddes/Dockerfile create mode 100644 geddes/README.md create mode 100644 geddes/postgrest.conf diff --git a/geddes/Dockerfile b/geddes/Dockerfile new file mode 100644 index 0000000..12c13e8 --- /dev/null +++ b/geddes/Dockerfile @@ -0,0 +1,38 @@ +# ─── Birck Digital Twin — Geddes Postgres + PostgREST image ─────────────────── +# +# Extends the official PostGIS image with the PostgREST binary baked in so +# the API layer survives container restarts without manual re-installation. +# +# Build: +# docker build -t geddes-registry.rcac.purdue.edu//dt-postgres-postgrest:v1 . +# +# Push: +# docker push geddes-registry.rcac.purdue.edu//dt-postgres-postgrest:v1 +# ────────────────────────────────────────────────────────────────────────────── + +FROM postgis/postgis:16-3.4 + +ARG POSTGREST_VERSION=v13.0.6 + +# Install PostgREST static binary +RUN apt-get update && \ + apt-get install -y --no-install-recommends wget xz-utils && \ + wget -q "https://github.com/PostgREST/postgrest/releases/download/${POSTGREST_VERSION}/postgrest-${POSTGREST_VERSION}-linux-static-x86-64.tar.xz" \ + -O /tmp/postgrest.tar.xz && \ + tar -xf /tmp/postgrest.tar.xz -C /usr/local/bin/ && \ + chmod +x /usr/local/bin/postgrest && \ + rm /tmp/postgrest.tar.xz && \ + apt-get remove -y wget xz-utils && \ + apt-get autoremove -y && \ + rm -rf /var/lib/apt/lists/* + +# Copy PostgREST configuration (values can be overridden via env-vars at runtime) +COPY postgrest.conf /etc/postgrest/postgrest.conf + +# Copy custom entrypoint that starts both Postgres and PostgREST +COPY entrypoint.sh /usr/local/bin/dt-entrypoint.sh +RUN chmod +x /usr/local/bin/dt-entrypoint.sh + +EXPOSE 5432 3000 + +ENTRYPOINT ["/usr/local/bin/dt-entrypoint.sh"] diff --git a/geddes/README.md b/geddes/README.md new file mode 100644 index 0000000..f3e5e88 --- /dev/null +++ b/geddes/README.md @@ -0,0 +1,95 @@ +# Geddes — Postgres + PostgREST Docker Image + +This folder contains the files needed to build a **permanent, self-healing** +deployment of PostgreSQL (PostGIS) + PostgREST on the Purdue Geddes cluster. + +## Why this exists + +Previously, PostgREST was installed manually inside the running Postgres +container with `apt install` + `nohup postgrest &`. Since Docker containers are +ephemeral, every container restart wiped out the installation, causing the +`502 Bad Gateway` error you see in the Azure Function logs. + +This image bakes PostgREST directly into the Docker image so it starts +automatically on every container restart — no human intervention required. + +--- + +## Files + +| File | Purpose | +|------|---------| +| `Dockerfile` | Extends `postgis/postgis` with the PostgREST binary | +| `postgrest.conf` | Default PostgREST configuration (DB URL, schemas, role, JWT secret) | +| `entrypoint.sh` | Starts Postgres in background → waits → starts PostgREST in foreground | + +--- + +## Usage + +### 1. Build the image + +```bash +cd geddes/ + +docker build \ + -t geddes-registry.rcac.purdue.edu//dt-postgres-postgrest:v1 \ + . +``` + +Replace `` with your Geddes registry namespace (e.g. `nanohub`). + +### 2. Push to Geddes registry + +```bash +docker login geddes-registry.rcac.purdue.edu + +docker push geddes-registry.rcac.purdue.edu//dt-postgres-postgrest:v1 +``` + +### 3. Update the Rancher Deployment + +In Rancher: +1. Go to **Workloads → Deployments → `dt-postgres`** +2. Click **Edit Config** +3. Change the **Container Image** to: + ``` + geddes-registry.rcac.purdue.edu//dt-postgres-postgrest:v1 + ``` +4. Click **Save** + +Kubernetes will roll out the new pod. PostgREST will start automatically every +time the pod restarts from now on. + +--- + +## Overriding secrets at runtime (recommended for production) + +Instead of hardcoding credentials in `postgrest.conf`, set Kubernetes Secrets +and pass them as environment variables. PostgREST reads any `PGRST_*` env-var: + +```yaml +env: + - name: PGRST_DB_URI + valueFrom: + secretKeyRef: + name: dt-postgres-secret + key: db-uri + - name: PGRST_JWT_SECRET + valueFrom: + secretKeyRef: + name: dt-postgres-secret + key: jwt-secret +``` + +--- + +## Ports + +| Port | Service | +|------|---------| +| 5432 | PostgreSQL | +| 3000 | PostgREST HTTP API | + +The existing Geddes Ingress (`dt-nanohub`) already routes external HTTPS +traffic → port 3000, so no Ingress changes are needed. diff --git a/geddes/postgrest.conf b/geddes/postgrest.conf new file mode 100644 index 0000000..613dc4d --- /dev/null +++ b/geddes/postgrest.conf @@ -0,0 +1,19 @@ +# PostgREST configuration for the Birck Digital Twin Geddes deployment. +# +# These values are baked in as defaults. In production you should override the +# sensitive ones (db-uri, jwt-secret) via Kubernetes Secrets injected as +# environment variables (PGRST_DB_URI, PGRST_JWT_SECRET) rather than editing +# this file directly. +# +# Full reference: https://postgrest.org/en/stable/references/configuration.html + +db-uri = "postgres://glance:glance_secret@localhost:5432/logger" +db-schemas = "public" +db-anon-role = "glance_public" +jwt-secret = "test_secret_that_is_at_least_32_characters_long" + +# PostgREST listens on this port; Ingress/nginx will proxy 443 → 3000 +server-port = 3000 + +# Enable schema cache auto-reload via NOTIFY pgrst +db-channel-enabled = true