0

I have the following Dockerfile

FROM golang as builder
ARG CADDY_HASH=4b4e99bdb2e327d553a5f773f827f624181714af
WORKDIR /root/caddy
RUN wget -qO- github.com/caddyserver/caddy/archive/"$CADDY_HASH".tar.gz | tar zx --strip-components=1
RUN set -e; cd cmd/caddy && CGO_ENABLED=0 go build

FROM scratch

COPY --from=builder /root/caddy/cmd/caddy/caddy /

ARG PORT=8000
ENV PORT $PORT
EXPOSE $PORT

CMD /caddy file-server --browse --listen :$PORT

I build and run with this command

DOCKER_BUILDKIT=0 docker build -t caddy-static-docker:latest . && docker run -e PORT=8000 -p 8000:8000 caddy-static-docker:latest

Why this won't work and I receive this error?

docker: Error response from daemon: failed to create shim: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "/bin/sh": stat /bin/sh: no such file or directory: unknown.

Rodrigo
  • 135
  • 4
  • 45
  • 107
  • Also see [Starting container process caused "exec: \"/bin/sh\": stat /bin/sh: no such file or directory": unknown](https://stackoverflow.com/questions/54820846/starting-container-process-caused-exec-bin-sh-stat-bin-sh-no-such-file). – David Maze May 14 '22 at 21:11

2 Answers2

3

Use a alpine image which is a lightweight image to run shell commands and it has /bin/sh loaded in it.

The SCRATCH image is basically empty with nothing inside / folder, thus no executables to execute anything that is given as part of CMD.

Prasad Tamgale
  • 325
  • 1
  • 12
3

Use an entrypoint instead of CMD

ENTRYPOINT ["/caddy"]
CMD ["file-server", "--browse", "--listen", "8080"]

Also note the json syntax (exec form), which leads to the things not run in a subshell.

Unlike the shell form, the exec form does not invoke a command shell. This means that normal shell processing does not happen. For example, CMD [ "echo", "$HOME" ] will not do variable substitution on $HOME. If you want shell processing then either use the shell form or execute a shell directly, for example: CMD [ "sh", "-c", "echo $HOME" ]. When using the exec form and executing a shell directly, as in the case for the shell form, it is the shell that is doing the environment variable expansion, not docker.

source: https://docs.docker.com/engine/reference/builder/#cmd

The shell form prevents any CMD or run command line arguments from being used, but has the disadvantage that your ENTRYPOINT will be started as a subcommand of /bin/sh -c, which does not pass signals. This means that the executable will not be the container’s PID 1 - and will not receive Unix signals - so your executable will not receive a SIGTERM from docker stop .

Source: https://docs.docker.com/engine/reference/builder/#entrypoint

Your PORT will still cause issues. Consider hard coding it.

The Fool
  • 16,715
  • 5
  • 52
  • 86
  • I can not use hardcoded PORT on Cloud Run, it is dynamic – Rodrigo May 14 '22 at 20:00
  • @Rodrigo, I would assume that the port outside, is dynamic. The published port like `--publish :8080`. But the port of your app doesnt have to be dynamic. – The Fool May 14 '22 at 20:04
  • Same error [ERROR] '/bin/sh' is not a recognized subcommand; see 'caddy help' – Rodrigo May 14 '22 at 20:06
  • 1
    @Rodrigo, its not the same error, it already used caddy properly as entrypoint. Otherwise, you would not get *see caddy help*. – The Fool May 14 '22 at 20:07