dockergodocker-composedocker-multi-stage-build

File not found when copied in docker container via multistage build


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: container directory

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.


Solution

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