[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-73220":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":17,"stars30d":18,"stars90d":16,"forks30d":16,"starsTrendScore":16,"compositeScore":19,"rankGlobal":10,"rankLanguage":10,"license":20,"archived":21,"fork":21,"defaultBranch":22,"hasWiki":21,"hasPages":21,"topics":23,"createdAt":10,"pushedAt":10,"updatedAt":30,"readmeContent":31,"aiSummary":32,"trendingCount":16,"starSnapshotCount":16,"syncStatus":33,"lastSyncTime":34,"discoverSource":35},73220,"unregistry","psviderski\u002Funregistry","psviderski","Push docker images directly to remote servers without an external registry","https:\u002F\u002Funcloud.run",null,"Go",4768,89,12,15,0,7,22,63.56,"Apache License 2.0",false,"main",[24,25,26,27,28,29],"containerd","docker","golang","kubernetes","oci","registry","2026-06-12 04:01:08","\u003Cdiv align=\"center\">\n  \u003Cimg src=\".github\u002Fimages\u002Flogo-light.svg#gh-light-mode-only\" alt=\"Unregistry logo\"\u002F>\n  \u003Cimg src=\".github\u002Fimages\u002Flogo-dark.svg#gh-dark-mode-only\" alt=\"Unregistry logo\"\u002F>\n  \u003Cp>\u003Cstrong>▸ Push docker images directly to remote servers without an external registry ◂\u003C\u002Fstrong>\u003C\u002Fp>\n\n  \u003Cp>\n    \u003Ca href=\"https:\u002F\u002Fdiscord.gg\u002FeR35KQJhPu\">\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fdiscord-5865F2.svg?style=for-the-badge&logo=discord&logoColor=white\" alt=\"Join Discord\">\u003C\u002Fa>\n    \u003Ca href=\"https:\u002F\u002Fx.com\u002Fpsviderski\">\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Ffollow-black?style=for-the-badge&logo=X&logoColor=while\" alt=\"Follow on X\">\u003C\u002Fa>\n    \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fsponsors\u002Fpsviderski\">\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FDonate-EA4AAA.svg?style=for-the-badge&logo=githubsponsors&logoColor=white\" alt=\"Donate\">\u003C\u002Fa>\n  \u003C\u002Fp>\n\u003C\u002Fdiv>\n\nUnregistry is a lightweight container image registry that stores and serves images directly from your Docker daemon's\nstorage.\n\nThe included `docker pussh` command (extra 's' for SSH) lets you push images straight to remote Docker servers over SSH.\nIt transfers only the missing layers, making it fast and efficient.\n\nhttps:\u002F\u002Fgithub.com\u002Fuser-attachments\u002Fassets\u002F9d704b87-8e0d-4c8a-9544-17d4c63bd050\n\n## The problem\n\nYou've built a Docker image locally. Now you need it on your server. Your options suck:\n\n- **Docker Hub \u002F GitHub Container Registry** - Your code is now public, or you're paying for private repos\n- **Self-hosted registry** - Another service to maintain, secure, and pay for storage\n- **Save\u002FLoad** - `docker save | ssh \u003Cremote server> docker load` transfers the entire image, even if 90% already exists\n  on the server\n- **Rebuild remotely** - Wastes time and server resources. Plus now you're debugging why the build fails in production\n\nYou just want to move an image from A to B. Why is this so hard?\n\n## The solution\n\n```shell\ndocker pussh myapp:latest user@server\n```\n\nThat's it. Your image is on the remote server. No registry setup, no subscription, no intermediate storage, no exposed\nports. Just a **direct transfer** of the **missing layers** over SSH.\n\nHere's what happens under the hood:\n\n1. Establishes SSH tunnel to the remote server\n2. Starts a temporary unregistry container on the server\n3. Forwards a random localhost port to the unregistry port over the tunnel\n4. `docker push` to unregistry through the forwarded port, transferring only the layers that don't already exist\n   remotely. The transferred image is instantly available on the remote Docker daemon\n5. Stops the unregistry container and closes the SSH tunnel\n\nIt's like `rsync` for Docker images — simple and efficient.\n\n> [!NOTE]\n> Unregistry was created for [Uncloud](https:\u002F\u002Fgithub.com\u002Fpsviderski\u002Funcloud), a lightweight tool for deploying\n> containers across multiple Docker hosts. We needed something simpler than a full registry but more efficient than\n> save\u002Fload.\n\n## Requirements\n\n### On local machine\n\n- Docker CLI with plugin support (Docker 19.03+)\n- OpenSSH client\n\n### On remote server\n\n- Docker is installed and running\n- SSH user has permissions to run `docker` commands (user is `root` or non-root user is in `docker` group — see\n  [Manage Docker as a non-root user](https:\u002F\u002Fdocs.docker.com\u002Fengine\u002Finstall\u002Flinux-postinstall\u002F#manage-docker-as-a-non-root-user)\n  for details)\n- If `sudo` is required, ensure the user can run `sudo docker` without a password prompt\n- Your server has internet access to [ghcr.io](https:\u002F\u002Fghcr.io) to pull the unregistry image\n  `ghcr.io\u002Fpsviderski\u002Funregistry:latest` on first `docker pussh` use.\n    - If your server requires a proxy to access the internet, configure Docker to use it by following the\n      [Daemon proxy configuration](https:\u002F\u002Fdocs.docker.com\u002Fengine\u002Fdaemon\u002Fproxy\u002F) guide.\n    - For air-gapped environments or where the access to [ghcr.io](https:\u002F\u002Fghcr.io) is restricted, you can preload the\n      image manually:\n      ```shell\n      # Get the needed unregistry image version from the plugin version output\n      docker pussh --version\n      # Will return:\n      #   ...\n      #   unregistry image: ghcr.io\u002Fpsviderski\u002Funregistry:X.Y.Z\n\n      # On a machine with internet access\n      docker pull ghcr.io\u002Fpsviderski\u002Funregistry:X.Y.Z\n      docker save ghcr.io\u002Fpsviderski\u002Funregistry:X.Y.Z | ssh user@server docker load\n      ```\n- Unregistry container requires access to the containerd socket at `\u002Frun\u002Fcontainerd\u002Fcontainerd.sock`, so the container\n  runs as `root` to have the necessary permissions\n\n## Installation\n\n### macOS\u002FLinux via Homebrew\n\n```shell\nbrew install psviderski\u002Ftap\u002Fdocker-pussh\n```\n\nAfter installation, to use `docker-pussh` as a Docker CLI plugin (`docker pussh` command) you need to create a symlink:\n\n```shell\nmkdir -p ~\u002F.docker\u002Fcli-plugins\nln -sf $(brew --prefix)\u002Fbin\u002Fdocker-pussh ~\u002F.docker\u002Fcli-plugins\u002Fdocker-pussh\n```\n\n### macOS\u002FLinux via direct download\n\nDownload the current version:\n\n```shell\nmkdir -p ~\u002F.docker\u002Fcli-plugins\n\n# Download the script to the docker plugins directory\ncurl -sSL https:\u002F\u002Fraw.githubusercontent.com\u002Fpsviderski\u002Funregistry\u002Fv0.4.2\u002Fdocker-pussh \\\n  -o ~\u002F.docker\u002Fcli-plugins\u002Fdocker-pussh\n\n# Make it executable\nchmod +x ~\u002F.docker\u002Fcli-plugins\u002Fdocker-pussh\n```\n\nIf you want to download and use the latest version from the main branch:\n\n```shell\ncurl -sSL https:\u002F\u002Fraw.githubusercontent.com\u002Fpsviderski\u002Funregistry\u002Fmain\u002Fdocker-pussh \\\n  -o ~\u002F.docker\u002Fcli-plugins\u002Fdocker-pussh\nchmod +x ~\u002F.docker\u002Fcli-plugins\u002Fdocker-pussh\n```\n\n### Debian\n\nVia unofficial repository packages created and maintained\nat [unregistry-debian](https:\u002F\u002Fgithub.com\u002Fdariogriffo\u002Funregistry-debian\u002F) by @dariogriffo\n\nYou can install unregistry the debian way by running:\n\n```sh\ncurl -sS https:\u002F\u002Fdebian.griffo.io\u002FEA0F721D231FDD3A0A17B9AC7808B4DD62C41256.asc | sudo gpg --dearmor --yes -o \u002Fetc\u002Fapt\u002Ftrusted.gpg.d\u002Fdebian.griffo.io.gpg\necho \"deb https:\u002F\u002Fdebian.griffo.io\u002Fapt $(lsb_release -sc 2>\u002Fdev\u002Fnull) main\" | sudo tee \u002Fetc\u002Fapt\u002Fsources.list.d\u002Fdebian.griffo.io.list\napt install -y unregistry\napt install docker-pussh\n```\n\nor in the releases page of the repository [here](https:\u002F\u002Fgithub.com\u002Fdariogriffo\u002Funregistry-debian\u002Freleases)\n\n### Windows\n\nWindows is not currently supported, but you can try using [WSL 2](https:\u002F\u002Fdocs.docker.com\u002Fdesktop\u002Ffeatures\u002Fwsl\u002F)\nwith the above Linux instructions.\n\n### Verify installation\n\n```shell\ndocker pussh --help\n```\n\n## ⚠️ Containerd image store configuration\n\nUnregistry stores images directly in containerd's image store, which is the underlying container runtime used by Docker.\nHowever, by default, Docker maintains its own separate storage layer and doesn't directly use images from containerd.\n\nWhen you enable [containerd image store](https:\u002F\u002Fdocs.docker.com\u002Fengine\u002Fstorage\u002Fcontainerd\u002F) in Docker, it allows Docker\nto directly use the same images that unregistry stores in containerd, eliminating duplication.\n\n### With containerd image store enabled (recommended)\n\n- Images pushed through unregistry are immediately available to Docker\n- No additional storage space is used (images are stored once in containerd)\n- Faster `pussh` operations without the additional pull step from unregistry to the classic Docker image store\n\n### Without containerd image store (default Docker behaviour)\n\n- After pushing, `pussh` runs an additional `docker pull` on the remote host to pull the image from unregistry to make\n  it available to Docker\n- Images are stored twice: once in containerd (by unregistry) and once in the classic Docker image store\n- These unmanaged images in containerd can fill up disk space over time. To manage them manually, use:\n  ```shell\n  sudo ctr -n moby images ls\n  sudo ctr -n moby images rm \u003Cimage>\n  ```\n\n### How to enable containerd image store\n\nPlease refer to the official Docker documentation:\n[Enable containerd image store on Docker Engine](https:\u002F\u002Fdocs.docker.com\u002Fengine\u002Fstorage\u002Fcontainerd\u002F#enable-containerd-image-store-on-docker-engine).\n\n> [!WARNING]\n> Switching to containerd image store causes you to temporarily lose images and containers created using the classic\n> storage driver. Those resources still exist on your filesystem, and you can retrieve them by turning off the\n> containerd image store feature.\n\n## Usage\n\nPush an image to a remote server. Please make sure the SSH user has permissions to run `docker` commands (user is\n`root` or non-root user is in `docker` group). If `sudo` is required, ensure the user can run `sudo docker` without a\npassword prompt.\n\n```shell\ndocker pussh myapp:latest user@server.example.com\n```\n\nWith SSH key authentication if the private key is not added to your SSH agent:\n\n```shell\ndocker pussh myapp:latest ubuntu@192.168.1.100 -i ~\u002F.ssh\u002Fid_rsa\n```\n\nUsing a custom SSH port:\n\n```shell\ndocker pussh myapp:latest user@server:2222\n```\n\nUsing a custom SSH config file:\n\n```shell\ndocker pussh myapp:latest prod-server -F ~\u002F.ssh\u002Fconfig.prod\n```\n\nPush a specific platform for a multi-platform image. The local Docker has to use\n[containerd image store](https:\u002F\u002Fdocs.docker.com\u002Fdesktop\u002Ffeatures\u002Fcontainerd\u002F) to support multi-platform images.\n\n```shell\ndocker pussh myapp:latest user@server --platform linux\u002Famd64\n```\n\nUse a specific unregistry image version on the remote host:\n\n```shell\nUNREGISTRY_IMAGE=ghcr.io\u002Fpsviderski\u002Funregistry:A.B.C docker pussh myapp:latest user@server.example.com\n```\n\n## Use cases\n\n### Deploy to production servers\n\nBuild locally and push directly to your production servers. No middleman.\n\n```shell\ndocker build --platform linux\u002Famd64 -t myapp:1.2.3 .\ndocker pussh myapp:1.2.3 deploy@prod-server\nssh deploy@prod-server docker run -d myapp:1.2.3\n```\n\n### CI\u002FCD pipelines\n\nSkip the registry complexity in your pipelines. Build and push directly to deployment targets.\n\n```yaml\n- name: Build and deploy\n  run: |\n    docker build -t myapp:${{ github.sha }} .\n    docker pussh myapp:${{ github.sha }} deploy@staging-server\n```\n\n### Homelab and air-gapped environments\n\nDistribute images in isolated networks that can't access public registries over the internet.\n\n## Advanced usage\n\n### Running unregistry standalone\n\nSometimes you want a local registry without the overhead. Unregistry works great for this:\n\n```shell\n# Run unregistry locally and expose it on port 5000\ndocker run -d -p 5000:5000 --name unregistry \\\n  -v \u002Frun\u002Fcontainerd\u002Fcontainerd.sock:\u002Frun\u002Fcontainerd\u002Fcontainerd.sock \\\n  ghcr.io\u002Fpsviderski\u002Funregistry\n\n# Use it like any registry\ndocker tag myapp:latest localhost:5000\u002Fmyapp:latest\ndocker push localhost:5000\u002Fmyapp:latest\n```\n\n### Custom SSH options\n\nNeed custom SSH settings? Use the standard SSH config file, or pass a specific config with `-F`:\n\n```shell\n# ~\u002F.ssh\u002Fconfig\nHost prod-server\n    HostName server.example.com\n    User deploy\n    Port 2222\n    IdentityFile ~\u002F.ssh\u002Fdeploy_key\n\n# Now just use\ndocker pussh myapp:latest prod-server\n\n# Or use an alternate config file\ndocker pussh myapp:latest prod-server -F ~\u002F.ssh\u002Fconfig.prod\n```\n\n## Third-party projects\n\n- https:\u002F\u002Fgithub.com\u002FSonOfBytes\u002Funregistry-action - GitHub Action to push Docker images to remote servers using\n  `docker-pussh` plugin for Docker CLI\n- https:\u002F\u002Fgithub.com\u002FRezaKargar\u002Fsetup-unregistry - GitHub Action to install `docker-pussh` plugin for Docker CLI\n- https:\u002F\u002Fgithub.com\u002Filoveitaly\u002Fdocker-image-cleanup - Python tool to manage Docker images in self-hosted registries by\n  automatically removing outdated images while preserving recent and actively used ones\n\n## Contributing\n\nFound a bug or have a feature idea? We'd love your help!\n\n- 🐛 Found a bug? [Open an issue](https:\u002F\u002Fgithub.com\u002Fpsviderski\u002Funregistry\u002Fissues)\n\n* 💡 Have questions, ideas, or need help?\n    * Start a discussion or join an existing one in\n      the [Discussions](https:\u002F\u002Fgithub.com\u002Fpsviderski\u002Funregistry\u002Fdiscussions).\n    * Join the [Uncloud Discord community](https:\u002F\u002Fdiscord.gg\u002FeR35KQJhPu) where we discuss features, roadmap,\n      implementation details, and help each other out.\n\n## Inspiration & acknowledgements\n\n- [Spegel](https:\u002F\u002Fgithub.com\u002Fspegel-org\u002Fspegel) - P2P container image registry that inspired me to implement a registry\n  that uses containerd image store as a backend.\n- [Docker Distribution](https:\u002F\u002Fgithub.com\u002Fdistribution\u002Fdistribution) - the bulletproof Docker registry implementation\n  that unregistry is based on.\n\n##\n\n\u003Cdiv align=\"center\">\n  Built with ❤️ by \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fpsviderski\">Pasha Sviderski\u003C\u002Fa> who just wanted to deploy his images\n\u003C\u002Fdiv>\n","Unregistry 是一个轻量级的容器镜像注册表，允许用户直接通过 SSH 将 Docker 镜像推送到远程服务器，而无需外部注册表。其核心功能是通过 `docker pussh` 命令仅传输缺失的镜像层，从而提高效率和速度。该工具使用 Go 语言编写，支持 containerd、Docker 和 Kubernetes 等技术栈。Unregistry 适用于需要在开发环境和生产环境之间快速安全地传输 Docker 镜像的场景，特别是在不希望公开代码或支付额外存储费用的情况下。它简化了镜像部署流程，避免了自托管注册表带来的维护成本和复杂性。",2,"2026-06-11 03:44:33","high_star"]