Deploying Docker images over SSH

Have I told you lately about my home server? If we’ve talked in person there’s a good chance I’ve yapped about it at length.

It’s nothing fancy in terms of hardware – literally just a Raspberry Pi 5 with a 4 TB hard drive – but it’s perfectly capable of running a handful of containers, and acts as our Jellyfin media server.

It’s a great testbed for personal projects too. I develop on Mac, so both devices are ARM64. This makes it really easy to build images on the Mac and push to the Raspberry Pi for deployment.

Let’s say I’m working on a project with a Dockerfile on my Mac. I run:

docker build -t my-image .

If this was an image I wanted to share with the world, I could sign up for a registry like Docker Hub, or GitHub Container Registry, and use docker push to upload it. In this case though, the image is a work in progress so I want to keep it private.

If you have SSH access to the other machine, you can copy an image with docker save and docker load. Here’s how you can save an image as a gzip archive, copy it to the other machine and load it:

docker save my-image -o image.tgz
scp image.tgz user@other-machine.local:
ssh user@other-machine.local
docker load -i image.tgz
rm image.tgz
exit

This works fine, but it can be simplified. Instead of saving the image to a file, we can pipe the stdout of docker save to the stdin of docker load:

docker save my-image | ssh user@other-machine.local 'docker load'

Did you know that Unix pipes work over SSH? It’s a neat little trick.

The image should now be available on the other machine. I use Portainer, so recreating a container with the new image is as simple as choosing ‘Duplicate/Edit’ and ‘Deploy the container’ with the same options.

I wouldn’t recommend this as a means for deploying production apps, but for small homelab projects it’s really useful. Hope it helps!

If you enjoyed this article let me know! Check the contact page to see where you can find me on the web