coder: initial import of deployed stack (v2.35.3 compose, docker template, SSOT vault)

This commit is contained in:
Antigravity
2026-08-20 10:50:27 +02:00
commit 1fc121ed7e
19 changed files with 2176 additions and 0 deletions

112
q5vault/index.md Normal file
View File

@@ -0,0 +1,112 @@
---
title: "🏗️ Coder SSOT"
description: "Single source of truth for the self-hosted Coder control plane at https://code.loca.zone, its private postgres, its deliberate auth model, and its operations."
source: "verified deployment on the loca operator host, 2026-08-19; first user, template and first workspace verified 2026-08-20"
reviewed: 2026-08-20
---
# 🏗️ Coder SSOT
Self-hosted Coder control plane (a workspace manager, not an editor) running as a pinned docker compose stack in `/home/loca/dev/coder`, reverse-proxied by Nginx, published loopback-only on `127.0.0.1:52226`, backed by a private postgres container. Coder owns its own identity, so this vhost is deliberately not behind Authelia.
Sibling stack: the single-user browser IDE at `cdsr.loca.zone` is a different deployment and is documented in its own wiki.
## 🚀 Quick start
- open: https://code.loca.zone
- the Coder dashboard runs its own login; there is no `auth.loca.zone` redirect on this host
- wiki (public, no login): https://wiki.code.loca.zone
- stack root: `/home/loca/dev/coder`
- compose: `docker-compose.yml`, image pin `ghcr.io/coder/coder:v2.35.3`, database `postgres:17`
- runtime pin: `config/runtime-version.txt` contains `v2.35.3`
- nginx source of truth: `deploy/code.nginx.conf`, installed as `/etc/nginx/sites-available/code.loca.zone`
- secrets: `.env` (mode 600, git-ignored); it holds `CODER_PG_PASSWORD` and its contents are never read into docs
- admin login: `.admin-credentials` (mode 600, git-ignored); it holds the initial Owner login and a CLI session token, and its contents are never read into docs, a ticket or a chat message
- lifecycle, all of it needs `sudo -n` because `loca` is not in the `docker` group:
- bring up: `cd /home/loca/dev/coder && sudo -n docker compose up -d`
- status: `sudo -n docker compose ps`
- logs: `sudo -n docker compose logs -f coder`
- restart server only: `sudo -n docker compose restart coder`
- stop: `sudo -n docker compose down` (containers go, the postgres volume stays)
- loopback health, from the host shell:
- `curl -sf http://127.0.0.1:52226/healthz` returns `OK`
- `curl -sf http://127.0.0.1:52226/api/v2/buildinfo` returns version `v2.35.3+65e2bfb`, `dashboard_url` `https://code.loca.zone`, telemetry `false`
- port `52226` is the only host-visible socket, bound on `127.0.0.1` inside the `51000-53000` loca.zone app range; container-internal listener is `0.0.0.0:7080`
## 🔐 Auth model in two lines
- Coder authenticates users itself: the browser gets a host-scoped `coder_session_token` cookie, while the `coder` CLI and every workspace agent authenticate with the `Coder-Session-Token` header, so nginx passes all traffic through untouched with no `auth_request`.
- Authelia `default_policy` is `bypass` and no rule names `code.loca.zone`, so nothing gates this vhost; adding a rule would answer every cookie-less agent and CLI request with a 302 to `auth.loca.zone` and break the deployment. Full reasoning: [[operations/auth-model]].
## 👤 Bootstrapped state and the operator's next actions
- setup is done; this is no longer a deployment waiting for a first pass:
- Owner account `loca` (`admin@loca.zone`) exists, is active and holds the Owner role, so `GET /api/v2/users/first` answers `200`
- the default organization is `coder`
- the `docker` template is pushed and its version is active, and one workspace (`ws1`) is running against it; see [[operations/workspaces]]
- how that account was created, for the record: `POST /api/v2/users/first` over loopback, with a randomly generated 32-character password written straight into `/home/loca/dev/coder/.admin-credentials` (mode 600, git-ignored) and never displayed, logged or copied anywhere else
- the operator's actual next actions, in order:
- sign in at https://code.loca.zone and rotate that generated password in Account then Security, so the only stored copy stops being the live credential
- create further workspaces from the `docker` template, respecting the memory gate in [[reference/limits]]
- Coder OSS has no open signup: `POST /api/v2/users` requires authentication, so every later account is admin-created only (`coder users create`, or Users then New user in the dashboard)
## 🧩 Reaching a workspace
- workspace app, path-based because `coder_app` keeps `subdomain = false`: `https://code.loca.zone/@<username>/<workspace>.<agent>/apps/<slug>/`
- the trailing slash matters; the server redirects when it is missing
- web terminal: `https://code.loca.zone/@<username>/<workspace>.<agent>/terminal`
- arbitrary ports from your own machine: `coder port-forward <workspace> --tcp 8000:8080`, or `coder ssh <workspace>` plus normal SSH forwarding
- dashboard port forwarding and `subdomain = true` apps are unavailable here because no wildcard access URL is configured; see [[reference/limits]] and [[operations/workspaces]]
## ⬆️ Upgrade in four steps
```bash
cd /home/loca/dev/coder
# 1. snapshot first: upstream states Coder does not support rollbacks
sudo -n docker compose exec -T database pg_dump -U coder coder | gzip > /home/loca/dev/coder/backup-$(date +%F).sql.gz
# 2. edit the image tag in docker-compose.yml and config/runtime-version.txt
sudo -n docker compose pull coder && sudo -n docker compose up -d coder
curl -sf http://127.0.0.1:52226/api/v2/buildinfo
```
Full procedure, including restore: [[operations/install-upgrade]].
## ✅ Do / don't
- do: pin the image tag and keep `config/runtime-version.txt` in step with `docker-compose.yml`
- do: keep postgres private; it publishes no host port and is reachable only over the compose network
- do: record `free -m` before and after every workspace build; this host runs about ten co-tenant stacks and the gate is documented in [[reference/limits]]
- do: leave TLS to nginx; the container speaks plain HTTP on loopback only
- don't: add an Authelia rule for `code.loca.zone`; it would break agents, the CLI and DERP traffic
- don't: pass `/var/run/docker.sock` into a workspace container; the socket stays on the control plane
- don't: create Coder accounts for other people; this is a single-admin deployment with the Owner authoring every template
- don't: put secrets in this repo; `.env` is the only home for `CODER_PG_PASSWORD` and it is git-ignored
- don't: commit, paste or quote `.admin-credentials` anywhere; it stays at mode 600 in a git-ignored path, and its only legitimate use is one interactive sign-in before the password is rotated
## Start here
| Need | Page |
| --- | --- |
| Architecture section hub | [[architecture/index]] |
| Understand the deployed shape | [[architecture/runtime-topology]] |
| Operations section hub | [[operations/index]] |
| Bring up, upgrade, back up | [[operations/install-upgrade]] |
| Understand or change auth | [[operations/auth-model]] |
| Build templates and reach workspaces | [[operations/workspaces]] |
| Re-run the proof checks | [[operations/verification]] |
| Reference section hub | [[reference/index]] |
| Look up a path, port or env var | [[reference/config-paths]] |
| Know what is deliberately off | [[reference/limits]] |
## 📚 Sources
- https://coder.com/docs/install/docker
- https://coder.com/docs/admin/setup
- https://coder.com/docs/admin/networking/port-forwarding
- https://coder.com/docs/install/upgrade
- https://coder.com/docs/admin/users
- https://coder.com/docs/reference/api/users
- https://coder.com/docs/reference/api/authentication
- https://github.com/coder/coder
- https://github.com/coder/coder/blob/main/coderd/workspaceapps/appurl/appurl.go
- https://github.com/coder/coder/blob/main/site/src/modules/apps/apps.ts