通过多阶段构建在Docker容器中复制时出现文件未找到的问题

huangapple go评论115阅读模式
英文:

File not found when copied in docker container via multistage build

问题

在通过Docker多阶段构建将文件复制到容器中时,我遇到了一个问题,无法从位于项目根目录的Golang中打开一个简单的文件。然而,我可以在容器中看到该文件。

这是我的Dockerfile:

  1. # Start from a base Go image
  2. FROM golang:1.19 as builder
  3. # Set the working directory inside the container
  4. WORKDIR /app
  5. # Copy the Go module files
  6. COPY go.mod go.sum ./
  7. # Download the dependencies
  8. RUN go mod download
  9. # Copy the rest of the application code
  10. COPY . .
  11. # Copy the promotions.csv into the container
  12. RUN chmod +r /app/promotions.csv
  13. COPY promotions.csv /app/promotions.csv
  14. # Run with disabled cross-compilation
  15. RUN CGO_ENABLED=0 GOOS=linux go build -o app .
  16. # Final stage
  17. FROM alpine:3.18
  18. RUN apk --no-cache add ca-certificates
  19. WORKDIR /root/
  20. COPY --from=builder --chown=${USERNAME}:${USERNAME} /app/app .
  21. EXPOSE 1321
  22. CMD ["./app"]

promotions.csv 文件确实存在于容器文件系统中。

然而,main.go 中的 records, err := readCSVFile("promotions.csv") 代码返回一个错误:

open promotions.csv: no such file or directory

更奇怪的是,当我不使用多阶段构建时,一切都正常工作:

  1. # Start from a base Go image
  2. FROM golang:1.19 as builder
  3. # Set the working directory inside the container
  4. WORKDIR /app
  5. # Copy the Go module files
  6. COPY go.mod go.sum ./
  7. # Download the dependencies
  8. RUN go mod download
  9. #COPY promotions.csv ./
  10. # Copy the rest of the application code
  11. COPY . .
  12. # Copy the promotions folder into the container
  13. # Run with disabled cross-compilation
  14. RUN go build -o main
  15. EXPOSE 1321
  16. CMD ["./main"]

这是 docker-compose.yml 文件:

  1. version: '3'
  2. services:
  3. postgres:
  4. image: postgres:15.3-alpine
  5. restart: always
  6. ports:
  7. - 5432:5432
  8. environment:
  9. POSTGRES_USER: postgres
  10. POSTGRES_PASSWORD: password
  11. POSTGRES_DB: vrstore
  12. app:
  13. build:
  14. context: .
  15. dockerfile: Dockerfile
  16. restart: always
  17. ports:
  18. - 1321:1321
  19. depends_on:
  20. - postgres
  21. volumes:
  22. - .:/app
  23. environment:
  24. DATABASE_HOST: postgres
  25. DATABASE_PORT: 5432
  26. DATABASE_NAME: vrstore
  27. DATABASE_USER: postgres
  28. DATABASE_PASSWORD: password

可能导致第一种情况下出现错误的原因是什么?也许我漏掉了一些明显的东西?谢谢。

英文:

Having a trouble to open a simple file from Golang located in project root when copied in container via Docker multistage build. However I can see the file in container.

Here is my Dockerfile:

  1. # Start from a base Go image
  2. FROM golang:1.19 as builder
  3. # Set the working directory inside the container
  4. WORKDIR /app
  5. # Copy the Go module files
  6. COPY go.mod go.sum ./
  7. # Download the dependencies
  8. RUN go mod download
  9. # Copy the rest of the application code
  10. COPY . .
  11. # Copy the promotions.csv into the container
  12. RUN chmod +r /app/promotions.csv
  13. COPY promotions.csv /app/promotions.csv
  14. # Run with disabled cross-compilation
  15. RUN CGO_ENABLED=0 GOOS=linux go build -o app .
  16. # Final stage
  17. FROM alpine:3.18
  18. RUN apk --no-cache add ca-certificates
  19. WORKDIR /root/
  20. COPY --from=builder --chown=${USERNAME}:${USERNAME} /app/app .
  21. EXPOSE 1321
  22. CMD ["./app"]

promotions.csv file exists though in container file system:
通过多阶段构建在Docker容器中复制时出现文件未找到的问题

However records, err := readCSVFile("promotions.csv") code from main.go returns an error:

> open promotions.csv: no such file or directory

More strangely everything is working fine when I don't use mutistage build:

  1. # Start from a base Go image
  2. FROM golang:1.19 as builder
  3. # Set the working directory inside the container
  4. WORKDIR /app
  5. # Copy the Go module files
  6. COPY go.mod go.sum ./
  7. # Download the dependencies
  8. RUN go mod download
  9. #COPY promotions.csv ./
  10. # Copy the rest of the application code
  11. COPY . .
  12. # Copy the promotions folder into the container
  13. # Run with disabled cross-compilation
  14. RUN go build -o main
  15. EXPOSE 1321
  16. CMD ["./main"]

Here is the docker-compose.yml:

  1. version: '3'
  2. services:
  3. postgres:
  4. image: postgres:15.3-alpine
  5. restart: always
  6. ports:
  7. - 5432:5432
  8. environment:
  9. POSTGRES_USER: postgres
  10. POSTGRES_PASSWORD: password
  11. POSTGRES_DB: vrstore
  12. app:
  13. build:
  14. context: .
  15. dockerfile: Dockerfile
  16. restart: always
  17. ports:
  18. - 1321:1321
  19. depends_on:
  20. - postgres
  21. volumes:
  22. - .:/app
  23. environment:
  24. DATABASE_HOST: postgres
  25. DATABASE_PORT: 5432
  26. DATABASE_NAME: vrstore
  27. DATABASE_USER: postgres
  28. DATABASE_PASSWORD: password

What could possibly be the reason of the error in the first case? Maybe I'm missing something obvious?
Thanks.

答案1

得分: 2

文件在镜像中不存在,因为你没有将它复制到那里。

在容器中,你将文件作为卷挂载到/app目录下:

  1. volumes:
  2. - .:/app

然而,你正在/root目录下运行二进制文件:

  1. WORKDIR /root/
  2. COPY --from=builder --chown=${USERNAME}:${USERNAME} /app/app .
  3. CMD ["./app"]

所以二进制文件正在寻找/root/promotions.csv,但找不到它。你需要切换到/app目录或者使用完整路径打开文件。

英文:

The file does not exist in the image since you don't copy it there.

In the container, you are mounting the files as a volume into /app:

  1. volumes:
  2. - .:/app

However you are running the binary from /root:

  1. WORKDIR /root/
  2. COPY --from=builder --chown=${USERNAME}:${USERNAME} /app/app .
  3. CMD ["./app"]

So the binary is looking for /root/promotions.csv and cannot find it. You would need to change directory to /app or open the file with the fully qualified path.

huangapple
  • 本文由 发表于 2023年5月20日 22:28:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/76295727.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定