Unregistry – レジストリなしで「docker push」をサーバーへ直接転送
(github.com/psviderski)- Unregistryは、外部レジストリなしで Docker イメージをリモートサーバーへ直接転送できるオープンソースツール
docker pusshコマンドで SSH 経由によりリモートサーバーへイメージを効率的に転送し、すでに存在するレイヤーはスキップ- 従来の Docker Hub、自前レジストリ、save/load 方式の複雑さと非効率性を解消
- 本番環境へのデプロイ、CI/CD、閉域網環境などで、高速かつ安全なイメージ移送が大きな利点
- インストール、使い方、要件が非常にシンプルで、追加サービスの運用やポート公開が不要
Unregistry の紹介と主な利点
- Unregistryは、Docker デーモンのストレージから直接イメージを保存・提供する軽量イメージレジストリ
docker pusshコマンドを使うと、SSH 経由で外部レジストリなしにイメージをそのままリモート Docker サーバーへ移動可能- 転送時にはサーバー上にすでに存在するレイヤーを除外し、必要な部分だけを高速に転送できる
既存の Docker イメージ配布の問題点
- イメージをローカルでビルドしてからサーバーへ転送する際の選択肢は以下のとおり
- Docker Hub/GitHub Container Registry: コードを外部公開する必要がある、またはプライベートリポジトリ利用時に費用が発生
- 自前レジストリ: 別サービスの運用に加え、セキュリティやストレージ管理の負担が増加
- Save/Load: 常にイメージ全体を転送するため非効率
- サーバーで直接再ビルド: 時間とサーバーリソースの無駄、デバッグ上の問題が発生
Unregistry ソリューション
-
docker pussh myapp:latest user@serverコマンド一発で、中間ストレージなしに直接転送可能 -
追加のレジストリ設定、ポート公開、ストレージ準備、サブスクリプションは不要
-
転送の流れ
- SSH トンネルをリモートサーバーへ接続
- 一時的に unregistry コンテナを起動
- ランダムなローカルポートと unregistry ポートを接続
- docker push で存在しないレイヤーだけを転送(すぐに使用可能)
- unregistry コンテナと SSH トンネルを終了
-
rsyncのようなシンプルかつ効率的な方式 -
本プロジェクトは、Uncloudで複数の Docker ホストへコンテナをデプロイする際の複雑さを簡素化するために開発された
使用例
デプロイ先環境へ直接イメージを転送
- ローカルでビルドした後、そのまま本番サーバーへ push
docker build --platform linux/amd64 -t myapp:1.2.3 .docker pussh myapp:1.2.3 deploy@prod-serverssh deploy@prod-server docker run -d myapp:1.2.3
CI/CD パイプライン
- レジストリの複雑さなしにビルドとデプロイを実現
- GitHub Action YAML などから直接転送を利用可能
ホームラボ、インターネットのない閉域網環境
- イメージをインターネット上に公開せず、隔離ネットワークへ安全に転送
使い方
- SSH ユーザーアカウントがリモート上で docker コマンドを使用できる必要がある
- SSH 秘密鍵やカスタム SSH ポートなどの追加オプションに対応
- マルチプラットフォームイメージの転送にも対応(containerd ベースの場合)
要件
ローカル環境
- Docker CLI(プラグイン対応、19.03+)
- OpenSSH クライアント
リモートサーバー
- Docker がインストールされ、実行中であること
- ssh ユーザーが docker 権限を持っており、必要に応じてパスワードなしで
sudo dockerを実行できること - containerd image store を使用すると性能が向上
/etc/docker/daemon.jsonに次の設定を追加し、Docker の再起動が必要{ "features": { "containerd-snapshotter": true } }
高度な使い方
ローカルのスタンドアロンレジストリとして利用
- 追加コンポーネントなしで unregistry をローカルレジストリとして簡単に運用可能
- Docker コマンドで deploy と push が可能
SSH カスタムオプションの活用
- SSH config ファイルを利用して、追加認証やポートなど条件に応じた詳細設定が可能
コントリビューションとコミュニティ
- バグを発見した場合は GitHub Issue を活用
- Uncloud の Discord コミュニティで、機能・ロードマップ・実装詳細について議論可能
着想元と参考オープンソース
- Spegel: containerd ベースの P2P コンテナイメージレジストリ実装から着想を得ている
- Docker Distribution: 実際のレジストリ実装のベースとして使用
要約
- Unregistry は Docker イメージを簡単かつ高速にリモートサーバーへ直接移送できるツールで、レジストリ構築と管理の負担をなくす
- 本番環境へのデプロイ、CI/CD、閉域網などさまざまなシナリオで強力な利点を提供
- サーバーと管理者がシンプルにイメージだけを余計な手順なしで移動したい場合に非常に適している
1件のコメント
Hacker Newsの意見
サーバーの特性やセキュリティ境界、ハードニングの観点から、LinuxでHomebrewを使うことは勧めたくない。Linux向けインストールは後付けのように提供されているにもかかわらず、パッケージマネージャーというより碁盤の上のハトのように振る舞っているように見える
システムでAnsibleのようなプッシュ型デプロイツールをすでに使っている環境にはよく合いそうなクールなアイデアだと思う。また、Docker registryが24時間サポートされていない企業では、ホットフィックスのデプロイ手法としても適していそうに感じる。OCIツーリング(buildahなど)ともきれいに連携するのか、それとも両側にDocker一式のインストールが必要なのか気になっている。まだ本格的には掘っていないが、これに関連する作業をする予定で、skopeoがこのような環境で動くには、リモートサーバーで独自registryをブートストラップできる機能が不足していると感じていた
リモートサーバーにはcontainerdが必要で(DockerとKubernetesもcontainerdを使用している)、クライアント側はregistry APIを理解するものであれば何でも使える(OCI Distribution spec: https://github.com/opencontainers/distribution-spec)。Unregistryは公式Docker registryコードをAPIレイヤーとして再利用しており、Docker Hubのregistryに近い感覚になっている。skopeo、crane、regclient、BuildKitなどOCI registryを利用でき、これらを使うにはリモートホストでunregistryを直接実行する必要がある。
docker pusshコマンドはローカルDockerを活用してこの一連の流れを自動化する役割を担っている。bashスクリプトなので一度確認するのを勧める https://github.com/psviderski/unregistry/blob/main/docker-pussh両側にdocker daemonが必要。この方法は、2つのdaemonの間でlayerをssh経由で共有するという巧妙なやり方を使っている
pusshというコマンド名は覚えやすく自己説明的で、既存の標準コマンドと1文字違いしかない見事な言葉遊びだと思う「pussh」も悪くないが、自動化では
docker push-over-sshのような、もう少し明確な別名のほうが良さそうという意見。pusshを初見の人がタイプミスだと誤解する可能性があり、不要な混乱を生むかもしれない。短い版と完全なフラグ版の両方をサポートするとよいと思うsを1つ余分に使ったのはssshを表そうとしたのでは、という冗談交じりの説明があり、単なるタイプミスだと言う人もいるpusshという名前は他のコマンドと衝突する可能性があるこういう機能はもっと前からあるべきだったし、とてもクールだと思う。Docker registry自体には価値があるが、全体として複雑になりすぎていて、ハッカーマインドからは遠ざかってしまったと感じる
プロジェクトとアプローチが印象的。高価なregistryにうんざりしてZot(https://zotregistry.dev)のようなものを自前でホストしてみたが、この方法のほうがユースケースによってはずっと簡単に見えるという意見。簡単で安価、かつ従量課金のプライベートregistryサービスがもう少し一般的になってほしい
Dockerは最初からこう動くべきだったと思う。クールなアイデアだ
docker save -o my-app.tar my-app:latestで保存し、docker load -i /path/to/my-app.tarで読み込む。ansibleのような自動化ツールと組み合わせれば、Unregistryが自動化していることを自分で実現できる。ただし、save/load方式ではイメージ全体を毎回すべて転送しなければならず、イメージ管理もアーカイブファイルより便利だという点がgithub repoで述べられているこの種のツールとSSHツーリングを活用したセルフホスティングへの回帰は歓迎できるし、よくできた成果物だと思う。実際に使ってみるつもり
このツールのおかげでuncloudというプロジェクトを初めて知った。自分が求めていたdokkuのようなもので、しかもより強力なサーバーデプロイソリューションのように見えて興味深い
uncloudが自分にはよく合っているというフィードバックに共感する。気になる点があればDiscordでの問い合わせを歓迎する
https://skateco.github.io/ という似たアプローチのサービスもあるので参考までにおすすめ
Portainerを推薦。Portainer Community EditionとPortainer Agentを使ってAWS EC2 2台でうまく運用している。スタック機能(docker composeベース)が特に強みで、1台のEC2ではportainer agentがコンテナとしてCaddyを動かし、ロードバランサー兼リバースプロキシとして機能している
発想が新鮮。ただし、この方式はサービスデプロイと強く結びついているため、デプロイやスケーリング、たとえばブルー/グリーンデプロイでは「プッシュ」を認識する追加ロジックが必要になる。考えてみると、こうした役割はuncloudで実装されている構造だと分かった。しかし結局はトレードオフであり、1台のHetzner VMでシンプルさを重視するなら、ローカルでイメージをビルドするだけでも十分満足できる選択だ