Compose: Ctrl+C on `docker-compose up` does not send the signal to the services

Created on 11 Jan 2020  路  4Comments  路  Source: docker/compose

Description of the issue

Doing a Ctrl+C on a docker-compose up does not send the signals to the containers. However, signals are reaching the container fine with doing a docker stop or docker kill. Doing a Ctrl+C on a docker run also works as expected.

This behavior seems to be new as it is causing an issue in my dev environment I've never had until very recently.

Context information (for bug reports)

To show the issue, I created a minimal project to debug it. https://github.com/GuillaumeRochat/docker-signal-bug

I tried following the docker events to see what was going on, and I clearly see an event with the signal=15 being sent when doing Ctrl+C. So I really don't understand what's going on.

2020-01-10T17:36:24.652363796-05:00 container kill bd9e09d03cf852a76968af5a7d2fcff7405dd8abbf9b06ae35ed03bcd0e360bb (com.docker.compose.config-hash=4cfb00a831ce1d3b7ee745c0909bc85dbdc280101b19a0c3e31db7af97968780, com.docker.compose.container-number=1, com.docker.compose.oneoff=False, com.docker.compose.project=docker-signal-bug, com.docker.compose.project.config_files=docker-compose.yml, com.docker.compose.project.working_dir=/home/grochat/code/docker-signal-bug, com.docker.compose.service=service, com.docker.compose.version=1.25.1, image=docker-signal-bug, name=docker-signal-bug_service_1, signal=15)

I spent a few hours trying to figure this out and isolate the scenario, as I though I wasn't handling the signals correctly in the containers. However, since the issue does not happen with docker run, docker stop or docker kill, I decided to file an issue on docker-compose,. as it seems to be the logical place to search for a fix.

Output of docker-compose version

docker-compose version 1.25.1, build unknown
docker-py version: 4.1.0
CPython version: 3.8.1
OpenSSL version: OpenSSL 1.1.1d  10 Sep 2019

Output of docker version

Client:
 Version:           19.03.5-ce
 API version:       1.40
 Go version:        go1.13.4
 Git commit:        633a0ea838
 Built:             Fri Nov 15 03:19:09 2019
 OS/Arch:           linux/amd64
 Experimental:      true

Server:
 Engine:
  Version:          19.03.5-ce
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.13.4
  Git commit:       633a0ea838
  Built:            Fri Nov 15 03:17:51 2019
  OS/Arch:          linux/amd64
  Experimental:     true
 containerd:
  Version:          v1.3.2.m
  GitCommit:        d50db0a42053864a270f648048f9a8b4f24eced3.m
 runc:
  Version:          1.0.0-rc9
  GitCommit:        d736ef14f0288d6993a1845745d6756cfc9ddd5a
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

Output of docker-compose config
See repo with the example issue. https://github.com/GuillaumeRochat/docker-signal-bug

Steps to reproduce the issue

  1. Build the container with a single start.sh script that handles signals and sleeps while waiting for them.
  2. Up the container with the docker-compose up command.
  3. Do a Ctrl+C
  4. Notice that there is no Caught Term or Caught Int message appearing.
  5. Up the container with the docker-compose up command.
  6. Stop it with a docker stop docker-signal-bug_service_1 command.
  7. Notice that there is a Caught Term message appearing.

Observed result

Ctrl+C does not send a signal to the services.

Expected result

Ctrl+C on a docker-compose should send a signal to the services.

Additional information

OS: Arch Linux Kernel 5.4.10-arch1-1

kinquestion statu0-triage

Most helpful comment

Ctrl+C on a docker-compose up do run stop command on service containers
(see https://github.com/docker/compose/blob/master/compose/cli/main.py#L1406-L1420)
But also docker-compose stop piping logs into console at this time, so don't expect to read any container output trapping termination signal.

You can collect those logs using docker logs, which demonstrate Caugh Term is actually printed by your demo project

side note: thanks a lot for your bug reproduction project, wish we get such material on every reported issue :P
tip: your docker-compose.yml file can declare a build section so you don't need a build.sh script.

All 4 comments

Ctrl+C on a docker-compose up do run stop command on service containers
(see https://github.com/docker/compose/blob/master/compose/cli/main.py#L1406-L1420)
But also docker-compose stop piping logs into console at this time, so don't expect to read any container output trapping termination signal.

You can collect those logs using docker logs, which demonstrate Caugh Term is actually printed by your demo project

side note: thanks a lot for your bug reproduction project, wish we get such material on every reported issue :P
tip: your docker-compose.yml file can declare a build section so you don't need a build.sh script.

@ndeloof Oh wow, thanks! Now I feel stupid for not figuring this part out myself. _Note to self: don't trust yourself on Friday afternoons._ I was chasing after a teardown on ctrl+c that was no longer happening and have isolated the wrong issue.

In any case, why is it stopping to pipe logs even though the containers are not done yet? That could hide errors on teardown code and is not an expected behavior from my point of view. I'm assuming there's a reason behind it, but I wonder why/what. After all, if the teardown blocks or takes a while, docker-compose still does not exit entirely, so might as well keep forwarding logs?

I can't tell about the initial intent for this.
An obvious reason to me is that rendering of the stop progression (xyz_1 ... done) would be broken by some extra container logs. But maybe there's another "non-technical" reason. Otherwise a CLI option might be used to keep container logs until terminated. Could be a valid future improvement.

I do have a similar issue, and I am wondering if this is connected to the logs no longer being written to stdout.

I want to write a summary file of the happenings inside a java program in a Docker container to the host. What I did was write a Runtime.getRuntime().addShutdownHook which in a FileWriter then puts the interesting info inside a logfile.
When I run this on a single Docker container and press Ctrl+C, the file is written. Also when I write something to a file outside of the ShutdownHook it gets written in Docker Compose. So volume binding etc. is not the problem here.

What I cannot achieve is the file being written when I press Ctrl+C in Docker Compose, or run docker-compose stop.

As so often, you have been searching for hours and days for the answer, and the moment you are ready posting the issue, the solution walks in the front door with a wide grin.
The general problem here is: when you specify the workload of your docker image by CMD, then apparently signals are not forwarded to the program you run. You have to use ENTRYPOINT in order to get my usecase running. Oh boy.

Specs:

  • Manjaro Linux
  • Docker version 19.03.8
  • docker-compose version 1.25.5
Was this page helpful?
0 / 5 - 0 ratings