I have an Docker image and I can run it:
docker run -it --entrypoint="/bin/bash" gcr.io/docker:tag
Then I can source a script in the following way:
root@86bfac2f6ccc:/# source entrypoint.sh
The script looks like that:
more entrypoint.sh
#!/bin/bash
. /env.sh
. /root/miniconda3/etc/profile.d/conda.sh
conda activate base
exec "$@"
Which activate the base env:
(base) root@86bfac2f6ccc:/#
So far so good but I don't managed to include this in the Dockerfile
or as parameters to docker run
:
I tried many things:
For example:
docker run -it --entrypoint="/bin/bash" gcr.io/docker:tag source entrypoint.sh
/bin/bash: source: No such file or directory
But the script exist and can be executed:
docker run -it --entrypoint="/bin/ls" gcr.io/docker:tag -la
...
-rwxr-xr-x 1 root root 94 Apr 26 20:36 entrypoint.sh
...
Or:
docker run -it --entrypoint="/bin/bash" gcr.io/docker:tag ". /entrypoint.sh"
/bin/bash: . /entrypoint.sh: No such file or directory
Or in the Docker file:
ENTRYPOINT ["source", "/entrypoint.sh"]
I guess the issue I have is maybe related the fact that source
evaluate a script in the current shell.
Any guidance to achieve what I want ? It seems quite obvious but I am out of idea.
When Docker launches a container, there are two parts, the “entrypoint” and the “command”. When both are specified, the “command” part is passed as command-line arguments to the “entrypoint” part.
In particular, the script you show has a very typical pattern for an entrypoint script:
#!/bin/sh
# ... do some setup ...
# then run the CMD passed as command-line arguments
exec "$@"
If your Dockerfile names this script as its ENTRYPOINT
then you want to pass the command you want to run as the “command” part. If you run your shell as just
docker run --rm -it gcr.io/docker:tag sh
then sh
will be passed to the entrypoint script, which will do the setup and then eventually run it.
(Remember that source
is a vendor-specific extension and doesn’t exist in many shells, like the minimal BusyBox shell that Alpine base images use, but that .
means the same thing and is in the POSIX standard. Since a container only runs one process it also doesn’t really make sense for that one process to be “source this file”; it would set up some environment variables, and then it’s done so the container exits. The entrypoint pattern does the setup and then runs the main container command.)
In an interactive shell, source
tells the shell to read the commands from the file without creating a subshell. In your case, you want the initial shell to execute the commands from a script. So all you have to do is give the script as an argument. Try the following:
ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]
However, it is not a good idea to run a shell as the initial process in a container. That screws up the signal handling. You'll notice that you cannot stop execution with Ctrl-C.
Therefore, use CMD
instead of ENTRYPOINT
to start the shell. The initial process with id 1 should be a minimal init process, such as tini
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With