0

How can I insert nproc in Dockerfile inside a CMD instruction in the exec format?

I have this:

CMD [ "gunicorn", \
      "--access-logfile", "-", \
      "--error-logfile", "-", \
      "--bind=\"0.0.0.0:${PORT}\"", \
      "--workers=$(( $(nproc) * 2 + 1))", \
      "--worker-class=\"uvicorn.workers.UvicornWorker\"", \
      "--log-level=\"${LOGLEVEL}\"", \
      "\"app:app\"" ]

but I'm getting this error:

usage: gunicorn [OPTIONS] [APP_MODULE]
gunicorn: error: argument -w/--workers: invalid int value: '$(( $(nproc) * 2 + 1))'

Thanks


UPDATE:

After reading the @david-maze commentary, I searched and I solved creating a entrypoint.sh with this:

#!/bin/sh

set -e

exec gunicorn \
  --access-logfile - \
  --error-logfile - \
  --bind="0.0.0.0:${PORT}" \
  --workers=$(( $(nproc) * 2 + 1)) \
  --threads=2 \
  --worker-class="uvicorn.workers.UvicornWorker" \
  --log-level="${LOGLEVEL}" \
  "app:app" \
  "$@"

And my Dockerfile ends with:

# (...)

WORKDIR sfhskjd

# ENTRYPOINT ["./entrypoint.sh"]
CMD ["./entrypoint.sh"]

It's working as I want

Rui Martins
  • 3,337
  • 5
  • 35
  • 40
  • 1
    The `$(nproc)` is Bourne shell syntax, but with the JSON-array [exec form](https://docs.docker.com/engine/reference/builder/#exec-form-entrypoint-example) `CMD`, there's no shell being run. You need to remove the JSON syntax and use a plain-string [shell form](https://docs.docker.com/engine/reference/builder/#shell-form-entrypoint-example); `CMD gunicorn --access-logfile ...`. Also see [How do I use Docker environment variable in ENTRYPOINT array?](https://stackoverflow.com/questions/37904682/how-do-i-use-docker-environment-variable-in-entrypoint-array) for a similar problem. – David Maze Jul 01 '22 at 21:37
  • Thanks, I didn't know that, I'm changing from shell form to exec form because I think my signals are not being well handled. This article talk about that: https://emmer.dev/blog/docker-shell-vs.-exec-form – Rui Martins Jul 01 '22 at 22:02

0 Answers0