Updated
CI / check (push) Canceled after 0s
CI / integration-e2e (push) Canceled after 0s
Deploy to production / deploy (push) Canceled after 0s

This commit is contained in:
2026-10-14 23:30:02 +02:00
parent 04145e5985
commit d81a49175b
18 changed files with 867 additions and 716 deletions
+8 -8
View File
@@ -459,17 +459,17 @@ chmod 600 /opt/hackerspace/.env.local
### 10.3 Build and start the app
The repo ships with a Dockerfile that produces a standalone Next.js image, and a docker-compose.yml that runs it. The Dockerfile expects build-time access to the public Supabase URL and anon key (Next.js inlines `NEXT_PUBLIC_*` at build time), so pass them as build args.
The repo ships with a Dockerfile that produces a standalone Next.js image, and a `docker-compose.app.yml` that runs it (app only; `docker-compose.yml` is the all-in-one local stack and is not used here). The Dockerfile expects build-time access to the public Supabase URL and anon key (Next.js inlines `NEXT_PUBLIC_*` at build time), so pass them as build args.
```bash
cd /opt/hackerspace
docker compose build \
docker compose -f docker-compose.app.yml build \
--build-arg NEXT_PUBLIC_SUPABASE_URL=https://supabase.yourdomain.com \
--build-arg NEXT_PUBLIC_SUPABASE_ANON_KEY="<ANON_KEY>" \
--build-arg NEXT_PUBLIC_APP_URL=https://yourdomain.com
docker compose up -d
docker compose logs -f app
docker compose -f docker-compose.app.yml up -d
docker compose -f docker-compose.app.yml logs -f app
```
Wait for `Ready in <ms>`. Then verify locally on the Droplet:
@@ -725,11 +725,11 @@ Test restores at least quarterly on a staging Droplet. A backup you have not res
```bash
cd /opt/hackerspace
git pull origin main
docker compose build \
docker compose -f docker-compose.app.yml build \
--build-arg NEXT_PUBLIC_SUPABASE_URL=https://supabase.yourdomain.com \
--build-arg NEXT_PUBLIC_SUPABASE_ANON_KEY="<ANON_KEY>" \
--build-arg NEXT_PUBLIC_APP_URL=https://yourdomain.com
docker compose up -d --no-deps app
docker compose -f docker-compose.app.yml up -d --no-deps app
docker image prune -f
```
@@ -762,7 +762,7 @@ Read the [release notes](https://github.com/supabase/supabase/releases) before p
```bash
# App
docker compose -f /opt/hackerspace/docker-compose.yml logs -f app
docker compose -f /opt/hackerspace/docker-compose.app.yml logs -f app
# Supabase
cd /opt/supabase/docker
@@ -823,7 +823,7 @@ Before you point real users at this:
Almost always wrong env vars. Confirm `/opt/hackerspace/.env.local` has the four required values and that `NEXT_PUBLIC_SUPABASE_URL` exactly matches the URL you used in `API_EXTERNAL_URL` in the Supabase `.env`.
`docker compose -f /opt/hackerspace/docker-compose.yml logs app | tail -50` will surface the actual error.
`docker compose -f /opt/hackerspace/docker-compose.app.yml logs app | tail -50` will surface the actual error.
### "Invalid API key" from every Supabase call
+18
View File
@@ -4,6 +4,24 @@ Append-only. Newest entries on top. Keep each entry to one screen.
---
## 2026-10-11 (docker-compose = full local stack + secret generator)
Branch `main`, uncommitted.
- `docker-compose.yml` is now the all-in-one local stack (app + Postgres, GoTrue, PostgREST, Realtime, Kong, Studio). It is the former `docker-compose.full.yml`; compose project and network renamed to `hackerspace` / `hackerspace_net`.
- The old app-only file is `docker-compose.app.yml`. `docs/DEPLOY_DO_SELFHOSTED.md` commands updated to pass `-f docker-compose.app.yml`.
- `.env.example` replaced by the former `.env.full.example` plus app secrets (`SECRETS_ENCRYPTION_KEY`, `CRON_SECRET`, email, Sentry, OAuth, `SETUP_*`). `.env.full.example` removed.
- New `scripts/generate-env.sh`: copies `.env.example` to `.env`, fills POSTGRES_PASSWORD, JWT_SECRET, ANON_KEY, SERVICE_ROLE_KEY (HS256 JWTs), SECRET_KEY_BASE, SECRETS_ENCRYPTION_KEY, CRON_SECRET. Asks for confirmation (default N; `--yes` skips). `.env` added to `.gitignore`.
- `deploy/deploy.sh` now passes `-f docker-compose.app.yml` so the CD path keeps deploying the app only.
- Host port for Postgres is now `POSTGRES_HOST_PORT` (was `POSTGRES_PORT`, which the db image also reads as its internal port; setting it to 5433 broke first-boot init). Existing `.env` files need the rename.
- `supabase/db/*.sql` + db `command` fix: the db container must start with the image's own `config_file` and mount the first-boot init SQL, or the `postgres` role is never created (found on first real deploy). Verified on a standalone db container only (roles, passwords, `_realtime`).
- Booted locally (arm64): all services healthy after fixing the realtime healthcheck (needs the anon key header) and the studio healthcheck (listens on its hostname, not localhost). `scripts/schema.sql` alone creates all 52 tables; it records only migrations 014-017 as applied, so `apply-migrations.sh` on a fresh DB fails at 018 (view column rename). Fresh installs: run schema.sql only. Not fixed.
- Single-tenant flags (`NEXT_PUBLIC_SINGLE_TENANT`, `_SITE_NAME`, `_SINGLE_TENANT_SPACE_SLUG`, `_SINGLE_TENANT_OPEN_JOIN`, `_SHOW_MARKETING`) are now Dockerfile build args and compose build args. Before this, the Docker image ignored them (Next inlines `NEXT_PUBLIC_*` at build), so the createSpace guard was never active in containers. Not yet verified with a rebuild.
- New `scripts/setup-space.sh`: runs `scripts/setup.mjs` (same as `pnpm setup`) in a container built from the Dockerfile `deps` stage on `hackerspace_net`, reading `.env`. Host needs only Docker. Applies `scripts/schema.sql` itself when `public.spaces` is missing (fresh volume). Verified `doctor` after `down -v`; provision and create-admin not run.
- Decision for you: the script writes `.env`, not `.env.example`, since `.env.example` is committed. Use `--output .env.example` only if you accept real secrets in a tracked file.
---
## 2026-08-05 (single-tenant mode + setup CLI + security fix)
Shipped **single-tenant deployment mode** so a hackerspace can run its own private instance (own DB, own
+2 -1
View File
@@ -103,7 +103,8 @@ Single-tenant instances deploy exactly like any instance. The moving parts:
- `deploy/deploy.sh` runs the standard release: fetch, install, apply pending migrations, build, restart. It is idempotent, so a redeploy with no new migrations does not touch the database.
- `scripts/apply-migrations.sh` applies any `scripts/0NN_*.sql` not yet recorded in `public._migrations_applied` and records each filename. It does not restart PostgREST; do that separately afterward so PostgREST refreshes its schema cache (`deploy/deploy.sh` does this automatically, or run `docker compose restart rest` when applying migrations by hand).
- `docker-compose.full.yml` brings up the full stack (Supabase plus the app) for a container-based host.
- `scripts/setup-space.sh` creates the space and first admin on the `docker-compose.yml` stack without Node on the host. It takes the same flags as `pnpm setup` (`doctor`, `--yes`, `--admin-email`, and so on) and defaults the space name and slug from `NEXT_PUBLIC_SITE_NAME` and `NEXT_PUBLIC_SINGLE_TENANT_SPACE_SLUG` in `.env`.
- `docker-compose.yml` brings up the full stack (Supabase plus the app) for a container-based host. Run `scripts/generate-env.sh` first to create `.env` with fresh secrets (the app-only file is `docker-compose.app.yml`).
Set every `NEXT_PUBLIC_` value on the host before building, because Next.js inlines them at build time. Run `pnpm setup` once after the first successful deploy (it is a no-op on later deploys). Full procedure: [DEPLOY_DO_SELFHOSTED.md](./DEPLOY_DO_SELFHOSTED.md).