Remote Deploy with Docker-Compose to Unraid
Jacob Korsgaard
Posted on March 16, 2021
In my previous post I built a couple of containers with docker-compose. Now I'd like to share how I deploy those containers to my Unraid server using SSH.
I've had two goals, from my Windows machine I'd like to:
- Deploy my containers to Unraid
- Iterate on the containers locally
Multiple configurations with docker-compose
The first thing I tackled was figuring out how to customize my docker compose files based on the target I'm building for.
It turns out the tool for that is Multiple Compose Files.
By default when you run docker-compose
, the tool read two files from the target directory docker-compose.yml
and docker-compose.override.yml
. These two files are effectively merged to create the configuration. The thought is you'd put the common configuration into docker-compose.yml
and your development settings into the override.
docker-compose.yml
version: "3.8"
services:
nodeserver:
build:
context: ./home-video-server
nginx:
restart: always
build:
context: ./home-server-nginx
docker-compose.override.yml
version: "3.8"
services:
nodeserver:
volumes:
- c:\Users\jacob\videos:/media
nginx:
restart: always
ports:
- "81:80"
volumes:
- ./home-video/www:/data
- c:\Users\jacob\videos:/media
When you want to run a command using a different configuration, what you do is you explicitly declare exactly which files to use in the configuration. I created a docker-compose.prod.yml
with the settings for the Unraid containers.
docker-compose.prod.yml
version: "3.8"
services:
nodeserver:
volumes:
- /mnt/user/kids:/media
nginx:
restart: always
ports:
- "9000:80"
volumes:
- /mnt/user/web:/data
- /mnt/user/kids:/media
the command I run when building for unraid is then
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up --build
Using Contexts to target Unraid
Now to actually send those containers to Unraid using docker-compose.
There are a number of different methods you can use, I found this nice article going over some of them: How to deploy on remote Docker hosts with docker-compose
Contexts is the weapon of choice and it's fairly straightforward. First we have to create a context, which is a named connection string basically. Then we have to use that context in all our docker commands to make them execute on the target.
Create a context called 'remote'
docker context create remote ‐‐docker “host=ssh://user@remotemachine”
This command will use SSH to connect to a 'docker endpoint' (that's the --docker part). Docker Context Documentation
For Unraid, it'll look something like this:
docker context create unraid ‐‐docker “host=ssh://root@tower”
Our command from before now becomes the following:
docker-compose --context unraid -f docker-compose.yml -f docker-compose.prod.yml up --build
SSH to Unraid (Use SSH Keys)
If you tried running this you would be asked for your root password roughly a 100 times and it's likely the job would fail anyway.
Because docker-compose executes so many commands over the SSH connection, it will need the password many times. We can't have that and will have to setup an SSH key.
Before that though: SSH doesn't work on Unraid by default (Access Denied error). You have to login to Unraid and give the root user a password before you can SSH. It's not enough to create a new user and give that a password, root has to have a password.
What we need to do now is generate an SSH key on our Windows 10 machine. Then copy the public part of the key to Unraid.
I used this guide to help me with SSH keys How To Set Up SSH Keys
You should already have a version of OpenSSH installed on your Windows machine in c:\Windows\System32\OpenSSH
. So from a command line, you can generate a key like this:
ssh-keygen -t rsa
Let it install this into your user folder (c:\users\jacob\.ssh\id_rsa
).
Now we have to authorize that key on Unraid, by getting the public part of the key over to it.
Because you're playing with Docker on Windows with WSL2, we can use the WSL bash to get it across to Unraid. Fire up your WSL and use this command:
ssh-copy-id -i /mnt/c/Users/jacob/.ssh/id_rsa.pub root@tower
That's it! ...or is it?
ssh-agent: agent returned different signature type
If you try to run the docker command again, you'll have to put in your password still and you'll get this error/warning ssh-agent: agent returned different signature type
.
I found the answer and solution to this here.
It turns out the OpenSSH installation in Windows is old and incompatible. Specifically the ssh-agent
tool isn't good enough. So you'll have to go download another OpenSSH binary release extract it to your machine and use the instructions in the link above to register the ssh-agent.exe from that location instead of the default installation.
This is crappy, but it did solve the issue on my machine. A better way to do all this is probably to run all your docker stuff directly from WSL, which would have an updated SSH.
Now you should be set to run your docker-compose command against the Unraid context!
docker-compose --context unraid -f docker-compose.yml -f docker-compose.prod.yml up --build
Next up are tips for building and running the node.js applications.
Posted on March 16, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.