mirror of
https://github.com/tiennm99/composes.git
synced 2026-10-19 20:14:56 +00:00
feat(code-server): give the workspace its own volume
The workspace moves off the config volume onto code-server-workspace, so wiping editor state and wiping code are separate acts. The image only ever chowns the literal path /config/workspace, and reads DEFAULT_WORKSPACE to pick the folder to open, so a named volume on /workspace would come up root-owned and unwritable. Creating the directory in a local Dockerfile seeds the volume with the right ownership instead.
This commit is contained in:
1 parent
ff9ec68b0b
commit
a63c121075
4 files changed
+62
-5
No files matched your search
@@ -41,6 +41,27 @@ links out to each service. Per-service detail (variables, ports, storage)
|
|||||||
belongs in that service's README, not the root one. Adding a service means
|
belongs in that service's README, not the root one. Adding a service means
|
||||||
adding its README and a row to the root table.
|
adding its README and a row to the root table.
|
||||||
|
|
||||||
|
## Workspace services
|
||||||
|
|
||||||
|
A service someone works *inside* — an editor, a coding agent, anything with a
|
||||||
|
shell — gets exactly two named volumes: one for the container user's home
|
||||||
|
directory, one mounted at `/workspace`. The home volume holds settings,
|
||||||
|
credentials and CLI logins; `/workspace` holds the code. Point whatever
|
||||||
|
variable selects the working directory at `/workspace`.
|
||||||
|
|
||||||
|
`code-server`, `paseo` and `opencode-web` all follow this.
|
||||||
|
A service with no human inside it does not: `openhands` keeps only its state
|
||||||
|
volume, because each agent session gets a container of its own.
|
||||||
|
|
||||||
|
The split is so that wiping one does not take the other. Reinstalling an editor
|
||||||
|
should not cost you a repository, and deleting a repository should not cost you
|
||||||
|
your extensions and logins.
|
||||||
|
|
||||||
|
Check who owns `/workspace` on a fresh volume. Docker creates it `root:root`
|
||||||
|
unless the image ships the directory, and an image that drops to a non-root
|
||||||
|
user will not be able to write there. `code-server` needs an explicit `chown`
|
||||||
|
for this reason; `paseo` and `opencode-web` do not.
|
||||||
|
|
||||||
## Environment variable order
|
## Environment variable order
|
||||||
|
|
||||||
`environment:` entries are ordered by how badly the service needs them — not
|
`environment:` entries are ordered by how badly the service needs them — not
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
FROM lscr.io/linuxserver/code-server:latest
|
||||||
|
|
||||||
|
# Workspace directory, owned by the container user.
|
||||||
|
RUN mkdir -p /workspace && chown 1000:1000 /workspace
|
||||||
+33
-3
@@ -57,6 +57,36 @@ Coolify or Dokploy. See the [root README](../README.md) for why.
|
|||||||
|
|
||||||
## Storage
|
## Storage
|
||||||
|
|
||||||
Everything lives in the `code-server-config` named volume mounted at `/config`;
|
| Volume | Mount | Holds |
|
||||||
the default workspace is `/config/workspace`. Removing the volume wipes your
|
| --- | --- | --- |
|
||||||
files, settings, and extensions.
|
| `code-server-config` | `/config` | Home directory: settings, extensions, shell history, CLI logins |
|
||||||
|
| `code-server-workspace` | `/workspace` | Code you work on |
|
||||||
|
|
||||||
|
Two volumes, the same split [paseo](../paseo/README.md) and
|
||||||
|
[opencode-web](../opencode-web/README.md) use: home in one, the workspace in
|
||||||
|
the other. Code survives a wipe of the editor's state, and the editor's state
|
||||||
|
survives a wipe of the code.
|
||||||
|
|
||||||
|
`DEFAULT_WORKSPACE` points at `/workspace` to match. It only chooses the folder
|
||||||
|
code-server opens; it does not move anything.
|
||||||
|
|
||||||
|
The `Dockerfile` exists only because of that move. The image hard-codes what it
|
||||||
|
hands to the `abc` user — `init-adduser` takes `/app`, `/config` and
|
||||||
|
`/defaults`, `init-code-server` takes `/config/workspace` by literal path — and
|
||||||
|
reads `DEFAULT_WORKSPACE` only to decide which folder to open. A named volume
|
||||||
|
on `/workspace` is therefore never chowned, comes up `root:root`, and the
|
||||||
|
editor cannot write a single file into it.
|
||||||
|
|
||||||
|
Creating the directory in the image fixes it without any runtime step: Docker
|
||||||
|
seeds an empty named volume from the image directory, ownership included, so
|
||||||
|
`/workspace` arrives owned by `abc`. It is the same reason `paseo` needs no
|
||||||
|
fixup — its upstream image ships `/workspace` already owned.
|
||||||
|
|
||||||
|
The alternative was a `chown` script in `/custom-cont-init.d`, the image's own
|
||||||
|
init hook. It was rejected because it needs a bind mount from the repository
|
||||||
|
into the container, and because the hook silently skips any script that has
|
||||||
|
lost its executable bit — a read-only workspace with nothing obvious to blame.
|
||||||
|
Baking `1000:1000` into the image costs the ability to change `PUID` at
|
||||||
|
runtime, which is free here: both services pin it to `1000`.
|
||||||
|
|
||||||
|
Anything outside these two volumes is lost on redeploy.
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
services:
|
services:
|
||||||
code-server:
|
code-server:
|
||||||
image: 'lscr.io/linuxserver/code-server:latest'
|
build: .
|
||||||
hostname: ${SERVICE_HOSTNAME}
|
hostname: ${SERVICE_HOSTNAME}
|
||||||
environment:
|
environment:
|
||||||
- PUID=1000
|
- PUID=1000
|
||||||
@@ -11,7 +11,7 @@ services:
|
|||||||
- INSTALL_PACKAGES=gh|git|glab|unzip|zip
|
- INSTALL_PACKAGES=gh|git|glab|unzip|zip
|
||||||
- NODEJS_MOD_VERSION=24
|
- NODEJS_MOD_VERSION=24
|
||||||
- TZ=Asia/Ho_Chi_Minh
|
- TZ=Asia/Ho_Chi_Minh
|
||||||
- DEFAULT_WORKSPACE=/config/workspace
|
- DEFAULT_WORKSPACE=/workspace
|
||||||
- GIT_AUTHOR_NAME=${GIT_NAME}
|
- GIT_AUTHOR_NAME=${GIT_NAME}
|
||||||
- GIT_AUTHOR_EMAIL=${GIT_EMAIL}
|
- GIT_AUTHOR_EMAIL=${GIT_EMAIL}
|
||||||
- GIT_COMMITTER_NAME=${GIT_NAME}
|
- GIT_COMMITTER_NAME=${GIT_NAME}
|
||||||
@@ -20,6 +20,8 @@ services:
|
|||||||
- PWA_APPNAME=code-server
|
- PWA_APPNAME=code-server
|
||||||
volumes:
|
volumes:
|
||||||
- 'code-server-config:/config'
|
- 'code-server-config:/config'
|
||||||
|
- 'code-server-workspace:/workspace'
|
||||||
- '/var/run/docker.sock:/var/run/docker.sock:ro'
|
- '/var/run/docker.sock:/var/run/docker.sock:ro'
|
||||||
volumes:
|
volumes:
|
||||||
code-server-config:
|
code-server-config:
|
||||||
|
code-server-workspace:
|
||||||
Reference in new issue
Block a user