5

I am running a container with docker-py in Python. Similar to the docs:

import docker
client = docker.from_env()
container = client.containers.run('bfirsh/reticulate-splines', detach=True)

The container performs some tasks and saves a .json file to a shared volume. Everything is working fine except that I do not know how to catch the container exit when running in the background. More specifically, my question is the following:

"Is there a way in docker-py to pass a callback function to a container running in detach mode?"

I want to access the saved .json on exit and avoid using ugly statements like time.sleep() or iterating while the status is running. From the docs it does not seem possible. Do you have any workaround to share?

s.dallapalma
  • 1,225
  • 1
  • 12
  • 35
  • Might there be a way to use Docker Events (which I'd never noticed before): https://docs.docker.com/engine/reference/commandline/events ? If the docker-py library doesn't support this, maybe there is other Python code out there that does. Just a thought but probably a long shot. My guess is that you're not going to find a solution that avoids polling the status of the container. Best of luck! – CryptoFool Nov 03 '20 at 16:36
  • Hi, thanks. The events APIs look fine. They are not supported by docker-py, though. I guess the way to go is to start a thread and iterating over the `container.status` until it exits and then perform the post-run tasks within that thread. – s.dallapalma Nov 04 '20 at 10:36

1 Answers1

1

Answering my own question, I adopted the following solution using threads.

import docker
import threading

def run_docker():
    """ This function run a Docker container in detached mode and waits for completion. 
        Afterwards, it performs some tasks based on container's result.
    """

    docker_client = docker.from_env()
    container = docker_client.containers.run(image='bfirsh/reticulate-splines', detach=True)

    result = container.wait()
    container.remove()

    if result['StatusCode'] == 0:
        do_something()  # For example access and save container's log in a json file
    else:
        print('Error. Container exited with status code', result['StatusCode'])


def main():
    """ This function start a thread to run the docker container and 
        immediately performs other tasks, while the thread runs in background.
    """

    threading.Thread(target=run_docker, name='run-docker').start()
    # Perform other tasks while the thread is running.
s.dallapalma
  • 1,225
  • 1
  • 12
  • 35