为何Docker Compose构建镜像失败,单独执行docker build却成功
问题描述
使用docker compose构建镜像失败,进入Dockerfile所在目录直接执行docker build命令可以正常完成构建,已确认报错类型为构建时引用文件/目录不存在,但无法定位docker compose场景下的异常原因。
项目目录结构
parent_proj |_proj |_Dockerfile |_docker-compose.yml
现有配置
docker-compose.yml 内容
version: '3.4' services: integrations: build: context: . dockerfile: proj/Dockerfile network: host image: int ports: - "5000:5000"
proj/Dockerfile 内容
FROM openjdk:11 USER root #RUN apt-get bash ARG JAR_FILE=target/proj-0.0.1-SNAPSHOT.jar COPY ${JAR_FILE} /app2.jar ENTRYPOINT ["java","-jar", "/app2.jar"]
构建报错信息
failed to compute cache key: failed to walk /var/lib/docker/tmp/buildkit-mount316454722/target: lstat /var/lib/docker/tmp/buildkit-mount316454722/target: no such file or directory
问题根因
Docker构建过程中,所有COPY、ADD指令引用的文件相对路径,永远以构建时指定的context(构建上下文)根目录为基准,和Dockerfile自身存放的路径没有关联。
- 进入
proj目录执行docker build . -t proj时,构建上下文是当前的proj目录,Docker会在proj/target/路径下查找jar包,路径匹配所以构建成功。 - 在
parent_proj目录执行docker compose build时,配置中context: .代表构建上下文是parent_proj根目录,此时Docker会按照Dockerfile里写的target/proj-0.0.1-SNAPSHOT.jar路径,去parent_proj/target/下找文件,但实际target目录存放在parent_proj/proj/target/,路径不匹配直接触发文件不存在的报错。
解决方法(无需调整现有项目目录结构)
两种方案二选一即可:
- 方案1:修改docker-compose.yml的构建上下文配置,将上下文指向proj目录,同时调整Dockerfile路径为相对于新上下文的路径,修改后和直接执行docker build的上下文完全一致,无需改动Dockerfile:
version: '3.4' services: integrations: build: context: ./proj dockerfile: Dockerfile network: host image: int ports: - "5000:5000"
- 方案2:如果需要保留
context: .的配置(比如后续构建时需要引用parent_proj目录下的其他文件),直接修改Dockerfile内的JAR_FILE参数路径,匹配当前构建上下文即可:
ARG JAR_FILE=proj/target/proj-0.0.1-SNAPSHOT.jar
内容的提问来源于stack exchange,提问作者slipperypete
相关产品推荐
相关产品推荐

