e81f904afd
Self-hosting ran ghcr.io/insforge/postgres-all, which bakes its configuration
in. The published image's postgresql.conf dates from May and its
shared_preload_libraries omits insforge_pg_utils — the hook that lets
project_admin create policies on tables it does not own — so RLS on managed
tables fails on every self-hosted install, while this repo's own config has
carried the hook, its grant-role GUCs and insforge.internal_schemas for
months. Baked configuration cannot track a moving schema. The compose file now
runs the base image and mounts the three files from the checkout.
Same split, same result, for edge functions: ghcr.io/insforge/deno-runtime is
built in InsForge/deploy-provider, and hashing every historical revision of
functions/server.ts and functions/worker-template.js against the image's
copies matches none of them. It is 92 lines behind on server.ts and 175 on
worker-template.js, and where this repo registers self.onmessage before the
top-level await (d12e69c3b, "fix 504 race") the image still assigns it inline.
The stack now runs the official denoland/deno image with functions/ mounted
from the checkout, read-only and with --no-lock, since Deno otherwise tries to
write deno.lock back into it and the container restart-loops.
With a checkout part of self-hosting rather than an optional convenience:
- deploy/setup.sh sparse-checks out the ten files the stack reads (~700KB over
the network, no build step) and generates JWT_SECRET, ENCRYPTION_KEY,
ROOT_ADMIN_PASSWORD and POSTGRES_PASSWORD at mode 600. Postgres reads that
last one only at cluster init, so it has to be settled before first boot;
it defaulted to "postgres" and was left to a manual checklist item.
Re-running the script after `git merge` is what picks up files a release
adds — a merge lands them in git but not in a sparse working tree. It
refuses to touch a full development clone, where the sparse-checkout would
empty the working tree.
- One .env.example, at the repo root. The copy under deploy/docker-compose/
had drifted: the S3 storage settings went undocumented there for months.
- .env sits beside it, and COMPOSE_FILE inside it points Compose at
deploy/docker-compose/docker-compose.yml, so every command runs from the
checkout root. Compose reads .env, and COMPOSE_FILE within it, from the
directory you are in, while the compose file's relative mounts still resolve
against its own directory. The template ships the development value, which
resolves byte-identically to today's auto-discovery; setup.sh rewrites the
line. Shipping the production value there would have silently repointed
every developer's `docker compose up` at published images.
- Installs predating this layout keep .env beside the compose file, where
Compose ignores it — secrets that no longer reach Postgres read as a lost
database. setup.sh moves it. Those installs have no COMPOSE_PROJECT_NAME,
and Compose derives "docker-compose" for them from the compose file's
directory, the same name they already run under, so their volumes stay
attached.
PGDATA is pinned to the subdirectory postgres-all baked into its own ENV.
Changing it makes Postgres initdb an empty cluster beside the real one, which
reads as total data loss.
Dockerfile.deno did not build: the base image already ships a deno user at uid
1000, so `addgroup -S deno` exits 1. Nothing caught it because the override
only added `build:` to services that already declared `image:`, and Compose
skips building when the image is present — inert for anyone who had pulled it,
broken for anyone who had not.
postgrest's healthcheck is gone, and insforge depends on it with
service_started. On amd64 that image is 24 entries — bin/postgrest and a
certificate directory, no shell — so a CMD-SHELL probe reports unhealthy
forever and `docker compose up -d` ends with "dependency failed to start:
container postgrest-1 is unhealthy". The backend never starts. The same probe
and condition are on main; it went unnoticed because the arm64 image for that
tag is a full Debian build with a shell, so the stack comes up on an Apple
Silicon laptop and fails on the Linux servers people self-host on.
Verified on an amd64 EC2 instance following the guide as written: stack up,
/api/health 200 at 2.2.9, 63 migrations, insforge_pg_utils preloaded, CREATE
POLICY on storage.objects as project_admin, and an edge function created
through the API and invoked end to end.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
17 lines
697 B
Docker
17 lines
697 B
Docker
# The Deno function host, from this repository rather than a published image.
|
|
# ghcr.io/insforge/deno-runtime is built in another repo and its copy of
|
|
# functions/ matches no commit here, so fixes made here never reach it.
|
|
FROM denoland/deno:alpine-2.0.6
|
|
|
|
WORKDIR /app
|
|
|
|
# The base image already ships a deno user at uid 1000 — creating it again fails
|
|
# the build, which is how this file sat broken while nothing rebuilt it.
|
|
COPY --chown=deno:deno functions /app/functions
|
|
|
|
# A fresh named volume inherits the mount point's ownership from the image, so
|
|
# this is what lets the non-root user populate the module cache on first start.
|
|
RUN mkdir -p /deno-dir && chown deno:deno /deno-dir
|
|
|
|
USER deno
|