4.6 KiB
4.6 KiB
title, description, source, reviewed
| title | description | source | reviewed |
|---|---|---|---|
| 🧭 Runtime Topology | Request flow, local directory map, auth/cert rationale, process state, and websocket requirements for the cdsr.loca.zone code-server deployment. | verified deployment on the loca operator host, 2026-08-19 | 2026-08-19 |
🧭 Runtime Topology
Request path
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_locationandauthelia_authrequestsnippets includedauth_requestpolicy forcdsr.loca.zoneisone_factor- request allowed only after successful Authelia authentication
- Authelia → code-server
- reverse proxy to
127.0.0.1:52224 - loopback target:
bind-addris 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
- reverse proxy to
Local directory map
/home/loca/dev/code-serverconfig/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-addris127.0.0.1:52224, so code-server never binds a public interfaceauth: noneis correct because Authelia performs edge auth; enabling code-server auth would add a second credential store, break websocket UX, and duplicate login logiccert: falseis 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_requestbefore requests enter code-server - this is only safe because code-server is loopback-only
Process / state facts
- system scope unit:
cdsr.serviceUser=locaGroup=locaRestart=alwaysWorkingDirectory=/home/loca/dev/code-server
- editor state is project-isolated by explicit config, not by default:
config/config.yamlsetsuser-data-dir: /home/loca/dev/code-server/data/userandextensions-dir: /home/loca/dev/code-server/data/extensions, and the unit passes--config /home/loca/dev/code-server/config/config.yamldata/useranddata/extensionsare therefore inside the projectuser-data-dirdoes not capture everything — see the next section for what lands outside it anyway
- packaged unit
code-server@locais 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-serveralone is incomplete —~/.continuehas to be archived alongside it
Websocket + long-poll requirement
- Nginx must proxy websocket upgrades for terminal, shell, and extension transport:
proxy_http_version 1.1proxy_set_header Upgrade $http_upgradeproxy_set_header Connection $connection_upgrade
- keep long sessions with
proxy_read_timeout 86400