世界を動かす技術を、日本語で。

Show HN: Unregistry – レジストリなしでサーバーに「docker push」を直接行う

概要

Unregistry は外部レジストリ不要でDockerイメージをSSH経由で直接リモートサーバーへ転送 docker pussh コマンドで差分レイヤーのみ高速転送 インストールや使い方が簡単で、CI/CDやエアギャップ環境にも最適 Uncloud のために開発、スタンドアロン利用も可能 Windows はWSL2経由で一部サポート

Unregistryとは何か

  • Unregistry は軽量なコンテナイメージレジストリ
  • Dockerデーモンの image storage をそのまま利用
  • 外部レジストリや公開/有料リポジトリが不要
  • docker pussh コマンドでSSH経由で直接イメージ転送
  • 転送は 差分レイヤー のみ、効率的なデプロイ

従来の課題

  • Docker HubやGitHub Container Registryは 公開/有料 リポジトリ問題
  • 自己ホスト型レジストリ は運用・管理・ストレージコストが発生
  • docker save/load は全レイヤー転送で非効率
  • リモートビルドは サーバーリソース消費 ・デバッグ負担増大
  • シンプルに「AからBにイメージを送る」だけが難しい現状

Unregistryの解決策

  • docker pussh myapp:latest user@server で即座にリモート転送
  • レジストリ設定不要、中間ストレージ不要、ポート公開不要
  • SSHトンネル経由で 一時的なunregistryコンテナ を起動
  • ローカルから 差分レイヤーのみプッシュ
  • 転送後すぐにリモートでイメージ利用可能
  • 終了時にunregistryコンテナを自動削除・トンネルも閉じる
  • rsyncのような効率性 をDockerイメージ転送に実現

インストール方法

  • macOS/Linux (Homebrew)
    • brew install psviderski/tap/docker-pussh
    • プラグインとして使う場合はシンボリックリンク作成
      • mkdir -p ~/.docker/cli-plugins
      • ln -sf $(brew --prefix)/bin/docker-pussh ~/.docker/cli-plugins/docker-pussh
  • macOS/Linux (直接ダウンロード)
    • curl -sSL https://raw.githubusercontent.com/psviderski/unregistry/main/docker-pussh -o ~/.docker/cli-plugins/docker-pussh
    • chmod +x ~/.docker/cli-plugins/docker-pussh
  • Windows
    • 公式サポートなし、WSL2経由でLinux手順を利用
  • 動作確認
    • docker pussh --helpでインストール確認

基本的な使い方

  • リモートサーバーへイメージ転送
    • docker pussh myapp:latest user@server.example.com
  • SSH鍵認証利用時
    • docker pussh myapp:latest ubuntu@192.168.1.100 -i ~/.ssh/id_rsa
  • カスタムSSHポート指定
    • docker pussh myapp:latest user@server:2222
  • マルチプラットフォームイメージの特定プラットフォーム転送
    • docker pussh myapp:latest user@server --platform linux/amd64

主なユースケース

  • 本番サーバーへの直接デプロイ
    • 中間レジストリ不要、即時反映
  • CI/CDパイプライン
    • レジストリ構築不要、ビルド後に直接転送
  • ホムラボ・エアギャップ環境
    • インターネット非公開ネットワークでのイメージ配布

必要環境

  • ローカルマシン
    • Docker CLI(プラグイン対応版、19.03以上)
    • OpenSSHクライアント
  • リモートサーバー
    • Dockerインストール済み・稼働中
    • dockerコマンド実行権限(rootまたはdockerグループ所属ユーザー)
    • sudoが必要な場合はパスワード不要でsudo docker実行可能に設定
  • 推奨設定
    • リモート側/etc/docker/daemon.json"containerd-snapshotter": trueを追加、Docker再起動で効率化

応用・上級活用

  • スタンドアロンレジストリとしてunregistryを利用
    • docker run -d -p 5000:5000 --name unregistry -v /run/containerd/containerd.sock:/run/containerd/containerd.sock ghcr.io/psviderski/unregistry
    • 通常のレジストリ同様にタグ付け・プッシュ可能
      • docker tag myapp:latest localhost:5000/myapp:latest
      • docker push localhost:5000/myapp:latest
  • カスタムSSH設定
    • ~/.ssh/configで詳細なSSHオプション管理
    • ホスト名・ユーザー・ポート・鍵ファイル指定で柔軟運用

コミュニティ・貢献

  • バグ報告・要望
    • GitHubでissue登録
  • コミュニティ参加
    • Uncloud Discordで機能・実装・運用相談
  • インスピレーション元
    • Spegel (P2Pコンテナイメージレジストリ)
    • Docker Distribution (堅牢な公式レジストリ実装)
  • 開発者
    • Pasha Sviderski、Uncloud開発の副産物として公開

補足・開発背景

  • レジストリ経由の煩雑な運用から解放したいという動機
  • Dockerホスト上のimage storageを活用し、標準APIで公開する設計
  • docker pussh はSSHトンネル&一時unregistryコンテナ利用でクリーンな転送
  • Uncloudの一部として開発、スタンドアロンでも有用
  • 詳細・フィードバックはUnregistry GitHubUncloud GitHub参照

Hackerたちの意見

いいね!pusshコマンドは、最もエレガントなダジャレの一つとしての称号にふさわしいよね。覚えやすいし、自明だし、標準コマンドの姉妹コマンドからたった一文字離れてるだけだし。

その余分な's'は「sssh」のためだよ その余分な's'は何のため? それはタイプミスだよ

まあいいけど、docker push-over-sshみたいなもう少し正式なエイリアスがあってもいいかも。追記:これが重要だと思う理由は、共同で開発される自動化の中で、「pussh」はその機能に不慣れな人にはタイプミスと見なされて不必要な混乱を引き起こすかもしれないから。一方で「push-over-ssh」は明らかに意図的だよね。短縮形とフルフラグとして考えてみて。

ぶつかりやすいね!

おお、これでuncloudを知った!まさに探してたものにぴったりだ。dokkuみたいな、でももっとパワフルなサイドプロジェクト用のサーバーセットアップが欲しかったんだ。

まだ使ったことがないなら、Portainerをおすすめするよ。AWSでポータイナーのコミュニティエディションとエージェントを使って2つのEC2インスタンスを運用してるけど、すごくうまく動いてる。スタック機能(要はdocker composeだけど)もめっちゃ便利。一つのEC2インスタンスで、PortainerエージェントがCaddyをコンテナで動かしてて、ロードバランサーとリバースプロキシの役割を果たしてる。

それに、https://skateco.github.io/ もあるよ。ぱっと見、似てるみたい。

これ、ずっとあってもよかったのに!素晴らしいね。Dockerレジストリにも役割はあるけど、全体的にオーバーエンジニアリングされてて、ハッカー精神には反するよね。

いいプロジェクトだしアプローチも素晴らしい!高いレジストリにうんざりしてZotをセルフホスティングすることにしたけど、これはいくつかのユースケースにはずっと簡単そうだね。誰か、簡単に設定できて、安くて、使用量ベースのプライベートレジストリサービスがあればいいなって思ってる人いる?

これはクールなアイデアだね。Ansibleみたいなプッシュデプロイツールを使ってるシステムともうまく統合できそう。Dockerレジストリが24/7サポートされてない会社では、ホットフィックスデプロイメントのメカニズムとしても良さそうだし。OCIツール、例えばbuildahとかときれいに統合できるのかな?それとも両方にフルのDockerインストールが必要?まだ深く掘り下げてないけど、リモートサーバーにミニレジストリをブートストラップするのが、こういうセットアップでskopeoが動くための欠けてる部分みたいだね。

両方の端にDockerデーモンが必要だよ。これはSSHを介して二つのデーモンの間でレイヤーを共有する賢い方法だね。

リモート側にはcontainerdが必要だよ(DockerとKubernetesはcontainerdを使ってる)。クライアント側はレジストリアPIに対応してる何かが必要だね(OCI Distribution spec: https://github.com/opencontainers/distribution-spec)。UnregistryはAPIレイヤーのために公式のDockerレジストリコードを再利用してるから、見た目も使い心地もhttps://hub.docker.com/_/registryみたいだよ。クライアント側ではskopeo、crane、regclient、BuildKitなど、OCIレジストリに対応してるものを使えるけど、リモートホストでunregistryを手動で実行する必要があるよ。'docker pussh'コマンドはローカルDockerを使ってワークフローを自動化するだけだし。ちょっと見てみて、bashスクリプトだよ: https://github.com/psviderski/unregistry/blob/main/docker-pu... 自分なりの方法で簡単にハックできるよ。

Dockerが最初からこういう風に動かなかったのはすごくおかしいよね。ありがとう、かっこいいね!

画像をアーカイブにしてサーバーにプッシュし、サーバー上でアーカイブから実行することで、同じことはすでに実現できるよ。アーカイブとして保存するのはこんな感じ:docker save -o may-app.tar my-app:latest で、読み込むのはこう:docker load -i /path/to/my-app.tar Ansibleみたいなツールを使えば、「Unregistry」が自動でやってることを簡単に実現できるよ。GitHubのリポジトリによると、save/loadはネットワーク越しに全体のイメージを転送するという欠点があるみたいで、それは確かに問題かも。アーカイブファイルの代わりにイメージを管理する方が便利そうだね。

面白いアイデアだね。これ、デプロイをサービスに結びつけるっていう欠点があるかも。例えば、どうやってスケールアップしたり、レッド/グリーンデプロイをするの?(そのためにはプッシュを認識してる必要があるよね)。編集:そのためのものは存在する、uncloudだ!今知った!とはいえ、これはトレードオフだね。小規模で、HetznerのVM一台だけでシンプルさを重視してるなら(ローカルでイメージをビルドするのが気にならないなら)、すごくいいと思うよ。

ずっとunregistryが欲しかったんだ、素晴らしい仕事をありがとう!

俺はいつも「docker save」を使ってTARファイルを作って、それをサーバーにコピーしてから「docker load」を実行して、ターゲットマシンにインストールしてるよ。

これめっちゃ便利だね。トレントプロトコルを使って、全てのサーバーで共有できるようなものがあったらいいのに。