I try to build the go app as follow, my main.go file is at cmd/app/main.go.
However, when I try running docker build --no-cache .
and docker run <container_id>
.
It gives me exec ./bin/app: no such file or directory
I've already test that running go build -o ./bin/app ./cmd/app
and ./bin/app
is able to run correctly.
Here is my Dockerfile
# Build phase
FROM golang:1.20 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download && go mod verify
COPY . .
RUN go build -o ./bin/app ./cmd/app
# Production phase
FROM alpine:3.14
WORKDIR /app
COPY --from=builder /app/bin/app ./bin/app
ENTRYPOINT [ "./bin/app" ]
I tried to access into the container docker run -it -t fyno/server/multi /bin/sh
/app # cd bin
/app/bin # ls -la
total 11636
drwxr-xr-x 2 root root 4096 Apr 12 05:04 .
drwxr-xr-x 1 root root 4096 Apr 12 05:04 ..
-rwxr-xr-x 1 root root 11904381 Apr 12 05:04 app
/app/bin # ./app
/bin/sh: ./app: not found
/app/bin #
Thanks.
how to fix the problem?
First, there are some problems with the paths, causing your no such file or directory error.
I wrote a minimal Dockerfile
example and renamed the app
binary which was causing confusion because it was located in an app
directory in your example. I hope it makes more sense now.
Second, after fixing the paths inaccuracies in the Dockerfile
, you run into a more subtle problem, when trying to run the go binary: not found, because the the golang builder image is using Debian GLIBC 2.31-13+deb11u5 2.31 while the runner image is using musl libc (x86_64)
Version 1.2.2.
The easiest fix is to set CGO_ENABLED=0
when building. If you really want to use cgo
to compile, find a builder and a runner images that are compatible in this regard.
Several alternatives and workarounds are provided for a similar question here.
Third, you also mentioned about the .env
file in a comment so I also included in the MVP a simple read-display for an environment variable injected with docker run --env ...
.
.
├── cmd
│ └── main.go
├── Dockerfile
├── go.mod
└── go.sum
Dockerfile:
# Build phase
FROM golang:1.20 AS builder
# Next line is just for debug
RUN ldd --version
WORKDIR /build
COPY go.mod go.sum ./
RUN go mod download && go mod verify
COPY . .
WORKDIR /build/cmd
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o go-binary
# Production phase
FROM alpine:3.14
# Next line is just for debug
RUN ldd; exit 0
WORKDIR /app
COPY --from=builder /build/cmd/go-binary .
ENTRYPOINT [ "/app/go-binary"]
main.go:
package main
import (
"os"
"time"
"github.com/rs/zerolog/log"
)
func main() {
yourVar := os.Getenv("YOUR_VAR")
for {
time.Sleep(time.Second)
log.Info().Msg(yourVar)
}
}
Build and run:
docker build --no-cache -t stack-overflow-go-docker:v1.0 .
docker run --env YOUR_VAR=your-value stack-overflow-go-docker:v1.0
{"level":"info","time":"2023-04-14T21:12:37Z","message":"your-value"}
{"level":"info","time":"2023-04-14T21:12:38Z","message":"your-value"}