Run with Docker
Prefer containers? The server ships as a single image:
podman pull ghcr.io/yinyue123/16code:latest # docker works the sameThe container needs two things from the host, both persistent:
| Host path | Mounted at | Why |
|---|---|---|
/etc/code.yaml | /etc/code.yaml | The config file — see Configuration File |
/var/lib/code | /var/lib/code/data | All data including the HTTPS certificate cache. Not persisting this triggers Let's Encrypt rate limits on every recreate. |
The server inside the container runs as a non-root user (uid 10001), so both paths must be owned by it.
Setup
# 1. config — start from the example and edit (at minimum: tlsDomains, cookieSecure)
sudo curl -fsSL -o /etc/code.yaml \
https://raw.githubusercontent.com/yinyue123/16code/main/deploy/server.example.yaml
sudo $EDITOR /etc/code.yaml
# 2. data dir + ownership for the container user
sudo mkdir -p /var/lib/code
sudo chown 10001:10001 /etc/code.yaml /var/lib/codeRun
podman run -d --name code-server --network host \
--cap-add NET_BIND_SERVICE \
-v /etc/code.yaml:/etc/code.yaml \
-v /var/lib/code:/var/lib/code/data \
--restart always \
ghcr.io/yinyue123/16code:latest--network host— the server binds 80/443 directly; simplest for the ACME challenge and WebSockets.--cap-add NET_BIND_SERVICE— lets the non-root process bind ports below 1024. Not needed if you configure high ports.- Config file mounted read-write (no
:ro) so you can edit it live from inside:
podman exec -it code-server code-server-setupSaving with Ctrl+S reloads the server in place — no container restart.
As a systemd service (Podman quadlet)
Put this in /etc/containers/systemd/code-server.container, then systemctl daemon-reload && systemctl start code-server:
[Unit]
Description=code cloud server
[Container]
Image=ghcr.io/yinyue123/16code:latest
ContainerName=code-server
Network=host
Volume=/etc/code.yaml:/etc/code.yaml
Volume=/var/lib/code:/var/lib/code/data
AddCapability=CAP_NET_BIND_SERVICE
[Service]
Restart=always
[Install]
WantedBy=multi-user.targetBehind an existing reverse proxy
If nginx/Caddy/a tunnel already terminates TLS on this host, keep auto-HTTPS off and put the server on a loopback port instead: in /etc/code.yaml set tlsDomains: [] and listen: "127.0.0.1:5080", drop AddCapability, and point the proxy at 127.0.0.1:5080 (WebSocket pass-through required).
Upgrade
podman pull ghcr.io/yinyue123/16code:latest
podman restart code-server # quadlet: systemctl restart code-serverConfig, data, history, and certificates all live on the host volumes — an image upgrade touches none of them.