使用镜像、Dockerfile 和 Docker Compose
2022 年 12 月 16 日 - @chuxel
在创建开发容器时,您有多种不同的方式来定制环境,例如使用 “Features”(功能) 或 生命周期脚本。但是,如果您熟悉容器,可能更倾向于使用 Dockerfile 或 Docker Compose 来定制环境。本文将引导您了解如何在 Dev Container 规范中使用这些格式。
使用 Dockerfile
为了保持简单,许多 开发容器模板 (Dev Container Templates) 都直接使用容器镜像引用。
{
"image": "mcr.microsoft.com/devcontainers/base:ubuntu"
}
然而,Dockerfile 是扩展镜像、添加额外的原生操作系统软件包或对操作系统镜像进行微调的绝佳方式。您可以复用任何 Dockerfile,但让我们从头开始演示如何创建一个。
首先,在您的 devcontainer.json 旁边添加一个名为 Dockerfile 的文件。例如
FROM mcr.microsoft.com/devcontainers/base:ubuntu
# Install the xz-utils package
RUN apt-get update && apt-get install -y xz-utils
接下来,从 devcontainer.json 中删除 image 属性(如果存在),并改为添加 build 和 dockerfile 属性
{
"build": {
// Path is relative to the devcontainer.json file.
"dockerfile": "Dockerfile"
}
}
就是这样!当您启动开发容器时,Dockerfile 将自动构建,无需额外工作。有关其他相关 devcontainer.json 属性的更多信息,请参阅 Dockerfile 场景参考。
迭代包含开发容器元数据的镜像
更好的是,您可以将 Dockerfile 作为创作可与他人共享的镜像的一部分。您甚至可以直接在镜像中添加开发容器的设置和元数据。这避免了在多个 devcontainer.json 文件中重复配置和设置,并使它们与您的镜像保持同步!
请参阅关于 预构建 (pre-building) 的指南以了解更多信息!
使用 Docker Compose
Docker Compose 是定义多容器开发环境的绝佳方式。与其将数据库或 Redis 等内容添加到 Dockerfile 中,不如为这些服务引用现有的镜像,并将开发容器的内容专注于开发所需的工具和实用程序。
将 Docker Compose 与镜像结合使用
正如 Dockerfile 部分所提到的,为了保持简单,许多 开发容器模板 都使用容器镜像引用。
{
"image": "mcr.microsoft.com/devcontainers/base:ubuntu"
}
让我们在 devcontainer.json 旁边创建一个 docker-compose.yml 文件,引用相同的镜像并包含一个 PostgreSQL 数据库
version: '3.8'
services:
devcontainer:
image: mcr.microsoft.com/devcontainers/base:ubuntu
volumes:
- ../..:/workspaces:cached
network_mode: service:db
command: sleep infinity
db:
image: postgres:latest
restart: unless-stopped
volumes:
- postgres-data:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
POSTGRES_DB: postgres
volumes:
postgres-data:
在此示例中
../..:/workspaces:cached将本地源码树中的工作区文件夹挂载到开发容器中。network_mode: service:db将开发容器置于与数据库相同的网络中,以便它可以通过localhost访问数据库。db部分使用了带有特定设置的 Postgres 镜像。
接下来,让我们配置 devcontainer.json 以使用它。
{
"dockerComposeFile": "docker-compose.yml",
"service": "devcontainer",
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}"
}
在此示例中
service指定了docker-compose.yml文件中的哪个服务是开发容器。dockerComposeFile指定了在哪里可以找到docker-compose.yml文件。workspaceFolder指定了挂载工作区文件夹的位置。这对应于docker-compose.yml文件中../..:/workspaces:cached挂载点下的子文件夹。
就是这样!
在 Docker Compose 中使用 Dockerfile
您还可以结合这些场景,在 Docker Compose 中使用 Dockerfile。这一次,我们将通过用类似的 build 部分替换 image,来更新 docker-compose.yml 以引用 Dockerfile
version: '3.8'
services:
devcontainer:
build:
context: .
dockerfile: Dockerfile
volumes:
- ../..:/workspaces:cached
network_mode: service:db
command: sleep infinity
db:
image: postgres:latest
restart: unless-stopped
volumes:
- postgres-data:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
POSTGRES_DB: postgres
volumes:
postgres-data:
最后,正如在 Dockerfile 示例中一样,您可以使用相同的设置来创建一个可与他人共享的开发容器镜像。您还可以直接在镜像本身中添加开发容器设置和元数据。
请参阅关于 预构建 (pre-building) 的指南以了解更多信息!