Search code examples
pythondocker-composecommand-line-interfacefabric

Running docker-compose up with Python's 'fabric'


I am using Docker (+ Docker Compose). All docker-compose interaction occurs via the Python 'fabric' package (v1).

Example:

def runserver():
    local('docker-compose up')

and:

$ fab runserver

Everything behaves normally until I attempt to ^C out of a running docker-compose up:

  1. docker-compose appears to receive the ^C (SIGINT?) signal as it starts stopping my containers - e.g.:
Stopping celery-export ... done
Stopping celery        ...

However during the container stopping process (sometimes as long as 10 seconds if a container doesn't respond to signals properly), I can press enter / return and see / interact with my shell (as if the process has ended).

Though at this stage the containers haven't finished stopping yet (there's not a done next to each Stopping ... line). It's as if I've prematurely been given access to my shell, which I can freely use. If a late-finishing container eventually stops (usually after 10 seconds), it'll draw the done line over what I'm currently doing in my terminal.

Example:

Stopping celery-export ... done
Stopping celery        ...
Stopping redis         ...

$ uptime 
10:54  up 1 day, 17:22, 2 users, load averages: 1.73 1.94 1.92
Stopping celery        ... done
Stopping redis         ... done

This does not occur when I call docker-compose up directly (outside of fabric) so I suspect that it's something to do with fabric wrapping the execution of the command.

The expected behaviour being that I cannot access my shell until after the container stopping process finishes.

Forgive my lack of proper terminology for describing this issue, and if this'd be more appropriate on Superuser instead of SO.


Solution

  • Fabric 1.x has split into two projects, 'Invoke' (inv) is the replacement package for running local commands, and what is relevant here.

    Invoke has made drastic improvements in this area, and no longer has this issue. It is relatively easy to migrate from Fabric 1.x to Invoke. I do not see the potential for any fix in Fabric 1.x. My solution was to use Invoke instead.