devcontainer docker-compose 最佳实践

问题描述 投票:0回答:1

我有一个使用

docker compose
的现有 Django 项目,我正在尝试添加 devcontainer 支持。我基本上都能用,但还有一件事困扰着我。

在我的 docker-compose.yml 文件中,我定义了一个名为

web
的服务。我想扩展为
web
服务创建的 docker 镜像以添加更多开发功能。我已经使用
.devcontainer
文件创建了
devcontainer.json
目录。我在
docker-compose.yml
中还有一个
.devcontainer
文件,它定义了
dev
服务。我在
Dockerfile
中有一个
.devcontainer
,我想从
web
图像扩展。

我遇到的问题是,当 vscode 中的 devcontainer 系统尝试构建容器时,

web
容器不存在,因此构建
dev
容器失败。我必须首先手动构建
web
容器,以便图像存在,然后
dev
容器构建才能工作。

这是我的

.devcontainer/devcontainer.json
文件。

{
    "name": "Existing Docker Compose (Extend)",
    // Update the 'dockerComposeFile' list if you have more compose files or use different names.
    // The .devcontainer/docker-compose.yml file contains any overrides you need/want to make.
    "dockerComposeFile": [
        "../docker-compose.yml",
        "../docker-compose-development.yml",
        "docker-compose.yml"
    ],
    // The 'service' property is the name of the service for the container that VS Code should
    // use. Update this value and .devcontainer/docker-compose.yml to the real service name.
    "service": "dev",
    // The optional 'workspaceFolder' property is the path VS Code should open by default when
    // connected. This is typically a file mount in .devcontainer/docker-compose.yml
    "workspaceFolder": "/workspace",
    // Features to add to the dev container. More info: https://containers.dev/features.
    // "features": {},
    // Use 'forwardPorts' to make a list of ports inside the container available locally.
    // "forwardPorts": [],
    // Uncomment the next line if you want start specific services in your Docker Compose config.
    // "runServices": [],
    // Uncomment the next line if you want to keep your containers running after VS Code shuts down.
    // "shutdownAction": "none",
    // Uncomment the next line to run commands after the container is created.
    // "postCreateCommand": "bash pip install pre-commit"
    // Configure tool-specific properties.
    // "customizations": {},
    // Uncomment to connect as an existing user other than the container default. More info: https://aka.ms/dev-containers-non-root.
    "remoteUser": "vscode",
    "postStartCommand": "git config --global --add safe.directory ${containerWorkspaceFolder} && cd sas_applications && poetry install && cd ..",
    "customizations": {
        "vscode": {
            "extensions": [
                "ms-vscode.azure-repos",
                "vscodevim.vim",
                "ms-python.python",
                "ms-python.isort",
                "ms-python.black-formatter"
            ]
        }
    }
}

和我的

.devcontainer/docker-compose.yml
文件

services:
  # Update this to the name of the service you want to work with in your docker-compose.yml file
  dev:
    # Uncomment if you want to override the service's Dockerfile to one in the .devcontainer
    # folder. Note that the path of the Dockerfile and context is relative to the *primary*
    # docker-compose.yml file (the first in the devcontainer.json "dockerComposeFile"
    # array). The sample below assumes your primary file is in the root of your project.
    #
    build:
      context: .
      dockerfile: .devcontainer/Dockerfile
    # Overrides default command so things don't shut down after the process ends.
    entrypoint: []
    command: /bin/sh -c "while sleep 1000; do :; done"

.devcontainer/Dockerfile

FROM web
ARG UID=1000
ARG GID=1000
RUN apt install -y pipx zsh
RUN groupadd --gid "${GID}" vscode && useradd -u "${UID}" -g "${GID}" -s /usr/bin/zsh -m vscode
USER vscode
RUN sh -c "$(wget -O- https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
RUN sed -i '/plugins=/ s/=.*/=\(git python\)/' ~/.zshrc
RUN pipx install invoke && pipx ensurepath
WORKDIR /workspace/sas_applications
CMD ["sleep", "infinity"]

我研究了多种选择,但无法找到解决方案。我不想在

web
dockerfile 中复制
dev
dockerfile。我也不想让开发人员运行手动
docker-compose build
步骤。

我考虑尝试在定义

dev
服务的基本
docker-compose.yml
文件中定义
web
服务,并利用
profile
功能。但是,我不知道如何告诉 vscode devcontainers 将该配置文件参数添加到构建命令中。

提前致谢。

docker docker-compose vscode-devcontainer devcontainer
1个回答
0
投票

经过更多研究,我找到了一个不错的解决方案。该解决方案利用了 Docker 中的多阶段构建。这个 stackoverflow 的答案给了我线索,让我指明了正确的方向。

第一个更改是向现有 Dockerfile 添加多阶段构建。

FROM python:3.11 as base
# Do the original image build instructions

FROM base as dev
# Do the build steps needed to add any 
#  development tools or configuration

然后,在原始 docker-compose.yml 文件中,将构建目标设置为

base
镜像。

services:
  web:
    build:
     ...
     target: base
    ...

然后,在

.devcontainer/docker-compose.yml
文件中,将构建目标设置为
dev
图像。

services:
  web:
    build:
     ...
     target: dev
    ...

现在,在构建映像时,您只需更改命令行中包含的 docker-compose 文件即可指定要构建的目标。要构建部署,请使用

docker compose -f docker-compose.yml

{
    "name": "Existing Docker Compose (Extend)",
    // Update the 'dockerComposeFile' list if you have more compose files or use different names.
    // The .devcontainer/docker-compose.yml file contains any overrides you need/want to make.
    "dockerComposeFile": [
        "../docker-compose.yml",
        "docker-compose.yml"
    ],
    ...

.devcontainer/devcontainer.json
文件将指定包含两个 docker compose 文件。 vscode 现在将构建
dev
容器,其中包括其他开发工具和配置。

© www.soinside.com 2019 - 2024. All rights reserved.