skip to Main Content

It’s just a theoretical question. Is there a way to run the docker but only run one specific script without changing the Dockerfile? Maybe with the docker run [container] command?

Dockerfile:

FROM python:3.8

ADD main1.py
ADD main2.py
ADD main3.py
ADD main4.py
ADD main5.py

Theoretical Command:

docker run docker-test main2.py

2

Answers


  1. There is nothing "theoretical" about this. Docker copies into place the files, and if they are working executables, you can execute them with docker run image executable … but

    • it requires the files to be properly executable (or you will need to explicitly say docker run image python executable to run a Python script which is not executable)

    • it requires the files to be in your PATH for you to be able to specify their names without a path; or you will need to specify the full path within the container, or perhaps a relative path (./executable if they are in the container’s default working directory)

      docker run image /path/to/executable
      
    • you obviously need the container to contain python in its PATH in order for it to find python; or you will similarly need to specify the full path to the interpreter

      docker run image /usr/bin/python3 /path/to/executable
      

    In summary, probably make sure you have chmod +x the script files and that they contain (the moral equivalent of) #!/usr/bin/env python3 (or python if that’s what the binary is called) on their first line.

    (And obviously, don’t use DOS line feeds in files you want to be able to execute in a Linux container. Python can cope but the Linux kernel will look for /usr/bin/env python3^M if that’s exactly what it says on the shebang line.)

    Login or Signup to reply.
  2. In the specific case of a Python application, the standard Python setuptools package has some functionality that can simplify this.

    In your application’s setup.cfg file you can declare entry points (different from the similarly-named Docker concept) which provide simple scripts to launch a specific part of your application.

    [options.entry_points]
    console_scripts =
      main1 = app.main1:main
      main2 = app.main2:main
    

    where the scripts app/main1.py look like normal top-level Python scripts

    #!/usr/bin/env python3
    
    # the console_scripts call this directly
    def main():
      ...
    
    # for interactive use
    if __name__ == '__main__':
      main()
    

    Now in your Dockerfile, you can use a generic Python application recipe and install this; all of the console_scripts will be automatically visible in the standard $PATH.

    FROM python:3.8
    WORKDIR /app
    COPY . .
    RUN pip install .
    CMD ["main1"]
    
    docker run --rm my-image main2
    

    It’s worth noting that, up until the last part, we’ve been using generic Python utilities, and you can do the same thing without Docker

    # directly on the host, without Docker
    python3 -m venv ./virtual_environment
    . ./virtual_environment/bin/activate
    pip install .
    
    # then run any of the scripts directly
    main3
    
    # technically activating the virtual environment is optional
    deactivate
    ./virtual_environment/bin/main4
    

    The fundamental point here is that the same rules apply for running a command on the host, in a Dockerfile CMD, or in a docker run command override (must be on $PATH, executable, have the correct interpreter, etc.). See @tripleee’s answer for a more generic, non-Python-specific approach.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search