求教 Dev Container 配置问题,以及同时在 WSL & macOS 上使用 Dev Container 的最佳实践

71 天前
superhot  superhot

目的

抹平不同平台的系统差异,统一开发环境为 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
1069 次点击
所在节点   Docker  Docker
5 条回复
Sinksky
Sinksky
71 天前
使用 WSL 的情况下,直接在 WSL 里面检出代码文件然后 bind ,没遇到权限问题。
superhot
superhot
71 天前
@Sinksky 容器内的用户和文件权限是什么呢?我的情况是新建了一个用户,没有使用 `ubuntu:24.04` 提供的默认用户
Sinksky
Sinksky
71 天前
@superhot 目前容器内外都用的 root ,安装 wsl ubuntu 的时候命令行
> ubuntu install --root
Ubuntu 用户默认就是 root
superhot
superhot
71 天前
@Sinksky 这样做确实很方便,但感觉直接使用 root 用户不太好…
YsHaNg
YsHaNg
70 天前
docker run 的时候--user $(id -u):$(id -g)似乎没有遇到问题

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1105180

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX