Files
cdsr/q5vault/architecture/runtime-topology.md

91 lines
4.6 KiB
Markdown

---
title: 🧭 Runtime Topology
description: Request flow, local directory map, auth/cert rationale, process state, and websocket requirements for the cdsr.loca.zone code-server deployment.
source: verified deployment on the loca operator host, 2026-08-19
reviewed: 2026-08-19
---
# 🧭 Runtime Topology
## Request path
```mermaid
flowchart LR
Browser[Browser] --> Nginx443[Nginx 443\nTLS + security headers]
Nginx443 --> Authelia[Authelia auth_request\nauth.loca.zone one_factor]
Authelia --> CodeServer[code-server on 127.0.0.1:52224]
```
- Browser → Nginx `cdsr.loca.zone:443`
- TLS terminates at Nginx
- security headers included for app traffic
- forwards requests to code-server only after auth_request
- Nginx → Authelia
- `authelia_location` and `authelia_authrequest` snippets included
- `auth_request` policy for `cdsr.loca.zone` is `one_factor`
- request allowed only after successful Authelia authentication
- Authelia → code-server
- reverse proxy to `127.0.0.1:52224`
- loopback target: `bind-addr` is not public
- headers forwarded: `Host`, `X-Real-IP`, `X-Forwarded-For`, `X-Forwarded-Proto`
- websocket headers: `proxy_http_version 1.1`, `Upgrade $http_upgrade`, `Connection $connection_upgrade`
- `proxy_read_timeout 86400`
## Local directory map
- `/home/loca/dev/code-server`
- `config/`
- `scripts/`
- `deploy/`
- `data/user/`
- `data/extensions/`
- `tmp/extensions/`
- `q5vault/`
- `/etc/systemd/system/cdsr.service`
- `/etc/nginx/sites-available/cdsr.loca.zone`
- `/etc/letsencrypt/live/cdsr.loca.zone/`
- `/home/loca/dev/wikis/cdsr/{content,quartz.config.yaml,current}`
## Why `auth: none` and `cert: false`
- `bind-addr` is `127.0.0.1:52224`, so code-server never binds a public interface
- `auth: none` is correct because Authelia performs edge auth; enabling code-server auth would add a second credential store, break websocket UX, and duplicate login logic
- `cert: false` is correct because TLS is terminated at Nginx with a Let's Encrypt lineage certificate
- certs are in `/etc/letsencrypt/live/cdsr.loca.zone/` for Nginx TLS termination
- Authelia handles identity at the edge with `auth_request` before requests enter code-server
- this is only safe because code-server is loopback-only
## Process / state facts
- system scope unit: `cdsr.service`
- `User=loca`
- `Group=loca`
- `Restart=always`
- `WorkingDirectory=/home/loca/dev/code-server`
- editor state is project-isolated by explicit config, not by default: `config/config.yaml` sets `user-data-dir: /home/loca/dev/code-server/data/user` and `extensions-dir: /home/loca/dev/code-server/data/extensions`, and the unit passes `--config /home/loca/dev/code-server/config/config.yaml`
- `data/user` and `data/extensions` are therefore inside the project
- `user-data-dir` does not capture everything — see the next section for what lands outside it anyway
- packaged unit `code-server@loca` is deliberately disabled
## State outside the project
The unit sets `Environment=HOME=/home/loca`, so anything that resolves its own path from `$HOME` ignores `user-data-dir` entirely.
| Path | Written by / why | Deployment-owned |
| --- | --- | --- |
| `data/user/` | code-server, from `user-data-dir` in `config/config.yaml` | yes, in-project |
| `data/extensions/` | code-server, from `extensions-dir` in `config/config.yaml` | yes, in-project |
| `/home/loca/.local/share/code-server/heartbeat` | the running server, regardless of `user-data-dir` | yes, but outside the project |
| `/home/loca/.local/share/code-server/coder-logs/` | same server process, default log location | yes, but outside the project |
| `/home/loca/.continue/` | the Continue extension on first activation, resolved from `$HOME` | no — extension-owned, holds its real config and chat history |
| `/home/loca/.claude/`, `/home/loca/.claude.json` | pre-existing operator state shared with the host Claude Code CLI | no — operator-wide, not created by the extension install, never delete as part of cdsr maintenance |
- practical consequence: the deployment is reproducible from the project directory for the editor, extension binaries and editor settings, but extension-owned configuration and chat history are not, so a backup of `/home/loca/dev/code-server` alone is incomplete — `~/.continue` has to be archived alongside it
## Websocket + long-poll requirement
- Nginx must proxy websocket upgrades for terminal, shell, and extension transport:
- `proxy_http_version 1.1`
- `proxy_set_header Upgrade $http_upgrade`
- `proxy_set_header Connection $connection_upgrade`
- keep long sessions with `proxy_read_timeout 86400`