Roger That
Roger That

Reputation: 21

bash: No such file or directory when running a dockerfile

I'm trying to run a container from a dockerfile and a docker-compose file which look like this -

docker-compose.yml

build:
      context: .
      dockerfile: docker/Dockerfile
      target: go-container
    entrypoint: bash -c "./main"

the Dockerfile looks like this -

ARG GO_VERSION=1.17
FROM golang:$GO_VERSION as go-container
ENV GOPATH /gopath
ENV PATH $GOPATH/bin:$PATH
WORKDIR /gopath/src/project

ADD go.mod go.sum ./
RUN go mod download -x
RUN go build -o main cmd/main.go


FROM scratch as another_container
COPY --from=go-container /gopath/src/project/main .
ENTRYPOINT ["./main"]

On running the docker-compose, I get an error like this -

bash: line 1: ./main: No such file or directory
ERROR: 127

What is happening here? I don't know how to debug it so any help is appreciated!

Upvotes: 2

Views: 1236

Answers (2)

elulcao
elulcao

Reputation: 478

Docker scratch doesn't have binaries such as bash, basically it's an empty context. The FROM scratch as another_container instruction then removes previous layers; in this case ./main file is excluded.

You could use another minimal image, ie FROM busybox as another_container, to execute the ./main binary.

ie:

ARG GO_VERSION=1.17
FROM golang:$GO_VERSION as go-container
ADD go.mod go.sum ./
RUN go mod download -x
RUN go build -o main cmd/main.go
FROM busybox as another_container
COPY --from=go-container ./main /main
ENTRYPOINT ["./main"]

Full example:

docker-compose.yaml

version: "3.9"
services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
      target: go-container
    entrypoint: bash -c "./main"

Dockerfile

ARG GO_VERSION=1.17
FROM golang:$GO_VERSION as go-container
ENV GOPATH /gopath
ENV PATH $GOPATH/bin:$PATH
WORKDIR /gopath/src/project

ADD go.mod go.sum main.go ./
RUN go mod download -x
RUN go build -o main main.go

FROM busybox as another_container
COPY --from=go-container /gopath/src/project/main .

ENTRYPOINT ["./main"]

main.go

package main

import "fmt"

func main() {
    fmt.Println("Created with vim-go")
}

Execute with: docker compose up

docker compose up
[+] Running 2/2
 ⠿ Network delete_default  Created                                                                                                                                                                                                       0.0s
 ⠿ Container delete-web-1  Created                                                                                                                                                                                                       0.0s
Attaching to delete-web-1
delete-web-1  | vim-go
delete-web-1 exited with code 0

Upvotes: 1

Nick ODell
Nick ODell

Reputation: 25454

FROM scratch as another_container

You're using a FROM statement, which replaces the current container with a new container based on an image. In this case, you're doing it FROM scratch, which is a container with nothing in it.

Since you didn't use COPY --from to copy the compiled file from the previous stage, the file ./main is missing, so your application won't work.

See here for a multistage Go build example.

Upvotes: 3

Related Questions