154 lines
10 KiB
Markdown
154 lines
10 KiB
Markdown
---
|
|
title: "🗂️ Paths, ports, env vars"
|
|
description: "Exhaustive lookup of every file, container, volume, port and CODER_* environment variable in the code.loca.zone deployment, plus the deployed docker-compose.yml verbatim."
|
|
source: "verified deployment on the loca operator host, 2026-08-19"
|
|
reviewed: 2026-08-19
|
|
---
|
|
|
|
# 🗂️ Paths, ports, env vars
|
|
|
|
## 📁 Project files
|
|
|
|
| Path | Purpose | Owner and notes |
|
|
| --- | --- | --- |
|
|
| `/home/loca/dev/coder/` | stack root; compose project name `coder` derives from this directory name | `loca`; run every compose command from here |
|
|
| `/home/loca/dev/coder/docker-compose.yml` | the whole deployment definition: images, pins, ports, env, volumes, memory ceilings | `loca`; edit here, never with `docker run` flags |
|
|
| `/home/loca/dev/coder/.env` | supplies `CODER_PG_PASSWORD` to compose interpolation | `loca`, mode 600, git-ignored; contents are never read into or quoted by any document |
|
|
| `/home/loca/dev/coder/.gitignore` | ignores `.env`, `q5vault/.obsidian/`, and terraform working state under `templates/` | `loca`; keeps the secret, editor state and tfstate out of version control while the provider lockfile stays committed |
|
|
| `/home/loca/dev/coder/config/runtime-version.txt` | plain-text pin, currently `v2.35.3`; the human-readable twin of the image tag | `loca`; changes in the same commit as the tag |
|
|
| `/home/loca/dev/coder/deploy/code.nginx.conf` | source of truth for the four nginx server blocks | `loca`; the installed site file is a copy, so edit here first |
|
|
| `/home/loca/dev/coder/templates/docker/main.tf` | pre-validated docker workspace template; one `coder_app` at `subdomain = false`, persistent `/home/coder` volume, no docker socket in the workspace | `loca`; pushed by the operator with `coder templates push` |
|
|
| `/home/loca/dev/coder/templates/docker/.terraform.lock.hcl` | provider hash lock: `coder/coder` 2.18.0, `kreuzwerker/docker` 4.5.0 | `loca`; generated by the provisioner's own terraform (linux_amd64), committed on purpose |
|
|
| `/home/loca/dev/coder/templates/docker/README.md` | operator runbook for the template, incl. cited upstream sources and the validation performed | `loca` |
|
|
| `/home/loca/dev/coder/q5vault/` | this wiki, the real content vault | `loca`; the wiki grid symlinks into it |
|
|
| `/home/loca/dev/coder/quartz.config.coder.yaml` | Quartz configuration for this wiki: `pageTitle` `Coder SSOT`, `baseUrl` `wiki.code.loca.zone`, footer links to https://code.loca.zone and https://loca.zone | `loca`; derived from the pwiz config with the same plugin set |
|
|
|
|
## 🌐 Nginx, TLS and the wiki grid
|
|
|
|
| Path | Purpose | Owner and notes |
|
|
| --- | --- | --- |
|
|
| `/etc/nginx/sites-available/code.loca.zone` | installed copy of `deploy/code.nginx.conf`; four server blocks (app 443, wiki 443, app 80, wiki 80) | root; `sudo -n nginx -t` before any reload |
|
|
| `/etc/nginx/sites-enabled/code.loca.zone` | symlink activating the site | root |
|
|
| `/etc/letsencrypt/live/code.loca.zone/` | certificate lineage named `code.loca.zone`, covering `code.loca.zone` and `wiki.code.loca.zone`, expiring 2026-11-17; both vhosts read `fullchain.pem` and `privkey.pem` here | root, certbot-managed; HTTP-01 via `/var/www/html` webroot |
|
|
| `/home/loca/dev/wikis/code/content` | symlink to `/home/loca/dev/coder/q5vault` | `loca`; the vault stays in the project, the grid only points at it |
|
|
| `/home/loca/dev/wikis/code/quartz.config.yaml` | symlink to `/home/loca/dev/coder/quartz.config.coder.yaml` | `loca` |
|
|
| `/home/loca/dev/wikis/code/current` | symlink to the published `dist-*` directory and the nginx root for the wiki vhost | produced by `cd /home/loca/dev/wikis && ./build.sh code`; absent until the first build runs |
|
|
| `/home/loca/dev/services/authelia/config/configuration.yml` | shared Authelia access rules; `default_policy: bypass`, and deliberately no rule for `code.loca.zone` or `wiki.code.loca.zone` | root-adjacent shared service; do not add a rule for this stack, see [[operations/auth-model]] |
|
|
|
|
## 📦 Containers, volumes, network
|
|
|
|
| Object | Definition | Notes |
|
|
| --- | --- | --- |
|
|
| container `coder` | service `coder`, image `ghcr.io/coder/coder:v2.35.3`, `restart: unless-stopped`, `mem_limit: 8g` | the control plane; also runs the built-in provisioner |
|
|
| container `coder-database` | service `database`, image `postgres:17`, `restart: unless-stopped`, `mem_limit: 2g` | healthcheck `pg_isready -U coder -d coder`, interval 5s, timeout 5s, 12 retries; publishes no host port |
|
|
| volume `coder_pgdata` | mounted at `/var/lib/postgresql/data` in `coder-database` | all Coder state: users, templates, template versions, workspaces, Terraform state; survives `docker compose down` |
|
|
| volume `coder_home` | mounted at `/home/coder` in `coder` | server-side cache and config root |
|
|
| bind mount `/var/run/docker.sock` | host socket into `coder` at the same path | required by the built-in provisioner; never mounted into a workspace |
|
|
| `group_add: "105"` | host gid of the docker group, added to the `coder` container user | obtained with `getent group docker \| cut -d: -f3`, not guessed |
|
|
| compose network | default project network; `coder` reaches postgres at hostname `database` port 5432 | the only route to the database |
|
|
|
|
Named volumes are declared as `coder_pgdata` and `coder_home`; compose creates named volumes prefixed with the project name, so the docker-side names are `coder_coder_pgdata` and `coder_coder_home`. Address them through `sudo -n docker compose` from the project root.
|
|
|
|
## 🔌 Ports
|
|
|
|
| Port | Bound where | Meaning |
|
|
| --- | --- | --- |
|
|
| `52226` | host `127.0.0.1` only, published as `"127.0.0.1:52226:7080"` | the sole host-visible socket for this stack; nginx proxies to it |
|
|
| `7080` | inside the `coder` container, `0.0.0.0:7080` | the server's own listener; all interfaces of its own namespace, unreachable from outside the publish spec |
|
|
| `5432` | inside the `coder-database` container | reachable only over the compose network |
|
|
| `443` and `80` | host, nginx | `code.loca.zone` and `wiki.code.loca.zone` vhosts |
|
|
|
|
Registry context: `52222` pwiz, `52223` reserved for pwiz, `52224` cdsr (code-server), `52226` code (Coder). All loca.zone application backends bind loopback inside `51000-53000`. Ad-hoc dev servers started from an IDE or workspace terminal must avoid every registered port; check with `ss -ltn` first.
|
|
|
|
## ⚙️ Environment variables actually set
|
|
|
|
| Variable | Value | Why |
|
|
| --- | --- | --- |
|
|
| `CODER_HTTP_ADDRESS` | `0.0.0.0:7080` | binds all interfaces of the container namespace so the host publish can reach it; a container-local loopback bind would be unreachable |
|
|
| `CODER_ACCESS_URL` | `https://code.loca.zone` | the external URL that users and workspace agents use; upstream requires it whenever the built-in tunnel is not used, and it must not be localhost |
|
|
| `CODER_PG_CONNECTION_URL` | `postgresql://coder:${CODER_PG_PASSWORD}@database:5432/coder?sslmode=disable` | external-database mode against the private postgres container; `sslmode=disable` is acceptable only because the traffic never leaves the compose network |
|
|
| `CODER_TELEMETRY_ENABLE` | `"false"` | no usage data leaves the host; confirmed by `telemetry` `false` in `/api/v2/buildinfo` |
|
|
| `POSTGRES_USER` | `coder` | database role |
|
|
| `POSTGRES_PASSWORD` | `${CODER_PG_PASSWORD}` | interpolated from `.env`; the literal value is never documented |
|
|
| `POSTGRES_DB` | `coder` | database name |
|
|
|
|
Deliberately unset: `CODER_WILDCARD_ACCESS_URL` (see [[reference/limits]]), `CODER_TLS_ENABLE` and friends (nginx terminates TLS), every `CODER_OIDC_*` variable (see [[operations/auth-model]]), and `CODER_DISABLE_PATH_APPS` (path-based apps are the only app routing available without a wildcard).
|
|
|
|
## 📄 Deployed docker-compose.yml
|
|
|
|
The password appears only as the `${CODER_PG_PASSWORD}` placeholder, exactly as it does on disk.
|
|
|
|
```yaml
|
|
services:
|
|
database:
|
|
image: postgres:17
|
|
container_name: coder-database
|
|
restart: unless-stopped
|
|
environment:
|
|
POSTGRES_USER: coder
|
|
POSTGRES_PASSWORD: ${CODER_PG_PASSWORD}
|
|
POSTGRES_DB: coder
|
|
volumes:
|
|
- coder_pgdata:/var/lib/postgresql/data
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U coder -d coder"]
|
|
interval: 5s
|
|
timeout: 5s
|
|
retries: 12
|
|
mem_limit: 2g
|
|
|
|
coder:
|
|
image: ghcr.io/coder/coder:v2.35.3
|
|
container_name: coder
|
|
restart: unless-stopped
|
|
depends_on:
|
|
database:
|
|
condition: service_healthy
|
|
ports:
|
|
- "127.0.0.1:52226:7080"
|
|
environment:
|
|
CODER_HTTP_ADDRESS: 0.0.0.0:7080
|
|
CODER_ACCESS_URL: https://code.loca.zone
|
|
CODER_PG_CONNECTION_URL: postgresql://coder:${CODER_PG_PASSWORD}@database:5432/coder?sslmode=disable
|
|
CODER_TELEMETRY_ENABLE: "false"
|
|
# No CODER_WILDCARD_ACCESS_URL. Nested names such as foo.code.loca.zone
|
|
# DO resolve via the *.loca.zone wildcard; the actual blocker is TLS
|
|
# issuance: this lineage covers only code.loca.zone and
|
|
# wiki.code.loca.zone, and a *.code.loca.zone certificate needs DNS-01
|
|
# validation with DNS-provider credentials that are not configured here.
|
|
# Path-based workspace apps and `coder port-forward` are used instead.
|
|
group_add:
|
|
# host gid of /var/run/docker.sock; required so the built-in provisioner
|
|
# can build docker-template workspaces.
|
|
- "105"
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock
|
|
- coder_home:/home/coder
|
|
mem_limit: 8g
|
|
|
|
volumes:
|
|
coder_pgdata:
|
|
coder_home:
|
|
```
|
|
|
|
## 🔗 Endpoints worth bookmarking
|
|
|
|
| URL | Purpose |
|
|
| --- | --- |
|
|
| `http://127.0.0.1:52226/healthz` | loopback liveness, returns `OK` |
|
|
| `http://127.0.0.1:52226/api/v2/buildinfo` | running version, advertised dashboard URL, telemetry flag |
|
|
| `http://127.0.0.1:52226/api/v2/users/first` | `200`, the initial Owner exists; `404` only on a never-bootstrapped deployment |
|
|
| `https://code.loca.zone/` | dashboard, no auth redirect |
|
|
| `https://code.loca.zone/@<user>/<workspace>.<agent>/apps/<slug>/` | path-based workspace app |
|
|
| `https://code.loca.zone/@<user>/<workspace>.<agent>/terminal` | web terminal |
|
|
| `https://wiki.code.loca.zone/` | this wiki, public |
|
|
|
|
## 📚 Sources
|
|
|
|
- https://coder.com/docs/admin/setup
|
|
- https://coder.com/docs/install/docker
|
|
- https://coder.com/docs/reference/api/users
|
|
- https://docs.docker.com/reference/compose-file/volumes/
|
|
- 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
|