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.