0

Can you help me understand why I can't stop my Docker container?

This is my Dockerfile:

FROM python:3.10.4-alpine3.15

ENV PYTHONUNBUFFERED 1

WORKDIR /app

RUN apk update \
    && apk add --no-cache gcc musl-dev postgresql-dev python3-dev libffi-dev \
    && pip install --upgrade pip

COPY ./requirements.txt ./

RUN pip install -r requirements.txt

COPY ./ ./

EXPOSE 8000
ENTRYPOINT ["sh", "docker_init.sh"]

The problem began when I replaced CMD with ENTRYPOINT cause I needed to run some other stuff. This is the docker_init.sh file:

python manage.py migrate
python manage.py init_admin
python manage.py runserver 0.0.0.0:8000

Now, I can't stop the Docker container with Ctrl+C. I need to close the terminal, stop Docker and restart it (I'm using Linux).

Mustafa Özçetin
  • 1,893
  • 1
  • 14
  • 16
Alejandro Veintimilla
  • 10,743
  • 23
  • 91
  • 180

1 Answers1

1

With this setup, the main container process is no longer your Python script but the shell-script wrapper. You can see this if you docker exec running-container-name ps: process ID 1 will be sh here.

You can fix this by using the shell exec builtin to replace the shell with the main command. The setup will run under the shell but then the last command will switch over to the Django application as the main process.

exec python manage.py runserver 0.0.0.0:8000

A more general form of this is an entrypoint wrapper script. If you make that last line be exec "$@" then the shell will replace itself with whatever was passed as its command-line arguments. When Docker runs a container, if it has both an ENTRYPOINT and a CMD, the command is passed as arguments to the entrypoint, and it's a little easier to override the command part (docker run --rm -it your-container bash for example). This can give you a setup where you have an interactive debugging shell in a temporary container, but all of the entrypoint setup steps have been done.

So for this, keep the entrypoint as-is, except you don't put a specific command at the end:

#!/bin/sh
python manage.py migrate
python manage.py init_admin
exec "$@"

In the Dockerfile, keep the CMD you had originally, and also add the ENTRYPOINT

ENTRYPOINT ["./docker_init.sh"]
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
David Maze
  • 130,717
  • 29
  • 175
  • 215