Docker-Machine and Visual Studio Tools for Docker

If you’re using Docker Tools for Visual Studio, version 0.14 or later, you’ll notice that we depend on a docker-machine entry.  What exactly does that mean?

We wanted the Docker Tools for Visual Studio to align with the Docker tools from Docker. It doesn’t make sense for us to have different ways to reference remote hosts, and how the VS Tools resolve certs for hosts. In earlier builds, using the “publishing” UI, we placed certs in the root of the .docker folder. This meant the tools couldn’t work with multiple hosts, unless each had the same certs. When we moved the tools over to the inner loop, develop and test in a container scenarios, we moved to using docker-machine to resolve hosts.

An example: When routing calls to a docker host, you likely use docker-machine env to set the environment variables. Docker-machine stores these certs under the machines path.

Look under: %userprofile%.dockermachinemachinesazurehost

When you run commands against a docker host, you’ll first use something similar to the following command

docker-machine env azurehost | Invoke-Expression

Which sets several environment variables:

$Env:DOCKER_HOST = "tcp://"
$Env:DOCKER_CERT_PATH = "C:UsersSteveLas.dockermachinemachinesazurehost"
$Env:DOCKER_MACHINE_NAME = "azurehost"

When you issue docker commands, the docker CLI, including docker-compose, will use these environment variables to connect to the remote host

Targeting different Hosts

If you look at the files scaffolded into your project, you’ll notice DockerDockerTask.ps1

Within the dockerTask.ps1 file, we check what host you wish to target and use docker-machine to set the environment variables. Remember, environment variables are only set per process. Setting docker-machine env in one PowerShell instance doesn’t impact other sessions, or the session VS uses.

if (![System.String]::IsNullOrWhiteSpace($Machine)) {
# Set the environment variables for the docker machine to connect to
docker-machine env $Machine | Invoke-Expression

The $Machine variable comes from PropertiesDocker.props See here for the docs on the flow.

Note: you do need to restart VS for the docker.props file to be read. This is a temporary solution. We do have a backlogged item to replace this with some UI that will not require VS to restart to read the value. 

Do I need docker-machine installed on hosts that run the PowerShell script

Yes, and no.

As you see in the Docker-Task.ps1 script, we are using docker-machine env to set the environment variables for each session. These scripts are scaffolded into your project, which means they’re your scripts. We very explicitly gave you the script so you can edit it, as that was one of the biggest pieces of feedback from our earlier publish tools. You can bypass the docker-machine call, and set the environment variables directly if you’d like.

However, if you remove the docker-machine call, you still need the certs for the client to call the docker host. The steps involve:

  1. Copying the certs under %userprofile%.dockermachinemachines[yourhost] from the machine you created them upon, to the remote machine.
  2. If you are using docker-machine, you’ll need to update %userprofile%.dockermachinemachines[yourhost]config.json to reference the correct paths on the remote machine

"AuthOptions": {
"CertDir": "C:\Users\SteveLas\.docker\machine\certs",
"CaCertPath": "C:\Users\SteveLas\.docker\machine\certs\ca.pem",
"CaPrivateKeyPath": "C:\Users\SteveLas\.docker\machine\certs\ca-key.pem",

What about the Docker  for Windows beta?

If you’re using Docker For Windows beta, you no longer need docker-machine env. If no environment variables are set, the docker CLI knows where to find the host. Looking at the DockerTask.ps1 script, you’ll notice we only call docker-machine env if there’s a machine name. When using Docker for Windows, blank out the entry in docker.props

<DockerMachineName Condition=" '$(DockerMachineName)'=='' "></DockerMachineName>

Hopefully that gives a little insight to the docker flows. Does this match your flows? Are you doing something different that we should incorporate into the tools?  Please let us know