Search code examples
dockergodockerfile

go build -o /run-app vs. go build -o run-app


Locally, when I try to build my go application (main.go), I use go build -o run-app -v main.go to produce a run-app executable. If I try to change the command to go build -o /run-app -v main.go, I get the following error message on my Mac:

command-line-arguments: go build command-line-arguments: copying /var/folders/pp/rtf2ttw90bg5k2t1mw_ylcq00000gn/T/go-build1574791546/b001/exe/a.out: open /run-app: read-only file system

I use the following Dockerfile to deploy my app:

ARG GO_VERSION=1

# Specifies a parent image
FROM golang:${GO_VERSION}-bookworm as builder

# Creates an app directory to hold your app’s source code
WORKDIR /usr/src/app

# Copies everything from your root directory into /app
COPY . .

# Installs Go dependencies
RUN go mod download && go mod verify

# Builds your app with optional configuration
RUN CGO_ENABLED=0 go build -o /run-app -v main.go

# Specifies a parent image
FROM debian:bookworm

# Tells Docker which network port your container listens on
EXPOSE 8080

# Specifies the executable command that runs when the container starts
COPY --from=builder /run-app /usr/local/bin/
CMD ["run-app", "serve", "--http=0.0.0.0:8080"]

It works only if I use /run-app in the build command. Otherwise, the COPY command below fails: COPY --from=builder /run-app /usr/local/bin/ - even if I try to adapt it.

I am wondering what's the difference between /run-app and run-app. Does one create a folder? Why does it not work locally?


Solution

  • Neither creates a folder.

    /run-app tries to write the executable to the root path of the filesystem; on a Mac that is read only but in a container, it is not.

    Without a slash, it builds the binary in the current directory.

    If you exclude the slash in the Dockerfile, you'd need COPY --from=builder /usr/src/app/run-app since that's the WORKDIR