サクッとHarborを建ててみる
最近 PrivateRepository で主だった開発を進めている都合で GitHub Actions の利用上限に当たってしまい、自宅 K8s クラスタで ARC の運用を開始しました
しかし、セルフホストした ARC 上で Docker イメージをビルドしようすると、Docker Hub の pull 上限 Docker Hub usage and limits に引っかかってしまったり、ghcr.io からの pull に異様に時間がかかってしまったりと快適な開発体験とは言えない状況でした

そこで、試験的に Harbor を単一ノードで簡易的に建ててみました
0. Harbor とは

セルフホスト可能な OSS で開発されているコンテナレジストリです
Docker を用いた単一ノードへのインストールの他に K8s を用いた高可用構築も可能です
0-1. 最低要件
単一ノードで運用する際の最低要件は2Core/4GB RAM/40GB Storageとなっています
今回は単一ノードの最低要件に近い4Core/4GB/64GBのUbuntu 24.4を用意しました
1. Docker のインストール
ref: https://docs.docker.com/engine/install/ubuntu/
# Add Docker's official GPG key:
apt-get update
apt-get install ca-certificates curl
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null
apt-get update
apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
systemctl enable --now docker
2. SSL 証明書の用意
ref: https://certbot.eff.org/instructions?ws=other&os=pip
Harbor は SSL 証明書を要求します
自己署名証明書を使用することもできますが、今回はcertbotで証明書を取得します
著者は cloudflare を使用しているため、他の方法で認証を行う場合は適時調整して下さい
apt install python3 python3-dev python3-venv libaugeas-dev gcc
python3 -m venv /opt/certbot/
/opt/certbot/bin/pip install --upgrade pip
/opt/certbot/bin/pip install certbot certbot-dns-cloudflare
ln -s /opt/certbot/bin/certbot /usr/bin/certbot
certbot certonly --dns-cloudflare --dns-cloudflare-credentials <path-to-cred> -d <domain>
echo "0 0,12 * * * root /opt/certbot/bin/python -c 'import random; import time; time.sleep(random.random() * 3600)' && sudo certbot renew -q" | sudo tee -a /etc/crontab > /dev/null
取得した証明書のアドレスに、Harbor をインストールするホストのローカルアドレスを設定すると、ローカルネット上でも証明書付きの SSL 通信が可能になります
3. インストール準備
ref: https://goharbor.io/docs/2.14.0/install-config/download-installer/
https://github.com/goharbor/harbor/releases から最新版のリリース(今回の場合はv2.14.0)の Assets からオフラインインストーラーをダウンロードし展開します
wget https://github.com/goharbor/harbor/releases/download/v2.14.0/harbor-offline-installer-v2.14.0.tgz
tar xzvf harbor-offline-installer-v2.14.0.tgz
cd harbor
4. Harbor の設定
ref: https://goharbor.io/docs/2.14.0/install-config/configure-yml-file/
テンプレートをコピーし、ドメインと SSL の設定を行います
また、必要に応じて既定のアカウント admin のパスワードを更新して下さい
cp harbor.yml.tmpl harbor.yml
# Configuration file of Harbor
# The IP address or hostname to access admin UI and registry service.
# DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external clients.
hostname: <domain>
# http related config
http:
# port for http, default is 80. If https enabled, this port will redirect to https port
port: 80
# https related config
https:
# https port for harbor, default is 443
port: 443
# The path of cert and key files for nginx
certificate: /etc/letsencrypt/live/<domain>/fullchain.pem
private_key: /etc/letsencrypt/live/<domain>/privkey.pem
# enable strong ssl ciphers (default: false)
# strong_ssl_ciphers: false
#---(ry)---
# The initial password of Harbor admin
# It only works in first time to install harbor
# Remember Change the admin password from UI after launching Harbor.
harbor_admin_password: <password>
#---(ry)---
5. Harbor のインストール
以下のコマンドを実行することで docker compose で Harbor が起動します
./install.sh
6. Docker Proxy の設定
6.1 ダッシュボードへログイン
Harbor が起動したら設定したドメインを開いて証明書エラーなく Harbor のダッシュボードにアクセスできるか確認します

初期設定を変更していない場合、admin/Harbor12345 でログインできます
6.2 レジストリの追加
ダッシュボードにログインできたら サイドバーからAdministration > Registries を開き、NEW ENDPOINT をクリックして追加画面を開きます

Provider で Docker Hub を選択し、残りの項目を適当に埋めて OK を押します
6.3 プロジェクトの追加
サイドバーから Projects に戻り、NEW PROJECT をクリックして追加画面を開きます

ここで Proxy Cache を有効化し、右のドロップダウンから先程追加したプロキシを選択します
これで <domain>/<project>/<docker-hub上のイメージ名> (ex: example.com/proxy/node:24-slim) で Harbor 経由でイメージを取得できるようになりました
終わりに
今回は速度を重視してローカルネット上からのみアクセス可能な形で構築しましたが、外部からのアクセスが必要な場合はローカルネットワーク上のDNSのみ上書きするなどまた別の対応が必要になりそうです
Discussion