Search code examples
dockercmddockerfiledocker-entrypoint

Dockerfile Entrypoint no such file or directory: OCI not found


I have a Dockerfile with Entrypoint where I specify the config file variable and the executable file but it looks like Docker or Entrypoint doesn't recognize it. My main.py has to be executed with the config file.

ENTRYPOINT ["CONFIG_FILE=path/to/config.file ./main.py"]

always reproduce no such file or directory: OCI not found

Note: I have copied all the files in the current work directory already. main.py is an executable file. So I guess the problem is the config variable appended before the executable file. Does anyone know what is going on there? Also changing from ENTRYPOINT to CMD does not help as well.

Dockerfile

FROM registry.fedoraproject.org/fedora:34

WORKDIR /home

COPY . /home

ENTRYPOINT ["CONFIG_FILE=path/to/config.file ./main.py"]


Solution

  • If you just need to set an environment variable to a static string, use the Dockerfile ENV directive.

    ENV CONFIG_FILE=/path/to/config.file
    CMD ["./main.py"]
    

    The Dockerfile ENTRYPOINT and CMD directives (and also RUN) have two forms. You've used the JSON-array form; in that form, there is not a shell involved and you have to manually split out words. (You are trying to run a command CONFIG_FILE=... ./main.py, where the executable file itself needs to include the = and space.) If you don't use the JSON-array form you can use the shell form instead, and this form should work:

    CMD CONFIG_FILE=/path/to/config.file ./main.py
    

    In general you should prefer CMD to ENTRYPOINT. There's a fairly standard pattern of using ENTRYPOINT to do first-time setup and then execute the CMD. For example, if you expected the configuration file to be bind-mounted in, but want to set the variable only if it exists, you could write a shell script:

    #!/bin/sh
    # entrypoint.sh
    #
    # If the config file exists, set it as an environment variable.
    CONFIG_FILE=/path/to/config.file
    if [ -f "$CONFIG_FILE" ]; then
      export CONFIG_FILE
    else
      unset CONFIG_FILE
    fi
    
    # Run the main container CMD.
    exec "$@"
    

    Then you can specify both the ENTRYPOINT (which sets up the environment variables) and the CMD (which says what to actually do)

    # ENTRYPOINT must be JSON-array form for this to work
    ENTRYPOINT ["./entrypoint.sh"]
    # Any valid CMD syntax is fine
    CMD ["./main.py"]
    

    You can double-check the environment variable setting by providing an alternate docker run command

    # (Make sure to quote things so the host shell doesn't expand them first)
    docker run --rm my-image sh -c 'echo $CONFIG_FILE'
    docker run --rm -v "$PWD:/path/to" my-image sh -c 'echo $CONFIG_FILE'
    

    If having the same environment in one-off debugging shells launched by docker exec is important to you, of these approaches, only Dockerfile ENV will make the variable visible there. In the other cases the environment variable is only visible in the main container process and its children, but the docker exec process isn't a child of the main process.