英文:
File not found when copied in docker container via multistage build
问题
在通过Docker多阶段构建将文件复制到容器中时,我遇到了一个问题,无法从位于项目根目录的Golang中打开一个简单的文件。然而,我可以在容器中看到该文件。
这是我的Dockerfile:
# Start from a base Go image
FROM golang:1.19 as builder
# Set the working directory inside the container
WORKDIR /app
# Copy the Go module files
COPY go.mod go.sum ./
# Download the dependencies
RUN go mod download
# Copy the rest of the application code
COPY . .
# Copy the promotions.csv into the container
RUN chmod +r /app/promotions.csv
COPY promotions.csv /app/promotions.csv
# Run with disabled cross-compilation
RUN CGO_ENABLED=0 GOOS=linux go build -o app .
# Final stage
FROM alpine:3.18
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder --chown=${USERNAME}:${USERNAME} /app/app .
EXPOSE 1321
CMD ["./app"]
promotions.csv
文件确实存在于容器文件系统中。
然而,main.go
中的 records, err := readCSVFile("promotions.csv")
代码返回一个错误:
open promotions.csv: no such file or directory
更奇怪的是,当我不使用多阶段构建时,一切都正常工作:
# Start from a base Go image
FROM golang:1.19 as builder
# Set the working directory inside the container
WORKDIR /app
# Copy the Go module files
COPY go.mod go.sum ./
# Download the dependencies
RUN go mod download
#COPY promotions.csv ./
# Copy the rest of the application code
COPY . .
# Copy the promotions folder into the container
# Run with disabled cross-compilation
RUN go build -o main
EXPOSE 1321
CMD ["./main"]
这是 docker-compose.yml
文件:
version: '3'
services:
postgres:
image: postgres:15.3-alpine
restart: always
ports:
- 5432:5432
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
POSTGRES_DB: vrstore
app:
build:
context: .
dockerfile: Dockerfile
restart: always
ports:
- 1321:1321
depends_on:
- postgres
volumes:
- .:/app
environment:
DATABASE_HOST: postgres
DATABASE_PORT: 5432
DATABASE_NAME: vrstore
DATABASE_USER: postgres
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:
# Start from a base Go image
FROM golang:1.19 as builder
# Set the working directory inside the container
WORKDIR /app
# Copy the Go module files
COPY go.mod go.sum ./
# Download the dependencies
RUN go mod download
# Copy the rest of the application code
COPY . .
# Copy the promotions.csv into the container
RUN chmod +r /app/promotions.csv
COPY promotions.csv /app/promotions.csv
# Run with disabled cross-compilation
RUN CGO_ENABLED=0 GOOS=linux go build -o app .
# Final stage
FROM alpine:3.18
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder --chown=${USERNAME}:${USERNAME} /app/app .
EXPOSE 1321
CMD ["./app"]
promotions.csv
file exists though in container file system:
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:
# Start from a base Go image
FROM golang:1.19 as builder
# Set the working directory inside the container
WORKDIR /app
# Copy the Go module files
COPY go.mod go.sum ./
# Download the dependencies
RUN go mod download
#COPY promotions.csv ./
# Copy the rest of the application code
COPY . .
# Copy the promotions folder into the container
# Run with disabled cross-compilation
RUN go build -o main
EXPOSE 1321
CMD ["./main"]
Here is the docker-compose.yml
:
version: '3'
services:
postgres:
image: postgres:15.3-alpine
restart: always
ports:
- 5432:5432
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
POSTGRES_DB: vrstore
app:
build:
context: .
dockerfile: Dockerfile
restart: always
ports:
- 1321:1321
depends_on:
- postgres
volumes:
- .:/app
environment:
DATABASE_HOST: postgres
DATABASE_PORT: 5432
DATABASE_NAME: vrstore
DATABASE_USER: postgres
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
目录下:
volumes:
- .:/app
然而,你正在/root
目录下运行二进制文件:
WORKDIR /root/
COPY --from=builder --chown=${USERNAME}:${USERNAME} /app/app .
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
:
volumes:
- .:/app
However you are running the binary from /root
:
WORKDIR /root/
COPY --from=builder --chown=${USERNAME}:${USERNAME} /app/app .
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论