Using Docker Machine to provision a remote docker host
Tags: docker, containers
Published: 2019-04-06 22:43:18

---
title: Using Docker Machine to provision a remote docker host
published: true
description: A guide on how to run your docker containers on a remote host
tags: docker, containers
---

This article originated on [zsiegel.com](https://zsiegel.com/2019/04/06/using-docker-machine-to-provision-a-remote-docker-host)

Like many developers my primary machine is a laptop and when developing applications I typically use Docker containers to provide local instances of  databases, caches, message queues, and other supporting services. 

When running these services via Docker this can often wreak havoc on my machine and cause it to slow down to a crawl even with lots of ram and CPU power. I began exploring options on how to get the ease and flexibility of Docker but use remote computing resources instead. I found that Docker has a great tool for enabling this type of workflow where the containers run on a different host but you can still access them just like they were on your machine. 

## Docker Machine
Docker has a built in tool called `docker-machine` that allows you to provision many different types of remote machines as docker hosts. In order for this to run all you need is a remote system that you have SSH access to. Docker can then provision that remote system and your local `docker` tools can interface with it instead of your local machine.

This allows you to run all sorts of heavier services on the remote machine instead of your local machine. Let’s take a look at how you might provision a simple docker host on a home server.

## Docker Machine drivers
Take a look through the [documentation](https://docs.docker.com/machine/drivers/) and find what driver is appropriate for you. They provide many cloud drivers for running docker instances remotely. In this case we are going to provision a [generic](https://docs.docker.com/machine/drivers/generic/) host on a ubuntu server running I have running in my home office.

I went ahead and installed Ubuntu 18.04 LTS and I have a basic root account setup. The first thing we need to do is enable SSH key authentication.

## SSH Key Authentication

We are going to start by generating a set of keys to use for authentication with  [ssh-keygen](https://www.ssh.com/ssh/keygen/). I named my keys `zdocker` since that is the hostname of the server I will be connecting to in my office.

Once these keys are generated you can utilize a tool called [ssh-copy-id](https://www.ssh.com/ssh/copy-id) to automatically transfer the public key information to your server. In my case the command looked something like the following.

```bash
ssh-copy-id -i ~/.ssh/${PUBLIC_KEY} ${USERNAME}@${IP_ADDRESS} 
```

You will want to replace the placeholders above with the `public_key, username, and ip_address` of your server in the command above. Once transferred you can now log into your server via public key authentication. I then went ahead and disabled password login via SSH since the only way we will allowing logins going forward is with the keys.

```bash
nano /etc/ssh/sshd_config
```

```
# Turn off PasswordAuthentication by setting the value to no 
# and making sure it is not commented out like below
ChallengeResponseAuthentication no
PasswordAuthentication no
UsePAM no
```

Now that we have SSH key authentication we need to enable password-less sudo privileges for the user that we intent to login with. This is required by the docker-machine installer. 

### Edit the sudoers file
```bash
sudo visudo
```

```
# Insert a new entry at the bottom that enables passwordless sudo
${USERNAME} ALL=(ALL) NOPASSWD: ALL
```

You will want to replace the `username` with the user that you have created on the machine.

## Provision a Docker host

Now that we have SSH public key authentication setup with root access its time to let `docker-machine` provision our server.

```bash
docker-machine create \
	--driver generic \
	--generic-ip-address=$IP_ADDRESS \
	--generic-ssh-user $USERNAME \
	--generic-ssh-key ~/.ssh/$PRIVATE_KEY \
	zdocker

```

You will want to replace the placeholders above with the `ip_address, username, private_key, and machine_name` which in my example is `zdocker`. 

Note that the `machine_name` will be what shows up in your CLI tool when you run `docker-machine ls` . It is how you will reference this remote docker instance when choosing which docker host to use for running your services.

If the provisioning was a success you will be greeted with some output similar to what is below.

```bash
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.1.10:2376"
export DOCKER_CERT_PATH="/path/to/a/cert"
export DOCKER_MACHINE_NAME="zdocker"
# Run this command to configure your shell: 
# eval $(docker-machine env zdocker)
```

Next run the eval command in your current shell to point your `docker` CLI at the remote host.

```bash
eval $(docker-machine env zdocker)
```

You now have  `docker`  pointed at a remote docker host.  Within this shell all docker commands will utilize the remote system to do its work and your laptops hardware can breathe a little bit easier!