How to set docker-machine env for fabric local() commands

I’m trying to run commands against a docker-machine cloud provider, and so I need to take the contents of the command docker-machine env digitalocean which is typically as follows:

export DOCKER_HOST="tcp://"
export DOCKER_CERT_PATH="/Users/danh/.docker/machine/machines/digitalocean"
export DOCKER_MACHINE_NAME="digitalocean"
# Run this command to configure your shell:
# eval "$(docker-machine env digitalocean)"

and use the above as a shell prefix, such as:

  • I can't figure out this sequel pro and docker issue
  • Unable to migrate Django db when using docker container
  • Docker-compose error when try to start
  • reports tags in the web interface but we cannot some of them using the API
  • How to use Java Buildpack in Bluemix Docker?
  • How to change docker bridge address space (subnet)?
  • print 'outside with:' + local('echo $DOCKER_HOST')
    with prefix(local('docker-machine env digitalocean', capture=True)):
        print 'inside with:' + local('echo $DOCKER_HOST')
    with prefix('DOCKER_HOST="tcp://"'):
        print 'inside with (manual):' + local('echo $DOCKER_HOST')

    However this instead returns:

    outside with:tcp://
    inside with:
    inside with (manual):tcp://

    The only way I can see to get past this is to rip apart the result of local('docker-machine env digitalocean') manually. Surely there is a more fabric-esque way however?

  • How do I clean up cached partial images from a broken Docker pull?
  • Chef-Client fails to get the ruby gem during chef provisioning
  • If docker uses virtual machine to run on a mac then what is its advantage over vagrant?
  • Manage docker environment for Swarm running cluster with UPC
  • Visual Studio Docker Tools how to force a container rebuild from scratch
  • ELF Header or installation issue with bcrypt in Docker container
  • 2 Solutions collect form web for “How to set docker-machine env for fabric local() commands”

    Well, here’s the solution I’ve gone with so far, feels a bit hacky though:

    def dm_env(machine):
        Sets the environment to use a given docker machine.
        _env = local('docker-machine env {}'.format(machine), capture=True)
        # Reorganize into a string that could be used with prefix().
        _env = re.sub(r'^#.*$', '', _env, flags=re.MULTILINE)  # Remove comments
        _env = re.sub(r'^export ', '', _env, flags=re.MULTILINE)  # Remove `export `
        _env = re.sub(r'\n', ' ', _env, flags=re.MULTILINE)  # Merge to a single line
        return _env
    def blah():
        print 'outside with: ' + local('echo $DOCKER_HOST')
        with prefix(dm_env('digitalocean')):
            print 'inside with: ' + local('echo $DOCKER_HOST')


    outside with: tcp://
    inside with: tcp://

    Another way to get the required information is to use formatting templates for the output of the docker-machine inspect command, as also shown in the documentation.

    Note that curly brackets in Python strings need to be escaped by doubling them, so you end up having four opening and closing brackets each time.

    machine_name = dev
    machine_ip = local("docker-machine inspect --format='{{{{.Driver.IPAddress}}}}' {0}".format(machine_name), capture=True)
    machine_port = local("docker-machine inspect --format='{{{{.Driver.EnginePort}}}}' {0}".format(machine_name), capture=True)
    machine_cert_path = local("docker-machine inspect --format='{{{{.HostOptions.AuthOptions.StorePath}}}}' {0}".format(machine), capture=True)

    Now, you can use the shell_env context manager in order to temporarily point your Docker daemon to a remote machine by setting the according environment variables:

    from fabric.api import shell_env
    with shell_env(DOCKER_TLS_VERIFY='1',
                   DOCKER_HOST='tcp://{0}:{1}'.format(machine_ip, machine_port),
        # will print containers on the remote machine
        local('docker ps -a')
    # will print containers on your local machine 
    # since environment switch is only valid within the context manager
    local('docker ps -a') 
    Docker will be the best open platform for developers and sysadmins to build, ship, and run distributed applications.