code-server 4.143.1 Docker Compose 部署指南

code-server 4.143.1 官方镜像 Compose 部署:卷挂载、PASSWORD/HASHED_PASSWORD、Nginx 反代与 WebSocket、健康检查、升级回滚及只读卷装扩展等排障实测。

code-servercode-server远程开发Node.js2026/10/27

code-server 4.143.1 Docker Compose 部署指南

目标:用 Docker Compose 在一台 Linux 主机上部署 code-server 4.143.1,覆盖官方镜像、卷挂载、密码与 Argon2 哈希、Nginx 反向代理与 WebSocket、健康检查、升级回滚和常见故障。本文全部命令均在 2026-10-27 的实测环境执行,回显照抄;组件背景见《code-server 4.143.1 介绍与选型指南》,裸机安装见《Ubuntu 22.04 安装 code-server 4.143.1 指南》。

一、环境信息

项目实测值
操作系统Ubuntu 22.04.5 LTS(x86_64,Docker 宿主机)
Docker29.9.2(build a82e528)
Docker Composev5.6.1
code-server 镜像codercom/code-server:4.143.1
镜像 ID / 摘要sha256:377b66bec5645510ed52549bb00e648c273edc604d230a3f90fd2b2433afcb97
镜像构建时间2026-10-23T23:07:20Z(与 v4.143.1 发布同日)
镜像大小1,468,260,557 字节(约 1.37 GiB,docker image inspect 的 Size)
镜像运行用户UID 1000(coder),工作目录 /home/coder
镜像入口/usr/bin/entrypoint.sh --bind-addr 0.0.0.0:8080 .
暴露端口8080/tcp
本机端口映射code-server 8131→8080,Nginx 8132→80
演示账号密码 q1w2e3r4(仅实验环境)
自定义网络10.89.57.0/24,code-server 10.89.57.10,Nginx 10.89.57.11
项目名compose 文件写 name: code-server-4.143.1-stack,实际被规范化为 code-server-41431-stack

说明:镜像内的 entrypoint.sh 已默认带 --bind-addr 0.0.0.0:8080,且默认把当前目录 . 当作工作区。生产部署建议在 compose 的 command 中显式写监听地址和项目目录,避免镜像默认值随版本变化。

二、部署架构与前置条件

2.1 架构

浏览器
  │ http://<主机>:8132/codeserver/
  ▼
Nginx 1.27(容器,80)
  │ proxy_pass http://code-server:8080/
  │ Upgrade / Connection / 86400s 长连接
  ▼
code-server 4.143.1(容器,8080)
  ├─ /home/coder/.config/code-server      ← 配置卷
  ├─ /home/coder/.local/share/code-server ← 用户数据/扩展卷
  └─ /home/coder/projects                 ← 代码卷

2.2 前置条件

# Docker 与 Compose 插件
docker --version
docker compose version

# 端口未被占用(本文用 8131/8132)
ss -ltn | grep -E '8131|8132'

# 建目录
mkdir -p /opt/code-server/{data/config,data/local-share,projects,nginx}
cd /opt/code-server

⚠️ 注意:code-server 容器以 UID 1000 运行。宿主目录如果由 root 创建且权限为 755,UID 1000 无法写入配置和扩展目录,首次启动会反复报权限错误。最简单做法是 chown -R 1000:1000 data projects;本文实测环境即按此处理。

三、Compose 文件

3.1 完整示例

/opt/code-server/docker-compose.yml:

name: code-server-4.143.1-stack

services:
  code-server:
    image: codercom/code-server:4.143.1
    container_name: code-server-4.143.1-web
    restart: unless-stopped
    ports:
      - "8131:8080"
    environment:
      HASHED_PASSWORD: "$$argon2id$$v=19$$m=65536,t=3,p=4$$iPb1ZIY2e64aSh7RejIj8w$$7N+uXtqHzON/yuhxSYFJUVT4GLIsolYLmK17hvVHT/E"
      TZ: Asia/Shanghai
    volumes:
      - ./data/config:/home/coder/.config/code-server
      - ./data/local-share:/home/coder/.local/share/code-server
      - ./projects:/home/coder/projects
    command:
      - --bind-addr
      - 0.0.0.0:8080
      - --disable-telemetry
      - --disable-update-check
      - /home/coder/projects
    healthcheck:
      test: ["CMD", "curl", "-fsS", "http://127.0.0.1:8080/healthz"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 15s
    networks:
      code-server-net:
        ipv4_address: 10.89.57.10

  nginx:
    image: nginx:1.27-alpine
    container_name: code-server-4.143.1-nginx
    restart: unless-stopped
    ports:
      - "8132:80"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
    depends_on:
      code-server:
        condition: service_healthy
    networks:
      code-server-net:
        ipv4_address: 10.89.57.11

networks:
  code-server-net:
    name: code-server-4.143.1-net
    ipam:
      config:
        - subnet: 10.89.57.0/24

3.2 项目名实测坑

Compose 的项目名只允许小写字母、数字、连字符和下划线。写 code-server-4.143.1-stack 不会报错,但点号会被去掉:

docker compose config | head -3

实测回显:

name: code-server-41431-stack
services:
  code-server:

容器标签也随之为:

docker inspect code-server-4.143.1-web \
  --format '{{index .Config.Labels "com.docker.compose.project"}} | {{index .Config.Labels "com.docker.compose.service"}}'
# code-server-41431-stack | code-server

如果脚本里按项目名做过滤(docker compose -p code-server-4.143.1-stack ...),请统一使用规范化后的 code-server-41431-stack,或直接把 compose 文件的 name 改成不含点号的写法。

四、镜像与卷挂载

4.1 镜像事实

docker image inspect codercom/code-server:4.143.1

关键字段实测:

Id:          sha256:377b66bec5645510ed52549bb00e648c273edc604d230a3f90fd2b2433afcb97
RepoDigests: [codercom/code-server@sha256:377b66bec564...]
Created:     2026-10-23T23:07:20.202473976Z
Size:        1468260557
User:        1000
ExposedPorts: {"8080/tcp":{}}
Entrypoint:  ["/usr/bin/entrypoint.sh","--bind-addr","0.0.0.0:8080","."]
WorkingDir:  /home/coder
Env:         PATH=... LANG=en_US.UTF-8 ENTRYPOINTD=/entrypoint.d USER=coder

镜像里已经包含 Node.js 运行时、code-server 二进制和 curl,因此健康检查可以直接用 curl,不需要额外装工具。

4.2 三个卷的职责

宿主目录容器路径内容是否必须持久化
./data/config/home/coder/.config/code-serverconfig.yaml(监听、认证、证书)建议
./data/local-share/home/coder/.local/share/code-server扩展、用户设置、工作区状态、日志、IPC socket必须
./projects/home/coder/projects代码项目必须

挂载后的实测目录:

docker compose exec code-server ls -la /home/coder/.local/share/code-server
CachedExtensionVSIXs
CachedProfilesData
Machine
User
code-server-ipc.sock
coder-logs
coder.json
extensions
heartbeat
logs
machineid

其中 coder.json 记录了上次打开的工作区:

{
  "query": {
    "folder": "/home/coder/projects"
  }
}

4.3 卷权限

容器内是 UID 1000,宿主目录属主不是 1000 时会出现:

Error: EACCES: permission denied, open '/home/coder/.config/code-server/config.yaml'

处理:

sudo chown -R 1000:1000 /opt/code-server/data /opt/code-server/projects
# 如使用 SELinux 的发行版,再加 :z 或 :Z 标签

💡 提示:扩展目录 /home/coder/.local/share/code-server/extensions 必须是可写卷。若把它挂成只读(例如为了“锁定扩展版本”),--install-extension 会直接失败,详见第十节。

五、认证配置

5.1 方式一:PASSWORD

最简单,密码以明文出现在 compose 文件、docker inspect 和进程环境中:

environment:
  PASSWORD: "q1w2e3r4"

启动日志会明确标注来源:

[2026-10-27T10:58:27.717Z] info    - Authentication is enabled
[2026-10-27T10:58:27.717Z] info      - Using password from $PASSWORD

5.2 方式二:HASHED_PASSWORD(推荐)

先用 Argon2 生成哈希(官方 FAQ 给的命令):

echo -n 'q1w2e3r4' | npx argon2-cli -e

输出形如:

$argon2i$v=19$m=4096,t=3,p=1$wST5QhBgk2lu1ih4DMuxvg$LS1alrVdIWtvZHwnzCM1DUGg+5DTO3Dt1d5v9XtLws4

本文 compose 使用的是参数更强的 argon2id 哈希(m=65536,t=3,p=4),已实测可用:

$argon2id$v=19$m=65536,t=3,p=4$iPb1ZIY2e64aSh7RejIj8w$7N+uXtqHzON/yuhxSYFJUVT4GLIsolYLmK17hvVHT/E

写入 compose 时必须把每个 $ 写成 $$,否则 Compose 会把它当变量插值:

environment:
  HASHED_PASSWORD: "$$argon2id$$v=19$$m=65536,t=3,p=4$$iPb1ZIY2e64aSh7RejIj8w$$7N+uXtqHzON/yuhxSYFJUVT4GLIsolYLmK17hvVHT/E"

启动后容器内实际值已还原为单个 $:

docker inspect code-server-4.143.1-web --format '{{range .Config.Env}}{{println .}}{{end}}' | grep HASHED
# HASHED_PASSWORD=$argon2id$v=19$m=65536,t=3,p=4$iPb1ZIY2e64aSh7RejIj8w$7N+uXtqHzON/yuhxSYFJUVT4GLIsolYLmK17hvVHT/E

日志回显:

[2026-10-27T10:57:40.222Z] info    - Authentication is enabled
[2026-10-27T10:57:40.222Z] info      - Using password from $HASHED_PASSWORD

5.3 密码来源优先级

实测顺序为 HASHED_PASSWORD > PASSWORD > config.yaml 中的 password。容器内 config.yaml 仍是首次启动生成的随机密码,但登录只认环境变量里的哈希:

docker compose exec code-server cat /home/coder/.config/code-server/config.yaml
bind-addr: 127.0.0.1:8080
auth: password
password: c8eba0ad9683903ec1ac2dd3
cert: false

⚠️ 注意:即使容器以 --bind-addr 0.0.0.0:8080 启动,挂载卷里的 config.yaml 仍显示 127.0.0.1:8080。这是 CLI 覆盖配置文件的结果,不是配置没生效;实际监听以启动日志 HTTP server listening on http://0.0.0.0:8080/ 为准。

六、启动与验证

6.1 启动

cd /opt/code-server
docker compose up -d

首次启动的日志:

docker compose logs code-server | head -10

实测:

[2026-10-27T10:57:40.212Z] info  code-server 4.143.1 22ddf60dbc52f164cff13620ab515086dd08c90a
[2026-10-27T10:57:40.214Z] info  Using user-data-dir /home/coder/.local/share/code-server
[2026-10-27T10:57:40.221Z] info  Using config file /home/coder/.config/code-server/config.yaml
[2026-10-27T10:57:40.222Z] info  HTTP server listening on http://0.0.0.0:8080/
[2026-10-27T10:57:40.222Z] info    - Authentication is enabled
[2026-10-27T10:57:40.222Z] info      - Using password from $HASHED_PASSWORD
[2026-10-27T10:57:40.222Z] info    - Not serving HTTPS
[2026-10-27T10:57:40.222Z] info  Session server listening on /home/coder/.local/share/code-server/code-server-ipc.sock

6.2 状态

docker compose ps

实测:

NAME                        IMAGE                          STATUS                    PORTS
code-server-4.143.1-nginx   nginx:1.27-alpine              Up About an hour          0.0.0.0:8132->80/tcp
code-server-4.143.1-web     codercom/code-server:4.143.1   Up 56 minutes (healthy)   0.0.0.0:8131->8080/tcp

6.3 直连验证

# 未登录访问会 302 到登录页
curl -s -o /dev/null -w "%{http_code} -> %{redirect_url}\n" http://127.0.0.1:8131/
# 302 -> http://127.0.0.1:8131/login

# 错误密码
curl -s -X POST -d "password=wrong" http://127.0.0.1:8131/login | grep -o "Incorrect password"
# Incorrect password

# 正确密码
curl -s -o /dev/null -w "%{http_code} -> %{redirect_url}\n" -X POST -d "password=q1w2e3r4" http://127.0.0.1:8131/login
# 302 -> http://127.0.0.1:8131/

# 健康检查
curl -s http://127.0.0.1:8131/healthz
# {"status":"alive","lastHeartbeat":1793101861287}

6.4 版本

docker compose exec code-server code-server --version
# 4.143.1 22ddf60dbc52f164cff13620ab515086dd08c90a with Code 1.143.1

浏览器打开 http://<主机IP>:8131,输入 q1w2e3r4 即可进入 IDE。

七、Nginx 反向代理与 WebSocket

7.1 为什么必须处理 Upgrade

code-server 的工作台不是纯 HTTP 页面:终端输出、文件变更、扩展宿主通信都走 WebSocket。Nginx 默认按普通 HTTP 转发,不会传递 Upgrade / Connection 头,表现为“登录页能打开、进入工作台一直转圈或提示连接失败”。

7.2 可用配置

/opt/code-server/nginx/nginx.conf(子路径 /codeserver/ 版,已实测):

user  nginx;
worker_processes  auto;
error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;

events { worker_connections 1024; }

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" "$http_user_agent" '
                    'upstream=$upstream_addr';
    access_log /var/log/nginx/access.log main;
    sendfile on;
    keepalive_timeout 65;

    map $http_upgrade $connection_upgrade {
        default upgrade;
        ''      close;
    }

    upstream code_server {
        server code-server:8080;
    }

    server {
        listen 80;
        server_name _;

        location = /codeserver {
            return 301 /codeserver/;
        }

        location /codeserver/ {
            proxy_pass http://code_server/;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_buffering off;
            proxy_read_timeout 86400s;
            proxy_send_timeout 86400s;
        }
    }
}

关键点:

  • proxy_http_version 1.1:WebSocket 握手要求 HTTP/1.1;
  • Upgrade / Connection:把浏览器的升级请求透传给后端;
  • proxy_read_timeout 86400s:code-server 的 --reconnection-grace-time 默认 10800 秒(3 小时),代理超时必须大于它,否则空闲一会儿就被 Nginx 掐断;
  • proxy_buffering off:避免终端输出被缓冲;
  • 子路径反代时,proxy_pass http://code_server/; 末尾的 / 会剥掉 /codeserver/ 前缀,后端仍按根路径处理。

7.3 子路径实测

curl -s -o /dev/null -w "%{http_code} -> %{redirect_url}\n" http://127.0.0.1:8132/codeserver/
# 302 -> http://127.0.0.1:8132/codeserver/login

curl -s -o /dev/null -w "%{http_code} -> %{redirect_url}\n" -X POST -d "password=q1w2e3r4" http://127.0.0.1:8132/codeserver/login
# 302 -> http://127.0.0.1:8132/codeserver/

curl -s http://127.0.0.1:8132/codeserver/healthz
# {"status":"alive","lastHeartbeat":1793101861287}

7.4 WebSocket 101 实测

带登录 Cookie 发起升级请求:

curl -s -c /tmp/cs.cookies -o /dev/null -X POST -d "password=q1w2e3r4" http://127.0.0.1:8131/login
curl -s -i --max-time 3 -b /tmp/cs.cookies \
  -H 'Connection: Upgrade' -H 'Upgrade: websocket' \
  -H 'Sec-WebSocket-Version: 13' \
  -H 'Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==' \
  http://127.0.0.1:8132/codeserver/

实测响应头:

HTTP/1.1 101 Switching Protocols
Server: nginx/1.27.5
Date: Tue, 27 Oct 2026 11:58:21 GMT
Connection: upgrade
Upgrade: websocket
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

Nginx 访问日志同时出现 101 记录:

10.89.57.1 - - [27/Oct/2026:10:52:48 +0000] "GET /codeserver/ HTTP/1.1" 101 0 "-" "curl/8.18.0" upstream=10.89.57.10:8080

💡 说明:直连 8131 与经 Nginx 8132 都实测返回 101,说明 Upgrade 链路正常。如果只有直连是 101、经代理不是,问题一定在代理配置。

7.5 TLS

生产环境不建议把 80 端口直接暴露到公网。两种做法:

  1. Nginx 终止 TLS(推荐):在 server 中加 listen 443 ssl;、ssl_certificate、ssl_certificate_key,并把 80 重定向到 443;
  2. code-server 自己起 HTTPS:在 compose 的 command 中加 --cert(自签)或挂载证书后加 --cert /path/cert --cert-key /path/key,此时 Nginx 到后端也应改成 https:// 并处理证书校验。

无论哪种,登录密码 + 公网 IP 都不等于安全:code-server 内置终端等于一个 Web Shell,至少要有强密码和 TLS。

八、健康检查

compose 中的探针:

healthcheck:
  test: ["CMD", "curl", "-fsS", "http://127.0.0.1:8080/healthz"]
  interval: 30s
  timeout: 5s
  retries: 3
  start_period: 15s

curl -f 只以 HTTP 状态码判定成败,/healthz 返回 200 即视为健康。实测有一个容易误判的细节:

curl -s http://127.0.0.1:8131/healthz
# 刚启动、尚无浏览器会话时:
# {"status":"expired","lastHeartbeat":0}
# 有客户端登录后:
# {"status":"alive","lastHeartbeat":1793101861287}

即 status 可能是 expired,但 HTTP 仍是 200,探针不会判失败。健康检查不要写成“响应体必须包含 alive”,否则会在无人使用的时段误报。

九、升级与回滚

9.1 升级

cd /opt/code-server

# 1. 备份配置、用户数据和项目(至少备份 data 与 projects)
tar -czf backup-$(date +%F).tar.gz data projects

# 2. 改 compose 中的镜像标签,例如 4.143.1 → 4.150.0
#    image: codercom/code-server:4.150.0

# 3. 拉取并重建
docker compose pull code-server
docker compose up -d

# 4. 验证
docker compose ps
docker compose exec code-server code-server --version
curl -s http://127.0.0.1:8131/healthz
docker compose logs --tail 20 code-server

⚠️ 注意:扩展是跟着 VS Code 内核版本走的。跨多个大版本升级前先备份 data/local-share/extensions,升级后如出现扩展宿主反复崩溃,可临时清空扩展目录让 code-server 重新安装。

9.2 回滚

回滚就是把镜像标签改回旧版本,再 up -d。本文实测环境中保留了 4.141.1 镜像,可直接验证:

# 查看旧镜像版本
docker run --rm --entrypoint code-server codercom/code-server:4.141.1 --version
# 4.141.1 279b5702aaff359a8344c9fb8ac0a66d934ff1d6 with Code 1.141.0

回滚操作:

# compose 中改回:image: codercom/code-server:4.141.1
docker compose up -d
docker compose exec code-server code-server --version

如果旧镜像已被清理,可在维护窗口先 docker pull codercom/code-server:4.141.1,再切标签。不要在未备份 data/local-share 的情况下跨大版本降级。

9.3 升级窗口建议

  • 先 docker compose pull 预拉镜像,避免 up -d 时长时间拉取;
  • 用 docker compose up -d --remove-orphans 清理旧编排残留;
  • 升级后重点验证登录、打开工作区、终端、扩展市场四项;
  • 回滚阈值建议:5 分钟内无法登录或工作台无法建立 WebSocket,直接回滚。

十、排障实录

10.1 浏览器长连接异常(P1000 类错误)

现象:登录页正常,进入工作台后提示连接失败/断开;浏览器控制台出现 P1000 一类连接错误码。

先澄清一个事实:在 code-server 4.143.1 的服务端二进制和日志中检索不到 P1000 这个错误码(对镜像内 /usr/lib/code-server/lib 全量检索无匹配)。它更像客户端/代理链路侧的连接错误,而不是 code-server 自己抛出的业务错误。因此按“WebSocket 长连接”排查,而不是去搜服务端日志里的 P1000。

排查顺序:

# 1. 直连后端是否 101
curl -s -i --max-time 3 -b /tmp/cs.cookies \
  -H 'Connection: Upgrade' -H 'Upgrade: websocket' \
  -H 'Sec-WebSocket-Version: 13' \
  -H 'Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==' \
  http://127.0.0.1:8131/

# 2. 经代理是否 101
# 把 URL 换成 http://127.0.0.1:8132/codeserver/ 再执行一次

# 3. 看 Nginx 是否记录了 101
docker compose logs nginx | grep ' 101 '

# 4. 看代理超时是否小于 code-server 的重连宽限
docker compose exec code-server grep -E 'proxy_read_timeout|proxy_send_timeout' /etc/nginx/nginx.conf 2>/dev/null || true

本文实测结论:

  • 直连与经 Nginx 都返回 101 Switching Protocols;
  • Nginx 访问日志有 GET /codeserver/ HTTP/1.1" 101;
  • 代理配置使用 proxy_read_timeout 86400s / proxy_send_timeout 86400s;
  • code-server 启动日志显示 reconnection-grace-time ... 10800s(默认 3 小时)。

常见根因:

根因表现处理
代理没传 Upgrade/Connection登录页正常,工作台转圈按 7.2 补两行头
代理超时 60s(Nginx 默认)空闲一分钟后断线,刷新可恢复调到 86400s,且大于重连宽限
多层代理/负载均衡偶发 101 后立即断开逐层验证 101,确保每层都支持 WS
浏览器插件/企业代理拦截 WS仅部分客户端出现换浏览器/直连对比
反向代理路径未剥前缀静态资源 404,WS 连错路径检查 proxy_pass 末尾 /

⚠️ 注意:如果只是把 proxy_read_timeout 调大,但前面还有一层云负载均衡(默认空闲超时常见 60s/300s),仍会被上层掐断。长连接超时要按链路最短的那一跳来设。

10.2 只读卷安装扩展失败(实测)

场景:把扩展目录挂成只读,试图“锁定扩展版本”,再执行安装。

docker run --rm \
  -v /opt/data/quzuo/tmp/code-server/ro-test:/home/coder/ext-ro:ro \
  --entrypoint code-server codercom/code-server:4.143.1 \
  --install-extension editorconfig.editorconfig --force \
  --extensions-dir /home/coder/ext-ro

实测输出(退出码 1):

Installing extension 'editorconfig.editorconfig'...
Error while installing extension editorconfig.editorconfig: ENOENT: no such file or directory, mkdir '/home/coder/ext-ro/.3802a677-7f4d-4c86-9c83-8a284dbf7a69'
Failed Installing Extensions: editorconfig.editorconfig
[2026-10-27T11:59:22.300Z] error parent:1 Uncaught exception: ENOENT: no such file or directory, mkdir '/home/coder/ext-ro/.3802a677-7f4d-4c86-9c83-8a284dbf7a69'

结论:扩展目录必须是可写卷。只读卷连 VS Code 的临时安装目录都建不出来,报错是 ENOENT 而不是直觉上的 EROFS。正确做法:

  • 扩展目录保持可写;
  • 要固定版本,在初始化脚本里显式 --install-extension publisher.name@x.y.z --force,而不是把目录挂只读;
  • 需要“干净扩展基线”时,备份后清空 extensions 目录,让启动时重新安装。

10.3 healthz 返回 expired 但容器是 healthy

现象:

{"status":"expired","lastHeartbeat":0}

容器状态却是 healthy。原因见第八节:HTTP 200 即可,status 字段表示最近一次客户端心跳是否新鲜,不代表进程死了。不要用响应体文本做探针。

10.4 登录一直 401 / 循环回登录页

按顺序查:

# 1. 密码来源是否正确
docker compose logs code-server | grep -E 'Using password|Authentication'
# 2. 直连能否登录
curl -s -o /dev/null -w "%{http_code}\n" -X POST -d "password=q1w2e3r4" http://127.0.0.1:8131/login
# 3. 代理子路径是否一致
curl -s -o /dev/null -w "%{http_code} -> %{redirect_url}\n" -X POST -d "password=q1w2e3r4" http://127.0.0.1:8132/codeserver/login

常见原因:HASHED_PASSWORD 的 $ 没写成 $$ 导致哈希被 Compose 插值破坏;或子路径代理的 proxy_pass 少了末尾 /,登录 POST 打到错误路径。

10.5 卷权限导致反复重启

docker compose logs --tail 30 code-server

出现 EACCES / permission denied 时:

sudo chown -R 1000:1000 /opt/code-server/data /opt/code-server/projects
docker compose restart code-server

10.6 端口映射了但外网打不开

  • 检查 bind-addr 是否为 0.0.0.0(日志里看 HTTP server listening on);
  • 检查宿主防火墙/安全组是否放行 8131/8132;
  • 检查是否只映射到了 127.0.0.1:8131:8080(这样外网确实访问不到)。

十一、日常运维

# 查看状态与资源
docker compose ps
docker stats --no-stream code-server-4.143.1-web code-server-4.143.1-nginx

# 实时日志
docker compose logs -f --tail 100 code-server

# 重启单个服务
docker compose restart code-server

# 进入容器排查
docker compose exec code-server sh -c 'code-server --version; ss -ltn | grep 8080'

# 备份(低峰期执行)
tar -czf backup-$(date +%F).tar.gz data projects

本文实测资源占用(空闲):

code-server-4.143.1-web   0.01%   114.3MiB / 18.98GiB
code-server-4.143.1-nginx 0.00%   6.207MiB / 18.98GiB

主进程空闲约 55–115MB,取决于是否已有会话和扩展宿主进程;并发用户越多,扩展宿主和终端进程越多,内存按会话增长。

十二、清理

cd /opt/code-server
docker compose down --remove-orphans

# 如需连同数据一起删除(不可恢复,先备份)
# docker compose down -v
# sudo rm -rf /opt/code-server/data /opt/code-server/projects

# 清理镜像(可选)
docker image rm codercom/code-server:4.143.1

⚠️ 注意:docker compose down 默认不会删除宿主目录里的 data 和 projects;它们不是命名卷,而是 bind mount。要彻底清空必须手动删目录。

十三、参考与站内互链