The image’s ENTRYPOINT specifies the container’s default executable. Many Minimus images use a different entrypoint from what is commonly found in their Docker Hub alternatives. Where relevant, the entrypoint was modified to enhance security and/or to enforce an EXEC-form entrypoint, which is more secure than a shell entrypoint.

For example, a Minimus Node image will start up in node rather than in a shell script. This is true for both the dev and non-dev variants of the Minimus Node image. Minimus modified the entrypoint in the production (non-dev) Node.js image because it doesn’t include a shell. To guarantee compatibility and maintain consistency between the two image variants, the development Node image’s entrypoint is aligned and shares the same entrypoint instruction.



            "Entrypoint": [
                "/usr/bin/node"
            ],
            "Cmd": [
                "--help"
            ],

As a result, you may need to adjust your code when migrating to Minimus images to handle the entrypoint modifications.

Example: How to adapt to the Minimus entrypoint

Changes in the entrypoint will often dictate changes to the starting command. For example, the Minimus Node image starts directly as a node interpreter (/usr/bin/node entrypoint) rather than starting in a subshell. This has a direct impact on the CMD instruction.

If you were previously using an image with a sh entrypoint, your CMD instruction needed to explicitly invoke node:

CMD ["node", "myProgram.js"]

But this won’t work with the Minimus Node image. If you try to build and run your Node app using the Minimus Node image without changing the command, you will probably encounter this error:

Error: Cannot find module '/app/node'
at Function._resolveFilename (node:internal/modules/cjs/loader:1249:15)
...
at node:internal/main/run_main_module:36:49 {
code: 'MODULE_NOT_FOUND'
}

To fix the error, you need to drop the redundant node invocation. Since the entrypoint is already set to execute the command using Node.js, you only need to provide the script name in the CMD.

CMD ["myProgram.js"]

After the change, your Node app should run as expected.

Why Exec-form entrypoints are more secure

There are two types of entrypoints: exec-form and shell-form. The exec form entrypoint is considered more secure because it ensures that the container can stop, restart, and handle interruptions more smoothly. The security advantage of an exec form entrypoint stems from the concept of PID1.

The first process started during system boot is named PID1. According to the process tree model, PID1 is known as the parent process or init process. It is responsible for starting and managing all processes inside the container. PID1 is also responsible for handling signals from the Docker host.

An exec form entrypoint ensures that the first command runs directly as PID1 without involving a shell. This allows it to receive and handle signals directly from the host.

Beyond the obvious risk of shell injection vulnerabilities, a shell form entrypoint results in a shell process becoming PID1. The shell process doesn’t always handle signals from the Docker host properly, which can potentially lead to unclean shutdowns of the container. For example, if the Docker SIGTERM signal for graceful shutdown is received by a shell instead of the intended process, the results may be unpredictable. Using a shell-form entrypoint should therefore be avoided on principle.

Adapting to Minimus image entrypoints

The Minimus Image Gallery lists the default entrypoint for each image directly in the UI under the details tab to help with the migration. If you prefer, you can also run docker inspect {image} to look up the entrypoint and CMD instruction directly in the CLI.

Working with exec form entrypoints

Exec form entrypoints are written as a JSON array, with the terms wrapped in double-quotes (”) and square brackets. Exec form is also known as vector form. For example:

ENTRYPOINT ["executable", "param1", "param2"]

Exec form entrypoints can be combined with the CMD instruction to specify default commands. Learn more from Docker

ENTRYPOINT ["echo", "Hello"]
CMD ["World!"]

Overriding entrypoints

You can override the container entrypoint at runtime by passing a new entrypoint to the container. Add the --entrypoint flag to the docker run command to replace the default entrypoint specified in the Dockerfile. For example, you can start a dev container in a subshell:

docker run -it --entrypoint /bin/bash  {.../reg.minimus.io/nginx:1.26-dev}

Overriding default arguments

An exec form entrypoint can be combined with the CMD instruction to provide default arguments. You can supply ad-hoc arguments at runtime to override the defaults in the Dockerfile. Add the arguments after the image name in the docker run command. For example:

docker run -v "$(pwd)":/app -w {go image} run main.go

Empty vector

You can disable the default entrypoint by specifying an empty vector. Alternatively, if the default entrypoint is an empty vector, a CMD command can be added in vector form.

docker run --entrypoint "" my-image sh
# overrides the entrypoint and starts a shell