"docker run" cannot be killed with ctrl+c

Expected behavior

Try to kill “docker run” by pressing ctrl+c. I expect that the “docker run” command will stop and I’ll get a running shell again

Actual behavior

“docker run” traps or ignores ctrl+c.

Information

  • the output of:
    • pinata diagnose -u on OSX

$ pinata diagnose -u
OS X: version 10.11.4 (build: 15E65)
Docker.app: version v1.11.1-beta12
Running diagnostic tests:
[OK] Moby booted
[OK] driver.amd64-linux
[OK] vmnetd
[OK] osxfs
[OK] db
[OK] slirp
[OK] menubar
[OK] environment
[OK] Docker
[OK] VT-x
Docker logs are being collected into /tmp/20160522-085701.tar.gz
Most specific failure is: No error was detected
Your unique id is: AFA59180-C76B-4ECF-BB20-13C96956D87D
Please quote this in all correspondence.

Steps to reproduce the behavior

Follow the instructions in the tutorial here: Deploying Go servers with Docker - The Go Programming Language

The “outyet” project is no longer visible, I replaced it with a simple “Hello World” http handler.

Build it and run the following command: docker run --publish 8080:8080

The app runs and exposes port 8080 - when I run curl localhost:8080 I get “Hello World”.

1 Like

So there are two factors at play here:

  1. If you specify a string for an entrypoint, like this:

    ENTRYPOINT /go/bin/myapp

Docker runs the script with /bin/sh -c 'command'. This intermediate script gets the SIGTERM, but doesn’t send it to the running server app.

To avoid the intermediate layer, specify your entrypoint as an array of strings.

ENTRYPOINT ["/go/bin/myapp"]
  1. I built the app I was trying to run with the following string:

    docker build -t first-app .

This tagged the container with the name first-app. Unfortunately when I tried to rebuild/rerun the container I ran:

docker build .

Which didn’t overwrite the tag, so my changes weren’t being applied.

Once I did both of those things, I was able to kill the process with ctrl+c, and bring down the running container.

3 Likes

If you don’t want to lose your shell you can trying stopping the container from another terminal on the same docker host.

Open a new shell and execute

$ docker ps # get the id of the running container
$ docker stop <container> # kill it (gracefully)

The container process will end and your original shell will be released.

5 Likes

Can the tutorial be updated? The following is incorrect:

"
Run the app, mapping your machine’s port 4000 to the container’s published port 80 using -p:

docker run -p 4000:80 friendlyhello

Hit CTRL+C in your terminal to quit.

Now let’s run the app in the background, in detached mode:

docker run -d -p 4000:80 friendlyhello

"
Actual result: Ctrl+c detaches the friendlyhello process and returns control to the terminal. When you try to run the next “docker run…” command an error returns because there is already a process using the port 80.

Adding the flags -t and -i will allow Ctrl-c to work as suggested: [(source)] (https://github.com/moby/moby/issues/2838#issuecomment-29205965)

docker run -t -i -p 4000:80 friendlyhello

4 Likes

Thank you! I’ve been trying to figure this out for the past 2 hours haha

Try "Shift + Alt +C " - it works - It basically kills the foreground process

otherwise always try to spin the containers background to avoid such issues - docker run -d

Thanks a lot for this. Not only does this allow me to both ctrl-c and run commands while image is running, it also enables ASCII colors and formatting. Would you be able to tell me what exactly the --tty flag is doing here? I don’t have much exposure to tty, and the bit of research I’ve done hasn’t helped me understand what’s going on here in the context of Docker.

Well thank u man…u are savior…Thanks for the help!

Nice trick. Keep it up

Thank you. That’s clean.

1 Like

For future reference, see also the notes on PID 1 and using exec in Best practices for writing Dockerfiles, and ENTRYPOINT in Dockerfile reference.

docker run -it image

I believe it is also possible to use

ENTRYPOINT exec "/go/bin/myapp"

Am I right about that?