47

I have a program run in a docker container with detached mode.

So how to send a signal such as SIGINT to this program?

atupal
  • 16,404
  • 5
  • 31
  • 42

4 Answers4

101

You can use docker kill --signal="<signal>" <container name or id> to send any signal to the root process of a given container.

See https://docs.docker.com/engine/reference/commandline/kill/#send-a-custom-signal--to-a-container

Pratik
  • 959
  • 1
  • 14
  • 20
Andy
  • 35,844
  • 6
  • 43
  • 50
  • 1
    Yeah,but the program I want to send signal to is a program run in the container but not have to the root process. e.g. run a bash in a docker, then run a other command in the bash in docker. Thanks for your answer. – atupal Sep 06 '14 at 08:14
  • That's what this does. https://docs.docker.com/engine/reference/commandline/kill/ – FilBot3 May 02 '19 at 15:12
14

You can use nsenter to get into your container space and send your signal.

PID=$(docker inspect --format {{.State.Pid}} <container_name_or_ID>)
nsenter --target $PID --mount --uts --ipc --net --pid kill -SIGINT <PID of your program inside your container>

More info : http://jpetazzo.github.io/2014/06/23/docker-ssh-considered-evil/

Regan
  • 8,231
  • 5
  • 23
  • 23
  • 12
    You can now use `docker exec` instead of nsenter. https://docs.docker.com/reference/commandline/exec/ – Andy Jul 20 '15 at 19:07
  • 1
    New link for `docker exec`: https://docs.docker.com/engine/reference/commandline/exec/ – ipetrik Jun 06 '19 at 18:26
9
  • docker kill used to send signal to main container process i.e process with PID 1.
  • Any application with PID 1 can handle signals directly. Below command kill the main docker process: $ docker kill --signal="SIGTERM" container-id/name
  • But application which does not have PID 1 i.e application is background process:
    • We can not send single directly to any background process running within docker container.
    • In this case we need to trap and handle the user defined signal in the shell script running as entry point.
  • Let's we have the following Dockerfile. (Update it as per the application)

FROM centos:6.7
# Install/Deploye the service below.

# Copy the shell script.
COPY entrypoint.sh /home
EXPOSE 8080
ENTRYPOINT ["/home/entrypoint.sh"]

  • Below is the entrypoint.sh. (Update it it as per the application). Suppose we wants to restart a init.d service.

    #start the service
    /etc/init.d/<servicename> start
    pid="$!"
    
    # SIGUSR1- Single handler
    my_handler() {
        /etc/init.d/<servicename> restart
    }
    
    # Trap and handle the user defind singnal.
    trap 'my_handler' SIGUSR1
    
    # wait forever(Alive container.)
    while true
    do
        tail -f /dev/null & wait ${!}
    done
    
  • Build the docker image and run the container.
  • Now you can restart the service from Host machine: $docker kill --signal="SIGUSR1" container-id/name
NG_
  • 6,895
  • 7
  • 45
  • 67
Sudhanshu Dev
  • 360
  • 3
  • 9
  • If someone is looking for more explanation and complete code: https://medium.com/@gchudnov/trapping-signals-in-docker-containers-7a57fdda7d86 – vikramaditya234 Jul 12 '19 at 06:25
3

I managed to send a signal I want to a process(program) in docker container by:

  1. Getting the ID of the container - docker ps | grep yourProgramName - for me it looks like so - 4b6425cf4261
  2. Login into the container using docker exec -it 4b6425cf4261 bash
  3. List all the running processes with ps -A
  4. Find the PID of the process you want to send a SIGINT to
  5. Send the signal to it: kill -SIGINT PID (example: kill -SIGINT 15)
hipokito
  • 413
  • 4
  • 11