出来ることは出来るんだろうなと思いつつ、やったことがないのでチャレンジ。
結論から書くと、Dockerイメージを使うよりも簡単。
モノ
DockerHubにあるのは以下。
https://hub.docker.com/_/registry
そのDockerfileから、使っているバイナリを確かめる。
https://github.com/docker/distribution-library-image/blob/master/Dockerfile
そのバイナリのGitHubプロジェクトは以下。
https://github.com/distribution/distribution/
releasesのページにビルド済みのバイナリが置いてある。
https://github.com/distribution/distribution/releases
環境
Amazon Lightsailで$3.5(メモリ512MB)のUbuntu 20.04マシンを用意。
Docker registyをインストールする
Goプロダクトなのでシングルバイナリであり、tgzファイルを落として解凍すれば実行可。
$ wget https://github.com/distribution/distribution/releases/download/v2.8.1/registry_2.8.1_linux_amd64.tar.gz
$ tar xzf registry_2.8.1_linux_amd64.tar.gz
とりあえず起動
レジストリの設定ファイル内容については以下。
https://docs.docker.com/registry/configuration/
必要最低限ぽい値だけ設定ファイルに記述し、とりあえず起動。
$ cat >> config.yml << EOF
version: 0.1
http:
addr: :5000
EOF
$ mkdir data
$ export REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY=./data
$ ./registry serve config.yml
Docker CLIから接続確認
別の$3.5/Ubuntu 20.04のLightsailインスタンスを作成して、それにDockerをインストール。
https://docs.docker.com/engine/install/ubuntu/
てか、Dockerをインストールするのがメンドくて最近敬遠しがち。。
$ sudo apt-get remove docker docker-engine docker.io containerd runc
$ sudo apt-get update
$ sudo apt-get install \
ca-certificates \
curl \
gnupg \
lsb-release
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
$ echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
$ sudo docker run hello-world
hello-worldのイメージを、先に作ったレジストリにpushしてみる。
$ sudo docker images
$ REGISTRY=<レジストリサーバーの「プライベート」IPアドレス>
$ cat > daemon.json << EOF
{"insecure-registries":["${REGISTRY}:5000"]}
EOF
$ sudo cp daemon.json /etc/docker/
$ sudo systemctl restart docker
$ sudo docker tag hello-world ${REGISTRY}:5000/test/hello-world
$ sudo docker push ${REGISTRY}:5000/test/hello-world
(出力結果)
Using default tag: latest
The push refers to repository [172.26.6.23:5000/test/hello-world]
e07ee1baac5f: Pushed
latest: digest: sha256:f54a58bc1aac5ea1a25d796ae155dc228b3f0e11d046ae276b39c4bf2f13d8c4 size: 525
うんまあ、良さそう。
Registryにbasic認証を付ける
htpasswdで認証を設定する。
以下のコマンドを実行する前に、実行中のregistryのsshセッションでCtrl+cでプロセスを止めておく。
htpasswdはbcryptでの暗号化が必要。
$ sudo apt install -y apache2-utils
$ htpasswd -B -c ./htpasswd user1
$ cat >> config.yml << EOF
version: 0.1
http:
addr: :5000
auth:
htpasswd:
realm: basic-realm
path: ./htpasswd
EOF
んで、もう一回起動。
$ ./registry serve config.yml
Docker CLIでの動作確認(認証)
先のDocker CLIを導入したsshセッションに戻って、おもむろに再度docker pushする。
以下のように失敗する。
$ sudo docker push ${REGISTRY}:5000/test/hello-world
(出力結果)
Using default tag: latest
The push refers to repository [172.26.6.23:5000/test/hello-world]
e07ee1baac5f: Preparing
no basic auth credentials
docker loginしてから再度pushすれば成功する。
まあ、結果はalready existsだが。
$ sudo docker login -u user1 ${REGISTRY}:5000
$ sudo docker push ${REGISTRY}:5000/test/hello-world
ついでに
Registryを自己署名証明書でTLS有効にして、systemdで起動するまでやるなら以下の通り。
$ openssl genrsa -out ./key 2048
$ openssl req -key ./key -new -out ./csr -batch
$ openssl x509 -signkey ./key -in ./csr -req -days 3650 -out ./crt
$ cat > config.yml << EOF
version: 0.1
storage:
filesystem:
rootdirectory: /registry/data
http:
addr: :5000
tls:
certificate: /registry/crt
key: /registry/key
headers:
X-Content-Type-Options: [nosniff]
auth:
htpasswd:
realm: basic-realm
path: /registry/htpasswd
EOF
$ sudo mkdir /registry
$ sudo mkdir /registry/data
$ sudo cp registry config.yml htpasswd key crt /registry
$ cat > registry.service << EOF
[Unit]
Description=registry
[Service]
ExecStart=/registry/registry serve /registry/config.yml
Restart=always
[Install]
WantedBy=multi-user.target
EOF
$ sudo cp registry.service /etc/systemd/system/
$ sudo systemctl enable registry --now