How to source an entry point script with Docker?

21,138

Solution 1

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.)

Solution 2

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.

Share:
21,138
Dr. Fabien Tarrade
Author by

Dr. Fabien Tarrade

Sr. Data Scientist @AXA. Particle physicist for 10 years @CERN with @ATLASexperiment. Fascinated by #DeepLearning #MachineLearning #Python #MLOps #Kubeflow #TFX

Updated on March 13, 2020

Comments

  • Dr. Fabien Tarrade
    Dr. Fabien Tarrade over 4 years

    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.

  • Dr. Fabien Tarrade
    Dr. Fabien Tarrade about 5 years
    I have the same issue using your syntax for the ENTRYPOINT.
  • Dr. Fabien Tarrade
    Dr. Fabien Tarrade about 5 years
    I gave a try with tini and I am seeing the same kind of issues. Either it complain that the scrip doesn't exist or nothing happen. I think I need to do a deep dive in CMD, ENTRYPOINT, and sub SHELL. I will try to build a very simpe image which doesn't derived from a based image. I also try to look at "docker describe" but I need to understand what I am suppose to have.
  • Roland Weber
    Roland Weber about 5 years
    @Dr.FabienTarrade "the same issue" being that source is not found, because bash thinks it's supposed to execute a script of that name?