目的

抹平不同平台的系统差异,统一开发环境为 ubuntu:24.04,让团队内全部成员拥有完全相同的配置与开发体验。

顺便吐槽一下,macOS 并不像很多人吹得那么好用,虽然是 *nix ,但实际命令行使用体验还是跟 Linux 有区别,为了解决这个问题还要特意下个 homebrew 来装 GNU 套件。相比之下,虽然原生 Windows 上的开发体验很烂,但 WSL 是完完全全的 Linux ,配合 Terminal 和 VS Code ,反而比 macOS 要趁手得多。

问题

Dev Container 有两种方式挂载,一种是 bind,一种是 volume

  1. 通过 volume 的方式挂载时,VS Code 不会自动将项目文件拷贝到里面去,需要用 postCreateCommand 执行 Shell 脚本把整个项目仓库代码拉取到命名 volume 中去。这样会带来的问题是,容器内外有两套毫不相干的项目文件,修改互不影响,一般来说,一切修改只能发生在容器内,而本地的项目拷贝只用来做入口,实际上有用的只有 .devcontainer 目录下的内容而已。
  2. 通过 bind 的方式挂载时,VS Code 将本地文件映射到容器中去,容器内外共享文件,修改也是同步且双向可见的。然而这个方法在 WSL 下会有文件权限问题。

macOS 下,容器内的文件继承了容器内 dev 用户与组的权限,项目根目录下的 .git 也可正常使用。 而在 WSL 下,文件未能正确继承容器用户 dev 的权限,而是 ubuntu 的,这就需要额外在 postCreateCommand 执行 Shell 脚本,通过 sudo chown -R "$USERNAME":"$USERNAME" ~ 修改用户目录下所有文件权限为 dev:dev。这能解决 WSL 的问题,但又带来了新的问题,同样的命令在 macOS 下会报错:

chown: changing ownership of '/home/dev/project/.git/objects/0d/6fb98ba513f068f7a1839e4e92c0fe482f256a': Permission denied

尝试过判断宿主机操作系统类型,并通过 ${localEnv:HOST_OS_TYPE} 传递给 postCreateCommand 的脚本。但没法仅通过 VS Code 与 devcontainer.json 实现,必须事先手动在命令行中添加此环境变量 export HOST_OS_TYPE="$(uname)"

个人是比较偏向 bind 挂载的,感觉 volume 虽然干净,但还要额外拉取代码,同时存在两份,不太优雅。

然而上面的问题不知如何解决,AI 问过无果,所以想来问问是否有更好的做法。

当前配置

devcontainer.json:

  "build": {
    "dockerfile": "Dockerfile",
    "context": "..",
    "args": {
      "USERNAME": "dev"
    }
  },
  "workspaceFolder": "/home/dev/project",
  "workspaceMount": "source=${localWorkspaceFolder},target=/home/dev/project,type=bind,consistency=cached",
  "remoteUser": "dev",
  "containerUser": "dev",
  "containerEnv": {
    "USERNAME": "dev"
  },

Dockerfile:

FROM ubuntu:24.04

ARG USERNAME

RUN groupadd ${USERNAME} \
    && useradd -m -s /bin/bash -g ${USERNAME} ${USERNAME} \
    && usermod -aG sudo ${USERNAME} \
    && mkdir -p /etc/sudoers.d \
    && echo "${USERNAME} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/nopasswd \
    && chmod 0440 /etc/sudoers.d/nopasswd
举报· 208 次点击
登录 注册 站外分享
1 条回复  
Sinksky 小成 13 小时前
使用 WSL 的情况下,直接在 WSL 里面检出代码文件然后 bind ,没遇到权限问题。
返回顶部