'Copy file and not dir with the same name in docker 2-stage build

In the following Dockerfile

WORKDIR /app
RUN go build -ldflags "-s -w" -a -installsuffix cgo -o tool-web ./tool-web

...

FROM scratch
COPY --from=build /app/tool-web /app/tool-web

turns out the COPY directive copies the directory tool-web and not the binary.

Is there a way to specify to the COPY that the binary is to be copied?



Solution 1:[1]

Per the go command documentation:

The -o flag forces build to write the resulting executable or object to the named output file or directory, instead of the default behavior described in the last two paragraphs. If the named output is an existing directory or ends with a slash or backslash, then any resulting executables will be written to that directory.

Thus, if you use -o tool-web and ./tool-web/ is an existing directory, your output binary will be written as a file within the tool-web directory. A decent guess is your binary may have been installed as ./tool-web/main.

To fix this, two easy approaches would be:

  1. Figure out the path your binary is installed as, and adjust COPY to use that path as the source
    • COPY --from=build /app/tool-web/main /app/tool-web
  2. Or, change the -o to write to a different filename, and then adjust COPY to use that name as the source
    • -o tool-web-binary
    • COPY --from=build /app/tool-web-binary /app/tool-web

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1