Popen.wait never returning with docker-compose

Question:

I am developing a wrapper around docker compose with python.
However, I struggle with Popen.

Here is how I launch launch it :

import subprocess as sp
argList=['docker-compose', 'up']
env={'HOME': '/home/me/somewhere'}
p = sp.Popen(argList, env=env)
def handler(signum, frame):
  p.send_signal(signum)
for s in (signal.SIGINT,):
  signal.signal(s, handler) # to redirect Ctrl+C
p.wait()

Everything works fine, when I hit Ctrl+C, docker-compose kills gracelly the container, however, p.wait() never returns…

Any hint ?

NOTE : While writing the question, I though I needed to check if p.wait() does actually return and if the block is after (it’s the last instruction in the script). Adding a print after it end in the process exiting normally, any further hints on this behavior ?

Asked By: hl037_

||

Answers:

When I run your code as written, it works as intended in that it causes docker-compose to exit and then p.wait() returns. However, I occasionally see this behavior:

Killing example_service_1  ... done
ERROR: 2

I think that your code may end up delivering SIGINT twice to docker-compose. That is, I think docker-compose receives an initial SIGINT when you type CTRL-C, because it has the same controlling terminal as your Python script, and then you explicitly deliver another SIGINT in your handler function.

I don’t always see this behavior, so it’s possible my explanation is incorrect.

In any case, I think the correct solution here is imply to ignore SIGINT in your Python code:

import signal
import subprocess

argList = ["docker-compose", "up"]
p = subprocess.Popen(argList)
signal.signal(signal.SIGINT, signal.SIG_IGN)  # to redirect Ctrl+C

p.wait()

With this implementation, your Python code ignores the SIGINT generated by CTRL-C, but it is received and processed normally by docker-compose.

Answered By: larsks
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.