In case we have multiple docker hosts, we can use docker-machine.
What is Docker Machine?
In a nutshell, docker-machine is used to manage remote docker daemons, basically automating the steps listed here. It makes docker listen on 0.0.0.0:2376 TCP, but allows connections only from clients with a valid certificate (a cert signed by the ca on the docker server). In practice, it would work like this:
run the command docker-machine create --driver generic --generic-ip-address=<ip docker host> --generic-ssh-key <path ssh key> --generic-ssh-user=root <docker machine name>
docker machine will create the certs, put them on the docker server and setup /etc/systemd/system/docker/service.d/10-machine.conf so the docker daemon will listen for remote connections and validate the clients with the generated certificates
On the client, docker machine put the client certificate and key (and the ca certificate) in ~/.docker/machine
Then you can use eval docker-machine env <machine> to load the environment variables letting you run docker command remotely on the <machine>. You can use docker-machine active to check if the environment variables are properly set. Any subsequent docker command will run on the remote docker host.
How to use that in our infrastructure?
On the server that hosts the drone CI agents, we can create the docker machines (one for each docker host), then in the .drone.yml file (this one for example), we can mount the .docker folder (where the docker machine configuration is) and eval the configuration for the target docker host, Then the rest remains the same: run docker compose to deploy the service, but this time it will get deployed remotely. The .drone.yml file would look like:
deploy: image: tmaier/docker-compose volumes: - /root/.docker:/root/.docker:ro - /var/run/docker.sock:/var/run/docker.sock commands: - wget https://github.com/docker/machine/releases/download/v0.16.0/docker-machine-$(uname -s)-$(uname -m) -O docker-machine - eval $(dokcer-machine env <target docker host>)' - docker-compose build - docker-compose up -d
Bonus point: this is backward-compatible, all the existing CI configuration in .drone.yml will continue to work (as long as the drone agents run on lund). So if we can afford to create a second docker host, we can migrate containers to it incrementally. This is a simple approach that adds very little complexity and yet allows us to easily choose where services are going to be deployed if we create more docker hosts.