Docker: how to send a signal from one running container to another one?

7.4k Views Asked by At

I'm using docker, and I would like to know: Is it possible to send a signal, from a running container to another running container ?

More precisely, I would like to send SIGUSR1 to python program.

I already made a bash script to get pid of my python process and send the signal:

send_signal.sh

#!/bin/bash py_pid=$(pidof -s python my_programme.py kill -SIGUSR1 $py_pid

Before, I executed send_signal.sh from Docker host like that:

docker exec docker_with_python bash send_signal.sh

Or simply like that:

docker kill --signal="SIGUSR1 docker_with_python

But now, I would like to send signal to a running container to another one. So, how could I execute this command from another running container. Or is there another way of send a signal ?

Thanks in advance

4

There are 4 best solutions below

2
On BEST ANSWER

This is the code I used. It could help someone else:

echo -e "POST /containers/<docker_id>/kill?signal=SIGUSR1 HTTP/1.0\r\n" | nc -U /tmp/docker.sock

Previously, in my docker-compose.yml, I shared volumes:

example1:
   hostname: example_1
   volumes:
     - /var/run/docker.sock:/tmp/docker.sock
1
On

To accomplish this you'd want to mount Docker socket from host machine into the container you'd like to be sending signals from. See, for instance, this post for explanation and details.

0
On

From within a Python codebase, one may consider using Docker SDK for Python in order to send a signal to a process running into a container from another container.

from docker import DockerClient

client = DockerClient(base_url='unix:///tmp/docker.sock')
container = client.containers.get('<container name goes here>')
container.exec_run(['kill', '-SIGUSR1', '1'])
0
On

You can do this in python by overriding the socket of an HTTPConnection

import socket
from http.client import HTTPConnection

f = '/var/run/docker.sock' # Or wherever you've mounted it to in the container
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect(f)

conn = HTTPConnection('notused')
conn.sock = s
conn.request('POST', '/containers/<docker_id>/kill?signal=SIGHUP')
resp = conn.getresponse()

print(resp.status)
print(resp.headers)
print(resp.read())

The advantage is that you can check the status for success (a 204). And if the status indicates an error, the response body will have an error message.

As indicated in the accepted answer, you will need to mount the docker socket if you're doing this from within a container: -v /var/run/docker.sock:/tmp/docker.sock and change the code to point to the right socket.