プライベートコンテナリポジトリを構築しdockerコンテナを起動してみる

# はじめに
プライベートリポジトリを立てて、そこからイメージをPullしてdockerコンテナを起動する手順について紹介します。  
以下のリポジトリの構築に関しては以下の2種類の方法について紹介します。どちらもdockerコマンドを使ってコンテナとして動かします。  
- `registry`(https://github.com/distribution/distribution/tree/main)
  コンテナを1つ立てるだけなので手っ取り早くできる、GUIでの操作はできない
- `Harbor`(https://github.com/goharbor/harbor)  
  docker composeで複数コンテナを起動する必要が有るがGUIでリポジトリの設定などが可能  

本記事ではリポジトリはhttpアクセスし、その際にBasic認証を必要とする設定で構築します。  
httpsでアクセスするための設定などは各ドキュメントを参照してください。  

# 必要なもの
- Linux(本記事ではUbuntuで実行しています)
- docker 

# プライベートコンテナリポジトリの構築

## registryでの構築
手順に関しては[deploying.md](https://github.com/distribution/distribution/blob/main/docs/content/about/deploying.md)を基にしています。  

### 1. Basic認証用にhtpasswdファイルを作成  
ユーザ名とパスワードは任意のものを設定してください。
```sh
# authディレクトリにhtpasswdを作成し、後ほど起動するregistryコンテナにマウント
$ mkdir auth
$ docker run \
  --entrypoint htpasswd \
  httpd:2 -Bbn <ユーザ名> <パスワード> > auth/htpasswd
```

### 2. registryコンテナの起動  
```sh
$ docker run -d \
-p 5000:5000 \
--restart=always \
--name registry \
-v "$(pwd)"/auth:/auth \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
registry:2

```

## Harborでの構築
Harborのインストールも公式ドキュメントの[Harbor Installation and Configuration](https://goharbor.io/docs/2.7.0/install-config/)にそって行っていきます。  
今回はv2.7.3を試してみました。  

### 1. インストーラーのダウンロード
Githubのreleases(https://github.com/goharbor/harbor/releases)からインストーラーをダウンロードします。  
インストーラーには以下の2種類があります。  
- online  
インストール時にイメージをdocker hubからPullしてくる、インストーラー自体の容量は軽量
- offline
インストーラーの中にイメージが含まれているためインストール時にPullが不要、インストーラー自体は容量大きめ

今回はofflineでインストールをしてみるため「harbor-offline-installer-v2.7.3.tgz」をダウンロードしておきます。 
ダウンロードしたら以下で解凍しておきます。
```sh
$ tar xzvf harbor-offline-installer-v2.7.3.tgz
$ cd harbor
```

### 2. インストール(Harborの起動)
解凍したディレクトリにある`install.sh`を実行するとインストール(docker composeによるコンテナ起動)が行われます。その前にconfigファイルである`harbor.yml.tmpl`を編集します。  
`hostname`フィールドにマシンのIP、`harbor_admin_password`フィールドにコンソールのログインパスワードを指定します。また今回はhttpでアクセスするため、以下のようにhttpsの設定をコメントアウトします。ファイルは`harbor.yml`という名前で保存します。  

```yaml:harbor.yml
# 変更点抜粋
hostname: <マシンのIPアドレス>

# 以下の4行をコメントアウト
#https:
#  port: 443
#  certificate: /your/certificate/path
#  private_key: /your/private/key/path

# コンソールへのログインパスワード
harbor_admin_password: <パスワード>
```

ファイル編集後、以下のコマンドを実行すると複数のコンテナが実行され、harborが起動する。
```sh
sudo ./install.sh
```

### 3. リポジトリの作成
インストール後、ブラウザからhttp://<マシンのIPアドレス>にアクセスしharborのコンソールにログインします。  
ユーザ名は`admin`、パスワードはharbor.ymlで設定したパスワードです。  
ログイン後Project(リポジトリの集合を管理する単位)一覧が表示されます。`NEW PROJECT`からtestという名前の新規Projectを作成します。プライベートにしたいのでPublicにチェックはしません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959481/e6b6e56a-bbe9-36de-2a6b-a1add41a798c.png)

作成したtest Projectを利用していきます。イメージは<マシンのIPアドレス>/<Project名>/<レジストリ名>となります。

# プライベートリポジトリへログイン
docker loginコマンドで設定したユーザ名/パスワードでログインしておきます。  
```sh
# registryの場合
$ docker login localhost:5000
# harborの場合
$ docker login localhost
```

# プライベートリポジトリへイメージをPush
[deploying.md](https://github.com/distribution/distribution/blob/main/docs/content/about/deploying.md)で行っているようにubuntuイメージをプライベートリポジトリにPushしてみます。  


```sh
# 公式のUbuntu 22.04イメージをダウンロード
$ docker pull ubuntu:22.04

# ローカルリポジトリ用にイメージをtag付け
# registryの場合
$ docker tag ubuntu:22.04 localhost:5000/my-ubuntu:22.04
# harborの場合
$ docker tag ubuntu:22.04 localhost/test/my-ubuntu:22.04

# ローカルリポジトリにPush
# 「server gave HTTP response to HTTPS client」といったエラーが発生した場合は以下
# registryの場合
$ docker push localhost:5000/my-ubuntu:22.04
# harborの場合
$ docker push localhost/test/my-ubuntu:22.04

# イメージを削除
$ docker rmi ubuntu:22.04

# Pushしたイメージも削除
# registryの場合
$ docker rmi localhost:5000/my-ubuntu:22.04
# harborの場合
$ docker rmi localhost/test/my-ubuntu:22.04

```

※ localhostではなくマシンのIPでも問題ありません。Pushの際に「server gave HTTP response to HTTPS client」といったエラーが発生する場合はdaemon.jsonに以下のような設定を追加しdockerを再起動してください。
詳細は[Insecure registries](https://docs.docker.com/engine/reference/commandline/dockerd/#insecure-registries)を参照
```json:daemon.json
{
"insecure-registries": ["localhost", "マシンのIPアドレス"]
}
```


レポジトリのイメージは以下のcurlコマンドで確認できます。  
```sh
# registryの場合
$ curl http://localhost/v2/_catalog -u <ユーザ名>:<パスワード>
# harborの場合
$ curl http://localhost/v2/_catalog -u admin:<パスワード>
```

Harborの場合はコンソールの作成したtest Projectからも確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959481/06ba47cb-2dd4-ecba-2c83-55ba8a9875a4.png)


# プライベートリポジトリからイメージをPullし起動
```sh
# registryの場合
$ docker run -i -d localhost:5000/my-ubuntu:22.04
# harborの場合
$ docker run -i -d localhost/test/my-ubuntu:22.04
```

上記で構築したプライベートリポジトリからイメージを取得しコンテナを起動することができました。


# 片付け

起動したubuntuコンテナを停止・削除、イメージの削除をします。
```sh
$ docker stop <ContainerID> && docker rm <ContainerID>
$ docker rmi <my-ubuntu:22.04 Image ID>
```

コンテナレジストリを削除します。
```sh
# registryの場合
$ docker container stop registry && docker container rm -v registry

# harborの場合
$ sudo docker-compose down -v
$ rm -r /data/database
$ rm -r /data/registry
$ rm -r /data/redis
```