How to Fix Docker Not Appending Arguments to ENTRYPOINT (uWSGI Example)


7 views

When working with Docker's ENTRYPOINT instruction, many developers expect command-line arguments passed to docker run to automatically append to the entrypoint command. However, this behavior depends on whether you're using exec form or shell form of ENTRYPOINT.

// Problematic Dockerfile entry
ENTRYPOINT ["uwsgi", "--ini /home/docker/app/uwsgi_app.ini"]

In your case, there are actually two problems occurring simultaneously:

  1. You're using exec form (JSON array syntax) but including the entire ini path as a single argument
  2. Docker isn't properly handling the argument passing due to the entrypoint format

Here's the correct way to structure your ENTRYPOINT:

ENTRYPOINT ["uwsgi", "--ini", "/home/docker/app/uwsgi_app.ini"]

Notice the separate array elements for the ini flag and its value. Now when you run:

docker run -itP uwsgi_app:0.1 --uid=docker

Here's a full Dockerfile demonstrating proper argument handling:

FROM python:3.9-slim

RUN useradd -ms /bin/bash docker

WORKDIR /home/docker/app
COPY uwsgi_app.ini .
COPY requirements.txt .

RUN pip install -r requirements.txt

ENTRYPOINT ["uwsgi", "--ini", "/home/docker/app/uwsgi_app.ini"]

Another approach is to combine ENTRYPOINT with CMD:

ENTRYPOINT ["uwsgi"]
CMD ["--ini", "/home/docker/app/uwsgi_app.ini", "--uid=docker"]

Then override CMD when running:

docker run -itP uwsgi_app:0.1 --uid=docker

To verify how arguments are being passed:

# Create test container
docker run --rm --entrypoint sh uwsgi_app:0.1 -c 'echo $@'

# Or to see full command
docker inspect --format '{{.Config.Entrypoint}}' uwsgi_app:0.1
docker inspect --format '{{.Config.Cmd}}' uwsgi_app:0.1
  • Always split command arguments into separate array elements in exec form
  • Consider using gosu or similar tools for better user switching
  • Test argument passing with simple commands before implementing complex entrypoints

When working with Docker containers running uWSGI, you might encounter situations where additional arguments passed via docker run don't properly append to the entrypoint command. This commonly occurs when trying to pass security-related flags like --uid to uWSGI.

The fundamental misunderstanding here stems from how Docker handles ENTRYPOINT and CMD combination. When using the exec form of ENTRYPOINT (JSON array format), arguments passed via docker run don't automatically append unless you specifically account for them.

// Problematic Dockerfile snippet
ENTRYPOINT ["uwsgi", "--ini /home/docker/app/uwsgi_app.ini"]

To properly handle additional arguments, you have several approaches:

Option 1: Use Shell Form with Parameter Expansion

ENTRYPOINT uwsgi --ini /home/docker/app/uwsgi_app.ini "$@"

Option 2: Use CMD for Additional Arguments

ENTRYPOINT ["uwsgi", "--ini", "/home/docker/app/uwsgi_app.ini"]
CMD ["--uid=docker"]

Then run with:

docker run -itP uwsgi_app:0.1

Option 3: Explicit Argument Handling

ENTRYPOINT ["/bin/sh", "-c", "uwsgi --ini /home/docker/app/uwsgi_app.ini $@", "--"]

Here's a fully functional Dockerfile that implements the best practice:

FROM python:3.9-slim

RUN useradd -ms /bin/bash docker
WORKDIR /home/docker/app
COPY . .

# Best approach combining ENTRYPOINT and CMD
ENTRYPOINT ["uwsgi", "--ini", "/home/docker/app/uwsgi_app.ini"]
CMD ["--uid=docker", "--gid=docker"]

EXPOSE 8000

To test if your arguments are properly being passed:

docker run -it --rm uwsgi_app:0.1 --uid=docker --gid=docker

You should see uWSGI attempting to run with the specified user/group, or at least showing the arguments in the error message if the user doesn't exist.

  • Mixing shell form and exec form improperly
  • Not properly escaping arguments with spaces
  • Forgetting to add the -- separator when using shell form
  • Assuming argument order when combining ENTRYPOINT and CMD

For more complex scenarios where arguments need conditional handling, consider using an entrypoint script:

#!/bin/bash
# entrypoint.sh

# Basic arguments
args=("--ini" "/home/docker/app/uwsgi_app.ini")

# Add uid/gid if specified
if [ -n "$UID" ]; then
    args+=("--uid=$UID")
fi

if [ -n "$GID" ]; then
    args+=("--gid=$GID")
fi

# Append any additional arguments
exec uwsgi "${args[@]}" "$@"

Then in your Dockerfile:

COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]