pass signals to mitmproxy in docker-entrypoint.sh (#5920)

Current docker-entrypoint.sh [0][1] runs

    gosu mitmproxy "$@"

for mitmproxy, mitmdump and mitmweb. There is a problem with this
approach: bash becomes a parent process for mitmproxy [2][3], but when
signals are sent by docker-compose to mitmproxy container they are sent
to bash, but they are not delivered to mitmproxy [4]. This leads to a
slow shutdown of the container, because by default docker sends SIGTERM,
waits for 10 seconds and then sends SIGKILL if the container is still
alive [5].

This patch solves the issue by replacing bash process with mitmproxy
entirely using "exec" - this way the signals are delivered to mitmproxy
directly.

To test the patch a Dockerfile [6] that applies the patch to the release
image from the dockerhub could be used along with slighly modified
compose.yml [7]. With the patch bash is no longer running inside the
container [8] and the `docker compose down` time on my machine drops
from 10.3s to 0.5s [9].

0. https://github.com/mitmproxy/mitmproxy/blob/main/release/docker/docker-entrypoint.sh
1. To confirm that this is what's actually in the image:
    ```
    > docker run mitmproxy/mitmproxy grep gosu /usr/local/bin/docker-entrypoint.sh
      gosu mitmproxy "$@"
    ```
2. compose.yaml
    ```
    services:
      mitmproxy-test:
        image: mitmproxy/mitmproxy
        command: ["mitmweb"]
        # https://github.com/mitmproxy/mitmproxy/issues/5727
        stdin_open: true
        tty: true
    ```
3. We can see that the parent PID for mitmweb is the pid of bash.
    ```
    > docker compose up -d
    [+] Running 2/2
     ⠿ Network mitmproxy_default             Created           0.1s
     ⠿ Container mitmproxy-mitmproxy-test-1  Started           0.5s
    > docker compose top
    mitmproxy-mitmproxy-test-1
    UID    PID     PPID    C    STIME   TTY     TIME       CMD
    root   31227   31202   0    16:12   pts/0   00:00:00   /bin/bash /usr/local/bin/docker-entrypoint.sh mitmweb
    root   31314   31227   1    16:12   pts/0   00:00:01   /usr/local/bin/python /usr/local/bin/mitmweb
    ```
4. https://unix.stackexchange.com/a/196053
5. https://docs.docker.com/compose/faq/#why-do-my-services-take-10-seconds-to-recreate-or-stop
6. Dockerfile:
    ```
    FROM mitmproxy/mitmproxy

    RUN sed -i 's/^  gosu mitmproxy/  exec gosu mitmproxy/' /usr/local/bin/docker-entrypoint.sh
    ```
7. compose.yaml to build an image from Dockerfile and use it:
    ```
    services:
      mitmproxy-test:
        build:
          dockerfile: Dockerfile
          context: .
        command: ["mitmweb"]
        # https://github.com/mitmproxy/mitmproxy/issues/5727
        stdin_open: true
        tty: true
    ```
8. With the patch:
    ```
    > docker compose top
    mitmproxy-mitmproxy-test-1
    UID    PID    PPID   C    STIME   TTY     TIME       CMD
    root   4994   4970   50   17:00   pts/0   00:00:02   /usr/local/bin/python /usr/local/bin/mitmweb
     ```
9. Without the patch:
    ```
    > docker compose down
    [+] Running 2/2
     ⠿ Container mitmproxy-mitmproxy-test-1  Removed          10.2s
     ⠿ Network mitmproxy_default             Removed           0.1s
    ```
   With the patch:
    ```
    > docker compose down
    [+] Running 2/2
     ⠿ Container mitmproxy-mitmproxy-test-1  Removed           0.4s
     ⠿ Network mitmproxy_default             Removed           0.1s
    ```
This commit is contained in:
Maksym Medvied 2023-02-09 14:43:47 +04:00 committed by GitHub
parent 41555edab9
commit 5969f25db4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -18,7 +18,7 @@ usermod -o \
mitmproxy
if [[ "$1" = "mitmdump" || "$1" = "mitmproxy" || "$1" = "mitmweb" ]]; then
gosu mitmproxy "$@"
exec gosu mitmproxy "$@"
else
exec "$@"
fi