10 KiB
title, description, source, reviewed
| title | description | source | reviewed |
|---|---|---|---|
| 🗂️ Paths, ports, env vars | 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. | verified deployment on the loca operator host, 2026-08-19 | 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.
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