I have this project:
script.sh
:
#!/bin/sh
echo "test"
Dockerfile
:
FROM ubuntu
RUN ["sh", "script.sh"]
With build command docker build -t test .
, I get this error:
=> [internal] load .dockerignore 0.1s
=> => transferring context: 2B 0.0s
=> [internal] load build definition from Dockerfile 0.1s
=> => transferring dockerfile: 118B 0.0s
=> [internal] load metadata for docker.io/library/ubuntu:latest 2.3s
=> [auth] library/ubuntu:pull token for registry-1.docker.io 0.0s
=> CACHED [1/2] FROM docker.io/library/ubuntu@sha256:ec050c32e4a6085b423d36ecd025c0d3ff00c38ab93a3d71a460ff1c44f 0.0s
=> ERROR [2/2] RUN ["sh", "script.sh"] 0.9s
------
> [2/2] RUN ["sh", "script.sh"]:
#0 0.791 sh: 0: cannot open script.sh: No such file
------
Dockerfile:2
--------------------
1 | FROM ubuntu
2 | >>> RUN ["sh", "script.sh"]
--------------------
ERROR: failed to solve: process "sh script.sh" did not complete successfully: exit code: 2
However if I change the Dockerfile to:
FROM ubuntu
CMD ["sh", "script.sh"]
Then it works:
[+] Building 1.2s (5/5) FINISHED
=> [internal] load build definition from Dockerfile 0.1s
=> => transferring dockerfile: 73B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/ubuntu:latest 1.0s
=> CACHED [1/1] FROM docker.io/library/ubuntu@sha256:ec050c32e4a6085b423d36ecd025c0d3ff00c38ab93a3d71a460ff1c44f 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:d9bf124a17e507c73f6defde7b046fff153fb464c2cad8a57333a0966ddf07c1 0.0s
=> => naming to docker.io/library/test 0.0s
From Difference between RUN and CMD in a Dockerfile:
RUN - command triggers while we build the docker image.
CMD - command triggers while we launch the created docker image.
Still, I can't explain why RUN doesn't work but CMD does.
Docker doesn't implicitly COPY
contents into the container, so with your current code, your container doesn't contain any script.sh
file at all.
Consider instead:
FROM ubuntu
COPY ./script.sh .
RUN ["./script.sh"]
Because you aren't running sh
, the script's choice of interpreter (#!/bin/sh
, #!/usr/bin/bash
, #!/usr/bin/env zsh
, #!/usr/bin/env python
, or whatever else it might want) will be honored. (It's good practice to drop the .sh
extension, so if you later rewrite to a non-shell language you won't need to choose between changing the calling convention and having a misleading filename).
Note that this does require your script to have executable permissions and a valid shebang line; you may need to use chmod +x
if it does not.