why docker does not recognize /bin/sh -c as a valid entrypoint?

I have a simple nginx container trying to run from docker-compose..

version: "3.3"
services:
  nginx:
    image: nginx
    privileged: true
    entrypoint: ["/bin/sh -c"]
    command: ["ls -lha ~"]

but it fails with:

docker-compose up -d
ERROR: for junk_nginx_1  Cannot start service nginx: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "/bin/sh -c": stat /bin/sh -c: no such file or directory: unknown

I thought it was because /bin/sh doesn't exists in the image, but it certainly does. removing the -c gives me the following error:

# this time the container runs, this is in the container logs.
/bin/sh: 0: Can't open ls -lha ~

so /bin/sh does exists within the image. what am I doing wrong?

Upvotes: 2

Views: 2962

Answers (2)

David Maze
David Maze

Reputation: 158908

When you use the array form of Compose command: and entrypoint: (and, similarly, the JSON-array form of Dockerfile CMD, ENTRYPOINT, and RUN), you are responsible for breaking up the input into words. Each item in the array is a word, just as though it was quoted in the shell, and includes any spaces, punctuation, and other characters.

So when you say

entrypoint: ["/bin/sh -c"]

That is one word, not a command and its argument, and you are telling the shell to look for an executable program named sh -c (including space hyphen c as part of the filename) in the /bin directory. Since that's not there, you get an error.

You shouldn't usually need to override entrypoint: in a Compose setup. In your case, the only shell expansion you need is the home directory ~ but that's not well-defined in Docker. You should be able to just write

command: ls -lha /usr/share/nginx/html

or in array form

command: ["ls", "-lha", "/usr/share/nginx/html"]
# (or other YAML syntaxes with fewer quotes or more lines)

or if you really need the sh -c wrapper

command: /bin/sh -c 'ls -lha ~'
command: ["/bin/sh", "-c", "ls -lha ~"]
command:
  - /bin/sh
  - -c
  - >-
      ls -lha ~;
      echo these lines get folded together;
      nginx -g 'daemon off;'

You're using the stock Docker Hub nginx image; also consider whether docker-compose run might be an easier way to run a one-off command

docker-compose run nginx \
  ls -lha /usr/share/nginx/html

If it's your own image, try hard to avoid needing to override ENTRYPOINT. Make CMD be a complete command; if you need an ENTRYPOINT, a shell script that ends with exec "$@" so that it runs the CMD is a typical pattern.

Upvotes: 3

atline
atline

Reputation: 31584

See entrypoint usage:

entrypoint: ["php", "-d", "memory_limit=-1", "vendor/bin/phpunit"]

Also see command usage:

command: ["bundle", "exec", "thin", "-p", "3000"]

So, your error means your syntax not ok, the correct one for you is:

version: "3.3"
services:
  nginx:
    image: nginx
    privileged: true
    entrypoint: ["/bin/sh", "-c"]
    command: ["ls", "-lha", "~"]

The execution:

$ docker-compose up
Creating network "20210812_default" with the default driver
Creating 20210812_nginx_1 ... done
Attaching to 20210812_nginx_1
nginx_1  | bin
nginx_1  | boot
nginx_1  | dev
nginx_1  | docker-entrypoint.d
nginx_1  | docker-entrypoint.sh
nginx_1  | etc
nginx_1  | home
nginx_1  | lib
nginx_1  | lib64
nginx_1  | media
nginx_1  | mnt
nginx_1  | opt
nginx_1  | proc
nginx_1  | root
nginx_1  | run
nginx_1  | sbin
nginx_1  | srv
nginx_1  | sys
nginx_1  | tmp
nginx_1  | usr
nginx_1  | var
20210812_nginx_1 exited with code 0

Upvotes: 1

Related Questions