为什么使用 docker compose 构建和镜像失败,但不使用 docker compose 却成功?

Dan*_*Dan 5 docker docker-compose

我正在尝试使用 docker compose 构建图像,但它失败了,但它仅适用于 docker。我读过一些 SO 帖子,说当在 Dockerfile 中找不到文件/文件夹时,会发生失败时引发的错误。使用 docker 构建时构建可以工作,所以我不知道为什么它不能与 docker-compose 一起使用。为什么会发生这种情况?

该项目的结构是这样的:

parent_proj
 |_proj
   |_Dockerfile
 |_docker-compose.yml
Run Code Online (Sandbox Code Playgroud)

这是我的 docker-compose 文件:

version: '3.4'
services:
  integrations:
    build:
      context: .
      dockerfile: proj/Dockerfile
      network: host
    image: int
    ports:
      - "5000:5000"
Run Code Online (Sandbox Code Playgroud)

这是 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"]
Run Code Online (Sandbox Code Playgroud)

当我进入 proj 文件夹时。我可以跑

docker build . -t proj
Run Code Online (Sandbox Code Playgroud)

以上成功,我随后可以运行容器。但是,当我在parent_proj 中并运行时,docker compose build它失败并显示错误消息

无法计算缓存密钥:无法行走 /var/lib/docker/tmp/buildkit-mount316454722/target:lstat /var/lib/docker/tmp/buildkit-mount316454722/target:没有这样的文件或目录

为什么会出现这种情况?如何在不重组项目的情况下使用 docker-compose 成功构建?

谢谢

Dav*_*aze 2

您的 Compose 构建选项和docker build您显示的选项是不同的。成功的命令是(其中-f Dockerfile是默认值):

docker build ./proj   -t proj    # -f Dockerfile
#            context:    image:       dockerfile:
Run Code Online (Sandbox Code Playgroud)

但您的 Compose 设置正在运行

docker build .         -t img     -f proj/Dockerfile
#            context:     image:     dockerfile:
Run Code Online (Sandbox Code Playgroud)

哪一个是正确的?在 Dockerfile 中,您

COPY target/proj-0.0.1-SNAPSHOT.jar /some/container/path
Run Code Online (Sandbox Code Playgroud)

target/...源路径始终相对于构建上下文目录(Composecontext:选项,目录参数docker build),即使它看起来像绝对路径,即使 Dockerfile 位于不同的目录中。如果该target目录是 的子目录,proj那么您需要第一种形式。

build:如果您唯一需要指定的是上下文目录,则可以使用简写 Compose语法,我将在此处使用它。如果您不特别关心图像名称是什么(您没有将其推送到注册表),那么 Compose 可以自行选择一个合理的名称;你不需要指定image:.

version: '3.8'
services:
  integrations:
    build: ./proj
    ports:
      - "5000:5000"
Run Code Online (Sandbox Code Playgroud)