How to Install Unregistry on Debian: Push Docker Images Straight Over SSH

Unregistry is a small but clever tool that lets you push Docker images directly to a remote server over SSH, with no external registry standing in the middle. It stores images straight in the remote Docker daemon’s containerd storage and transfers only the layers the target is missing, which makes deployments fast and keeps you off Docker Hub, GHCR or a self-hosted registry entirely.

The workflow is exposed through a Docker CLI plugin called docker pussh (yes, the double “s” is intentional). You build an image locally, then run a single docker pussh myimage:latest user@host command and it lands on the remote machine ready to run. For small teams and self-hosters, this removes a whole moving part from the deployment pipeline: there is no registry to run, secure, back up or pay for.

Being a young, niche tool, Unregistry is not in the official Debian archives. The unofficial deb.griffo.io repository packages the docker-pussh plugin so you can install it — and keep it current — with plain apt, instead of manually dropping a script into ~/.docker/cli-plugins.

Install the Latest Unregistry on Debian: The Short Version

If you only came for the commands, this adds the repository and installs the latest Unregistry .deb package on Debian:

sudo install -d -m 0755 /etc/apt/keyrings
curl -fsSL https://deb.griffo.io/EA0F721D231FDD3A0A17B9AC7808B4DD62C41256.asc | sudo gpg --dearmor --yes -o /etc/apt/keyrings/deb.griffo.io.gpg
echo "deb [signed-by=/etc/apt/keyrings/deb.griffo.io.gpg] https://deb.griffo.io/apt $(lsb_release -sc 2>/dev/null) main" | sudo tee /etc/apt/sources.list.d/deb.griffo.io.list > /dev/null
sudo apt update
sudo apt install unregistry

The rest of this guide explains what each command does, how to verify the install, how to keep Unregistry up to date, and what to check when something goes wrong.

What Makes Unregistry Special?

  • 🚫 No registry required — push images straight to a host over SSH, skipping Docker Hub, GHCR and self-hosted registries.
  • 📦 Layer-aware transfers — only the layers the remote is missing are sent, so pushes are quick and bandwidth-light.
  • 🔌 Native Docker plugin — integrates as docker pussh, so it feels like a first-class Docker subcommand.
  • 🔐 SSH-based security — reuses your existing SSH keys and config; no new credentials to manage.
  • 🗄️ containerd storage — images land directly in the remote daemon’s store, ready to docker run.
  • 🏗️ Multi-platform aware — target a specific architecture with --platform for cross-arch deployments.
  • 🪶 Tiny footprint — the client is a single shell plugin, and the server side is a short-lived helper image.
  • 🔑 Flexible SSH options — custom keys, ports and SSH config files are all supported per push.

Why Use the deb.griffo.io Repository?

Installing the plugin from deb.griffo.io beats copying scripts around by hand:

  • Easy installation and updates through the APT package manager.
  • Automatic dependency management so prerequisites are pulled in for you.
  • Always tracks upstream releases of the docker-pussh plugin.
  • No manual file juggling in ~/.docker/cli-plugins.
  • Works across supported Debian releases, from Bookworm to Sid.

Prerequisites

Before you begin, make sure you have:

  • A Debian-based system (Bookworm 12, Trixie 13, or Sid)
  • sudo privileges
  • curl installed (sudo apt install curl if needed)
  • Docker installed locally, and SSH access to a remote host that also runs Docker

Step 1: Add the deb.griffo.io Repository

Add the signing key and repository to APT with the following block:

# Create the keyrings directory
sudo install -d -m 0755 /etc/apt/keyrings

# Download and install the repository GPG key
curl -fsSL https://deb.griffo.io/EA0F721D231FDD3A0A17B9AC7808B4DD62C41256.asc | sudo gpg --dearmor --yes -o /etc/apt/keyrings/deb.griffo.io.gpg

# Add the repository (auto-detects your distro codename)
echo "deb [signed-by=/etc/apt/keyrings/deb.griffo.io.gpg] https://deb.griffo.io/apt $(lsb_release -sc 2>/dev/null) main" | sudo tee /etc/apt/sources.list.d/deb.griffo.io.list > /dev/null

# Update the package list
sudo apt update

What each step does:

  1. Keyrings directory — creates /etc/apt/keyrings to hold the signing key.
  2. GPG key — downloads the key and stores it de-armoured for APT.
  3. Repository entry — writes the source list, filling in your Debian codename via lsb_release -sc.
  4. Update — refreshes APT so the new package is visible.

Step 2: Update the Package List

If you skipped the last line above, update the index now:

sudo apt update

Step 3: Install Unregistry

Install the package with APT:

sudo apt install unregistry

This installs the docker-pussh CLI plugin and registers it with your Docker client.

Step 4: Verify the Installation

The plugin binary is docker-pussh, but you invoke it through Docker as docker pussh. Check it is wired up correctly:

docker pussh --help

You should see usage output similar to:

Usage: docker pussh [OPTIONS] IMAGE[:TAG] [USER@]HOST[:PORT]

Push a Docker image to a remote host over SSH without an external registry.

Options:
  -i FILE            SSH private key to use
  -F FILE            SSH config file to use
  --platform STRING  Push a specific platform (e.g. linux/amd64)
  -h, --help         Show this help message

If Docker reports that pussh is not a docker command, see the troubleshooting section below.

Getting Started with Unregistry

With the plugin installed, pushing an image is a one-liner. Everything happens over your existing SSH connection.

Push Your First Image

Build an image locally, then push it to a remote host. Unregistry spins up a temporary helper on the target, transfers the missing layers and tears the helper down again:

# Build an image locally
docker build -t my-app:latest .

# Push it straight to the remote host over SSH
docker pussh my-app:latest deploy@203.0.113.10

Once the push finishes, the image exists in the remote Docker daemon and you can docker run my-app:latest there immediately — no docker pull needed.

Use a Specific SSH Key or Port

Because it rides on SSH, all the familiar connection options apply. Pass a private key with -i, or specify a non-standard port after the host:

# Push using an explicit SSH key
docker pussh my-app:latest ubuntu@203.0.113.10 -i ~/.ssh/deploy_key

# Push to a host listening on a custom SSH port
docker pussh my-app:latest deploy@203.0.113.10:2222

Reuse Your SSH Config

If you already define hosts in ~/.ssh/config, refer to them by their alias, or point the plugin at a specific config file with -F:

# 'prod' is a Host entry in your SSH config
docker pussh my-app:latest prod

# Use a dedicated SSH config file
docker pussh my-app:latest prod-server -F ~/.ssh/config.prod

Push a Specific Platform

For multi-architecture builds, select the platform you want to land on the target:

# Push only the amd64 variant
docker pussh my-app:latest deploy@203.0.113.10 --platform linux/amd64

Pin the Unregistry Helper Version

The push uses a small helper image on the remote side. To pin it to a known version, set UNREGISTRY_IMAGE:

UNREGISTRY_IMAGE=ghcr.io/psviderski/unregistry:0.4.3 \
  docker pussh my-app:latest deploy@203.0.113.10

A typical deploy loop then becomes: build locally, docker pussh to the server, and docker compose up -d over SSH to roll the new image out.

Keeping Unregistry Updated

Since the plugin was installed from APT, updating it is routine:

sudo apt update && sudo apt upgrade

This keeps docker-pussh in step with upstream. When you bump the client, it is a good idea to let it pull a matching helper image on the next push, or pin one explicitly with UNREGISTRY_IMAGE as shown above.

Other Tools from deb.griffo.io

The repository is full of tools that complement a registry-free deployment workflow. A few that pair well with Unregistry:

  • Lazydocker — a terminal UI for Docker, handy for inspecting the images you have just pushed.
  • Uncloud — deploy containers across multiple hosts once your images are in place.
  • k9s — a terminal UI for Kubernetes when you graduate to a cluster.
  • Forgejo — a self-hosted Git forge to store the Dockerfiles behind your images.

Troubleshooting

GPG or Key Issues

If APT reports the repository is unsigned or the key has expired, re-add the signing key:

# Remove the existing key
sudo rm -f /etc/apt/keyrings/deb.griffo.io.gpg

# Re-download and install it
curl -fsSL https://deb.griffo.io/EA0F721D231FDD3A0A17B9AC7808B4DD62C41256.asc | sudo gpg --dearmor --yes -o /etc/apt/keyrings/deb.griffo.io.gpg

sudo apt update

Package Not Found

If apt install unregistry cannot find the package:

  1. Confirm you ran sudo apt update after adding the repository.
  2. Check your Debian release is supported (Bookworm, Trixie, or Sid).
  3. Inspect the source file: cat /etc/apt/sources.list.d/deb.griffo.io.list

docker: 'pussh' is not a docker command

If Docker does not recognise the subcommand after installation, the CLI plugin is not being discovered. Docker looks for plugins in ~/.docker/cli-plugins for the current user, so confirm the executable is present and runnable:

ls -l ~/.docker/cli-plugins/docker-pussh
chmod +x ~/.docker/cli-plugins/docker-pussh

If you install as one user but run Docker as another (for example via sudo), make sure the plugin exists in the correct home directory. A fresh docker pussh --help should then work.

Uninstalling

To remove Unregistry:

# Remove the package
sudo apt remove unregistry

# Optionally remove the repository and key
sudo rm -f /etc/apt/sources.list.d/deb.griffo.io.list
sudo rm -f /etc/apt/keyrings/deb.griffo.io.gpg
sudo apt update

Any images you already pushed to remote hosts stay exactly where they are; removing the plugin only affects your ability to push new ones.

Conclusion

Unregistry removes an entire layer of infrastructure from container deployment. Instead of standing up a registry, pushing to it and pulling on the far side, you push images directly to the servers that will run them, over the SSH access you already have. Only missing layers travel the wire, so it stays quick even over modest connections.

Installing it from deb.griffo.io means the docker pussh plugin is a single apt install away, and stays current with a routine apt upgrade — no scripts to copy, no plugin directory to manage by hand.

Frequently Asked Questions

How do I install the latest Unregistry on Debian?

Add the deb.griffo.io APT repository and its signing key, then run sudo apt install unregistry. The repository tracks upstream Unregistry releases, so you get the latest packaged version rather than a build frozen when your distribution was released.

Is there a .deb package for Unregistry?

Yes. deb.griffo.io publishes Unregistry as a signed .deb for Debian. You could download that .deb and install it by hand, but adding the repository is the better option: APT then resolves dependencies and picks up new versions on its own.

How do I update Unregistry to the latest version?

Run sudo apt update && sudo apt upgrade. Once Unregistry is installed from APT there is no separate updater to remember, since new releases arrive with the rest of your system updates.

How do I install Unregistry on Ubuntu?

Exactly the same way; lsb_release -sc simply resolves to a different codename. There is a companion guide with the Ubuntu specifics: How to install Unregistry on Ubuntu.

Which Debian releases are supported?

Bookworm 12, Trixie 13 and Sid. Because the repository line is built from lsb_release -sc, the matching suite is selected for you.

Resources


Disclaimer: The deb.griffo.io repository is an unofficial community project and is not affiliated with the official Debian or Ubuntu projects, or with the upstream Unregistry project.