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

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

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:
通过多阶段构建在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:

# 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.

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:

确定