gongarek
gongarek

Reputation: 1034

Pycharm add command

Pycharm Professional 2019.3

Ubuntu 18.04

I want to debug python script in container. I know that example below is overkill, but I want to make it simple as possible. How add entrypoint to Dockerfile?

docker-compose.yml:

version: '3'
services:
    python:
        build: .
        container_name: ppd

Dockerfile:

RUN apt-get update
RUN apt-get install -y --no-install-recommends \
    python3-pip
ENTRYPOINT ["sleep", "5"]

app.py:

from time import sleep
for i in [1, 2, 3, 4, 5]:
    sleep(2)
    print(i)

I based on pycharm configure

enter image description here enter image description here

If I run project without ENTRYPOINT everything works fine:

enter image description here

docker ps -a --no-trunc --format {{.Names}}{{.Command}} | grep ppd ppd "python3 -u /opt/project/build/app.py"

It looks like pycharm gives CMD command, because when I add CMD to app.py it is ignored by docker.

When I add ENTRYPOINT in app.py, and start container I see: enter image description here

docker ps -a --no-trunc --format {{.Names}}{{.Command}} | grep ppd ppd "sleep 5 python3 -u /opt/project/build/app.py"

How combine ENTRYPOINT in Dockerfile with pycharm CMD?

Upvotes: 1

Views: 285

Answers (1)

David Maze
David Maze

Reputation: 159998

If you change ENTRYPOINT to CMD in your Dockerfile, everything will work fine.

ENTRYPOINT isn't a required command in a Dockerfile. You generally need at least one of ENTRYPOINT or CMD but there's no specific requirement to use one or the other. If you specify both, the CMD gets passed as additional arguments to the ENTRYPOINT.

In docker run, for example, it's very straightforward to override the CMD when you create a container:

docker run --rm myimage \
  python app.py
docker run --rm myimage \
  ls -lrt /app

This appears to be what PyCharm is doing too; it also matches the command: option in Docker Compose.

Since the command part just gets appended to the entrypoint part, specifying ENTRYPOINT as you've shown can cause some odd behavior, and you need some awkward workarounds.

 # ENTRYPOINT ["sleep", "5"]

 # sleep 5 python myapp.py
 docker run --rm myimage \
   python myapp.py

 # actually runs "python myapp.py" without the "sleep" wrapper
 docker run --rm \
   --entrypoint python \
   myimage \
   myapp.py \

This pattern means a couple of things:

  • CMD should generally be a complete command line; you should expect it to potentially be replaced at container start time.
  • If you provide an ENTRYPOINT you should make sure to run the CMD that gets passed as arguments. If it's a shell script, ending it with exec "$@" will do this.
  • Prefer CMD to ENTRYPOINT if you're not sure which to use (and aren't using both).
  • If your program has a complex invocation, consider wrapping it in a shell script so that it can easily be launched with its standard set of arguments.
FROM python:3.8
WORKDIR /app
COPY requirements.txt .
RUN pip3 install -r requirements.txt
COPY . .
RUN chmod +x app.py

# No entrypoint; easy to specify an alternate command
CMD ["./app.py"]
# Entrypoint is a wrapper tool that takes a command as options
ENTRYPOINT ["wait-for-it.sh", "db:5432", "--"]
CMD ["./app.py"]
# Entrypoint is a shell script ending in `exec "$@"`
ENTRYPOINT ["./entrypoint.sh"]
CMD ["./app.py"]

(There is an alternate "container as command" pattern where ENTRYPOINT is a complete command and CMD is expected to be caller-provided options; the Docker documentation has an example. That won't work with the PyCharm setup you're describing.)

Upvotes: 2

Related Questions