You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解析Docker构建时WORKDIR与主机挂载卷的交互机制

问题

我有一个单仓库(monorepo),对应的docker-compose.yml配置如下:

version: '3'

services:
  alpha:
    build:
      context: .
      dockerfile: projects/alpha/Dockerfile
      target: alpha
    restart: always
    ports:
      - "8080:80"
    volumes:
      - ./projects/alpha:/projects/alpha

对应的Dockerfile内容为:

FROM python:3.11.3-slim as builder

# Make / set a working directory
WORKDIR /projects/alpha

# Install Poetry and system dependencies
RUN apt update && ... (install necessary apt packages)

# Copy pyproject.toml / poetry.lock
COPY projects/alpha/pyproject.toml projects/alpha/poetry.lock* ./

# Poetry install
RUN poetry install --no-interaction --no-ansi

# Copy source
COPY projects/alpha ./

# Add a random file to the directory
RUN touch ./RANDO.md

FROM builder as alpha
CMD gunicorn --reload -w 3 -b 0.0.0.0:80 -k uvicorn.workers.UvicornWorker alpha.asgi:application

当前场景下,gunicorn的--reload参数可在主机修改Python模块时重新加载工作进程,但未挂载主机目录则无法实现该效果。不过我发现:构建阶段通过RUN touch ./RANDO.md创建的RANDO.md文件在容器和主机目录中均不存在;而进入容器后手动执行touch RANDO.md创建的该文件可在容器和主机双向可见。请问Docker构建阶段执行WORKDIR /projects/alpha时,容器内和主机挂载目录实际发生了什么?

回答
  • Docker的构建阶段和容器运行阶段是完全独立的两个流程:
    • 执行构建时(docker build或docker-compose build),根本不会涉及主机目录的挂载。此时WORKDIR /projects/alpha只是在构建的镜像层里创建这个目录(如果不存在),并把后续命令的工作目录切换到这里。你在构建阶段用RUN touch ./RANDO.md创建的文件,只保存在镜像的文件系统层中。
  • 当通过docker-compose up启动容器时,你配置的volumes: - ./projects/alpha:/projects/alpha会用主机的./projects/alpha目录直接覆盖容器内的/projects/alpha目录。这就导致镜像层里原本存在的RANDO.md被主机目录的内容替换掉了——因为主机目录里没有这个文件,所以容器启动后自然看不到它。
  • 你进入容器后手动创建RANDO.md时,这个操作是直接在挂载的主机目录上进行的,所以主机和容器两边都能看到这个文件。

总结一下:构建阶段的操作只作用于镜像,启动容器时挂载的主机目录会覆盖镜像中对应路径的内容,所以构建出来的文件被覆盖消失;手动创建的文件是写在挂载的主机目录里,因此双向可见。

内容的提问来源于stack exchange,提问作者orokusaki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 19:53:10