moby: docker client doesn't pass signals when a terminal is attached

Description

Re #3793: when running with -ti, docker run does not pass signals to child process.

Steps to reproduce the issue:

  1. I built an image FROM base/archlinux, with https://github.com/krallin/tini in it.

  2. docker run -ti tini-arch /tini -- sleep 300

  3. ps -A f | grep docker

     31807 pts/5    Sl+    0:00              |   |   |   \_ docker run -ti tini-arch /tini -- sleep 300
    
  4. kill 31807

Describe the results you received:

In the terminal window attached I see

Terminated

In another window:

docker ps
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS               NAMES
94e81d8dd7db        tini-arch           "/tini -- sleep 300"   59 seconds ago      Up 58 seconds                           angry_ardinghelli

Describe the results you expected:

I expect the container to stop running because it has been passed the appropriate signal. I have confirmed that running the same without -ti prints nothing in the attached terminal, and docker ps shows that the running container has stopped.

This is necessary because I expect that in situations like running a container over an SSH session should terminate the container if the SSH session hangs up, because SIGHUP will be sent to the client when the terminal closes.

Output of docker version:

Client:
 Version:      1.11.0
 API version:  1.23
 Go version:   go1.6.1
 Git commit:   4dc5990
 Built:        
 OS/Arch:      linux/amd64

Server:
 Version:      1.11.0
 API version:  1.23
 Go version:   go1.6.1
 Git commit:   4dc5990
 Built:        
 OS/Arch:      linux/amd64

Output of docker info:

Containers: 19
 Running: 0
 Paused: 0
 Stopped: 19
Images: 206
Server Version: 1.11.0
Storage Driver: overlay
 Backing Filesystem: extfs
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins: 
 Volume: local
 Network: bridge null host
Kernel Version: 4.4.6-gentoo
Operating System: Gentoo/Linux
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 3.829 GiB
Name: guepardo
ID: Y6HO:RPCY:TMYW:63IN:CQP2:I4JY:6EUL:AYHK:HBH2:JK7U:YCYJ:ODTY
Docker Root Dir: /var/lib/docker
Debug mode (client): false
Debug mode (server): false
Username: jarro2783
Registry: https://index.docker.io/v1/
WARNING: No cpu cfs quota support
WARNING: No cpu cfs period support

Additional environment details (AWS, VirtualBox, physical, etc.):

Physical machine. I have confirmed this on another physical host running 1.12.0.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 23 (9 by maintainers)

Commits related to this issue

Most upvoted comments

@Mark-50 wrote:

@hashar this is not the same situation with #9098. when “docker run” process was killed, the container started by “docker run” should exit. when “docker exec” process was killed, the container started before should remain running, only the process started by “docker exec” inside the container should exit.

I think I understood the code for docker run and docker exec to both hit the same faulty code path. And I am pretty sure at time (back in 2017) I did reproduce the same behavior for both run and exec subcommands.

Anyway for the docker run case, I am pasting here my comment from the other issue https://github.com/moby/moby/issues/9098#issuecomment-347536699 :

I had that issue with both docker run and docker exec not dispatching signals to the daemon/container. The root cause is when using --tty signal proxying is entirely disabled with no way to enable it (even with --sig-proxy). It affects at least docker run and docker exec that share the same code path.

Previously --sig-proxy was an option to force proxying signals when not using a tty, and hence when using --tty the proxy got forwarded. Passing both --sig-proxy and -tty was leading to an error. That looked like:

Options Signal proxy?
none No
--tty Yes
--sig-proxy Yes
--tty --sig-proxy error: TTY mode (-t) already imply signal proxying (-sig-proxy)

October 2013 patch e0b59ab52b87b8fc15dd5534c3231fdd74843f9f was made to “_Enable sig-proxy by default in run and attach _”. It changed --sig-proxy to default to true and made --tty to always disable signal proxy.

Options Signal proxy?
none Yes (was No)
--tty No (was Yes)
--sig-proxy Yes
--tty --sig-proxy No (was an error)

So what happened with e0b59ab52b87b8fc15dd5534c3231fdd74843f9f is that signal proxying is now enabled by default for non-tty. BUT the patch has a fault: setting --tty always disable signal proxying.

I am pretty sure that signal-proxying should be enabled by default whether it is a tty or non-tty mode, it is still possible to disable it with --sig-proxy=false. A patch would thus have to implement the following changes:

Options Signal proxy (current) Expected
none Yes Yes
--tty No Yes
--sig-proxy Yes Yes
--sig-proxy=false No No
--tty --sig-proxy No Yes
--tty --sig-proxy=false No No

TLDR: --tty should not arbitrarily force sigProxy = false caused by e0b59ab52b87b8fc15dd5534c3231fdd74843f9f

Reference: https://phabricator.wikimedia.org/T176747#3749436

@thaJeztah thank you very much for the sig-proxy fix. Being able to Ctrl+C has really improved my user experience 😉