初探 Dev Containers
开发容器(Dev Container)是一种为开发者设计的容器化开发环境规范,通过devcontainer.json结构化元数据文件配置开发环境。该规范支持单容器和Docker Compose多容器方案,可实现开发环境与CI/CD流程的统一。开发容器与生产容器的关键区别在于前者包含开发工具而不用于部署。使用VSCode的"远程-容器"扩展,开发者只需Docker和VSCode即
文章目录
Dev Container = 给开发者用的“房间装修说明书”
概览
什么是开发容器(development containers)?
随着在生产环境中对工作负载进行容器化越来越普遍,越来越多的开发者开始在“部署”之外的场景使用容器,包括持续集成、测试自动化,甚至完整功能的编码环境。
不同场景的需求差异很大:从简单的单容器环境,到复杂的、由编排系统管理的多容器搭建。与其尝试再创造一种新的编排格式,“开发容器规范(Development Container Specification,简称 Dev Container Spec)”更倾向于在现有格式之上增加元数据,用于描述常见的、面向开发者的设置、工具和配置。
一种结构化的元数据格式
类似它之前的“语言服务器协议(Language Server Protocol)”,该规范中的第一个格式 devcontainer.json 也是因实际需求而生。它是一种带注释的结构化 JSON(jsonc)元数据格式,工具可以用它来存储在本地或云端的容器化编码环境中进行开发所需的各种配置。
自该规范最初发布以来,开发容器的元数据现在也可以存放在镜像标签(image labels)中,以及以可复用的元数据片段和安装脚本的形式存在,这些被称为 Dev Container Features。我们设想同样的结构化数据也可以嵌入到其他格式中——同时仍然保留统一的对象模型,以便进行一致的处理。
开发与生产的区别
开发容器定义的是一个“在你准备部署之前用于开发应用”的环境。虽然部署容器和开发容器在外观上可能很相似,但你通常不会希望把开发过程中使用的各种工具也打包进用于部署的镜像里。


构建与测试(Build and test)
除了可重复的环境搭建之外,这些开发容器还能提供一致性,从而避免开发者之间以及集中式构建与测试自动化服务中出现与环境相关的问题。开源的 CLI (CLI 是 Command Line Interface(命令行界面) 的缩写)参考实现既可以直接使用,也可以集成到产品体验中,通过结构化元数据来实现这些收益。它目前支持与 Docker Compose 集成,以及一种简化的、无需编排的单容器方案——因此既可以把它们用作编码环境,也可以用于持续集成与测试。
在 devcontainers/ci 中提供了 GitHub Action 和 Azure DevOps Task,可用于在持续集成(CI)构建中运行仓库的开发容器。这使你能够复用本地开发所使用的同一套环境配置,在 CI 中同样完成代码的构建与测试。
可以使用 VSCode 扩展“远程 - 容器”构建开发容器环境,只要有 Docker 和 VSCode,就可以在任何操作系统上构建。

如上图所示,启动开发容器环境后,VSCode 可以访问 Docker 容器并编辑容器内的文件。 此外,VSCode 的配置、扩展以及必要的语言和库的安装信息可以分别存储在 devcontainer.json 和 Dockerfile 文件中。 因此,开发者只需安装 Docker 和 VSCode,并在 VSCode 中打开项目仓库目录即可使用开发环境。
关于 .devcontainer 目录
当按照上述步骤创建环境时,会创建一个名为 .devcontainer 的目录(如下图所示),并且该目录下会自动创建两个文件。

devcontainer.json
此文件主要用于描述 VSCode 设置。您可以将其用于描述您希望在项目中标准化的 VSCode 扩展和设置。
Dockerfile
此文件描述了容器本身的配置。更多详情,请参阅此处。 也可以使用 docker-compose.yml 文件代替 Dockerfile,这样可以提高可读性。
可以试一试 dev container demo
不知道为什么一直加载不出来



devcontainer.json
devcontainer.json 是 开发容器的“说明书”:当你点“在容器中重新打开”时,VS Code 会按这个文件来:
- 用什么镜像(或 Dockerfile)
- 怎么挂载代码
- 装哪些扩展
- 怎么配置编辑器
- 容器需要什么特殊权限
{
"name": "devcontainer",
"build": {
"dockerfile": "Dockerfile",
"args":{
"DOCKER_BUILDKIT":"0"
}
},
"features": {},
"forwardPorts": [],
"customizations": {
"vscode": {
"settings": {
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true,
"python.analysis.extraPaths": [
"./"
],
"terminal.integrated.env.windows": {
"PYTHONPATH": "${workspaceFolder}"
},
"terminal.integrated.env.linux": {
"PYTHONPATH": "${workspaceFolder}"
},
"terminal.integrated.env.osx": {
"PYTHONPATH": "${workspaceFolder}"
},
"[python]": {
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll": "explicit"
}
},
"ruff.organizeImports": true,
"ruff.fixAll": true,
"editor.formatOnSave": true,
"bazel.buildifierExecutable": "/usr/local/bin/buildifier",
"gopls": {
"ui.completion.usePlaceholders": true
},
"go.goroot": "",
"go.useLanguageServer": true,
"go.toolsEnvVars": {
"GOPACKAGESDRIVER": "${workspaceFolder}/tools/go/gopackagesdriver.sh"
},
"terminal.integrated.defaultProfile.linux": "zsh",
"terminal.integrated.profiles.linux": {
"zsh": {
"path": "/bin/zsh"
}
}
},
"extensions": [
"ms-python.python",
"ms-python.vscode-pylance",
"charliermarsh.ruff",
"github.copilot",
"github.copilot-chat",
"42Crunch.vscode-openapi",
"eamodio.gitlens",
"foxundermoon.shell-format",
"ms-vscode-remote.remote-containers",
"ms-vscode-remote.remote-ssh",
"zxh404.vscode-proto3",
"BazelBuild.vscode-bazel",
"golang.go"
]
}
},
"workspaceFolder": "/code",
"workspaceMount": "source=${localWorkspaceFolder},target=/code,type=bind,consistency=cached",
"mounts": [
"source=devcontainer-cache,target=/.cache,type=volume",
"source=${localEnv:HOME}/.bazel_cache,target=/bazel-cache,type=bind,consistency=cached"
],
"initializeCommand": [
".devcontainer/hooks/init_command.sh",
"--env-file",
".devcontainer/.env"
],
"postCreateCommand": [
"/bin/bash",
"-c",
".devcontainer/hooks/post_create_command.sh"
],
"runArgs": [
// Allow fuse based filesystems in the container
"--cap-add=SYS_ADMIN",
"--device=/dev/fuse",
"--privileged",
"--security-opt=label=disable",
"--volume=/dev/fuse:/dev/fuse",
// Docker: --userns=host
// Podman: --userns=keep-id
// "--userns=host",
"--userns=keep-id",
"--env-file=${localWorkspaceFolder}/.devcontainer/.env",
"--volume=${localEnv:HOME}:/root/user_home:rw",
// Active NVIDIA GPU
// "--runtime=nvidia",
"--gpus=all"
]
}
之后我会持续更新,如果喜欢我的文章,请记得一键三连哦,点赞关注收藏,你的每一个赞每一份关注每一次收藏都将是我前进路上的无限动力 !!!↖(▔▽▔)↗感谢支持!
更多推荐




所有评论(0)