プライベートなDockerレジストリサーバーをコンテナで立てる

Docker Hubではなく自分だけのレジストリが欲しい場合はレジストリサーバーをコンテナで立てましょう。
![68747470733a2f2f7777772e646f636b65722e636f6d2f73697465732f64656661756c742f66696c65732f6f79737465722d72656769737472792d332e706e67.png](https://qiita-image-store.s3.amazonaws.com/0/94965/c7e09bb7-7e4a-8df9-29c7-f6fcb48aa6f2.png "68747470733a2f2f7777772e646f636b65722e636f6d2f73697465732f64656661756c742f66696c65732f6f79737465722d72656769737472792d332e706e67.png")



大抵は以下の様な時に使いたくなると思います。

- DockerHub以外でプライベートのレジストリを作りたい（お金払いたくない！）
- オンプレミスで使いたい（会社内だけで使いたい）

Docker Hubでアカウントを持っていれば1リポジトリだけプライベートリポジトリが使えますが、それ以上はお金を払う必要があります。
参考:[Billing Information & Pricing Plans](https://hub.docker.com/account/billing-plans/ "DockerHub")


# 用語
似てる用語が出てくるのでまとめておきます

| 用語 | 意味 |
|:-----------|:------------|
|レジストリ    |DockerHubのような複数のリポジトリ・イメージを格納しておくサーバー|
| リポジトリ   |イメージが保存されている領域。レジストリの中にいくつも存在する。Docker Hubでユーザーが作るのはリポジトリ|
|パブリックレジストリ/リポジトリ  | 誰でも見れて、取得して使用することができるレジストリ/リポジトリ |
|プライベートレジストリ/リポジトリ | 制限された範囲の人しか見れないし使うことができないレジストリ/リポジトリ |


# プライベートレジストリ選択肢
- Registryコンテナ
- Docker Trusted Registry

## Registryコンテナ
Docker環境さえあればすぐに作れる、DockerHubで公式に配布


- 評価目的のために調整されている
- 本番環境へのデプロイ時は自分でビルドして調整が必要
	- TLS認証設定
	- ストレージのバックエンド選択
- 管理インターフェイスが標準ではついてない

自分で使ってみる、社内にとりあえず構築してみるにはこれで十分。
本記事は主にこちらについて記載。

[DockerHub/registry](https://hub.docker.com/_/registry/)

## Docker Trusted Registry
お金を払って構築できるレジストリ

- 商用サポートライセンスが必要
    - Dockerエンジンは商用（CSエンジン）
    - Docker Hub上で入手
- ブラウザでの管理インターフェイス
	- リソース管理
	- ログ
	- ユーザー認証(Basic or LDAP)
- よりセキュア
	- TLSが有効(HTTPS通信)
	- CA証明書使用
- サポート環境
	- Ubuntu14.04 LTS
	- RHEL 7.0/7.1

安定して使いたい場合は素直にこっちを使いましょう。
フリートライアルもあるので試してみることもできます

[docker-trusted-registry](https://www.docker.com/products/docker-trusted-registry)



#Registryコンテナの構築
ではさっそくたててみましょう

##必要なもの・環境

以下を使います

- Docker環境
- インターネット接続環境

DockerHubと通信でき、コンテナを実行できる環境があればOKです。
※インターネットと接続できない人はregistryイメージをtarなどで入手して環境にloadしておいても構いません。

検証したときのバージョンは以下となります

- Docker Client 1.10.1
- Docker Engine 1.10.1
- registry:2.3.0
- docker-registry-frontend:v2

##構築
Dockerコマンドが実行できる状態で、レジストリを取得します。

```bash
$ docker pull registry:2.3.0
```

docker runしてRegistryのコンテナをたてましょう。
ただしRegistry上のイメージを永続化したいのでホストのディレクトリをコンテナにマウントさせます

```bash
$ docker run -d -p 5000:5000 -v /var/opt:/var/lib/registry registry:2.3.0
```
ホスト側、コンテナ側共に5000番ポートでつないでいます。これで`localhost:5000`などとするとコンテナの5000番ポートにフォワードされます
また、Registry:2.3.0では`/var/lib/regstry`上にpushされたイメージが保管されます。そのため、ホスト側の`/var/opt`をコンテナ上の`/var/lib/registry`にマウントしてます。

構築はこれだけでOKです。

##使ってみる
###push
ではレジストリにイメージをpushしてみましょう。
ここではubuntu:14.04のイメージをダウンロードした状態とします。プライベートレジストリにpushするためにはイメージの名前を変える必要があります。

`docker tag <イメージ名>:<tag> <レジストリのIP>:<ポート>/<任意のリポジトリ名>/<イメージ名>:<tag>`
自分の環境に当てはめると以下です

```bash
$ docker tag ubuntu:14.04 localhost:5000/rsakao/ubuntu:14.04
```
ubuntuイメージ名の前にレジストリ名をつけた形ですね。`<レジストリのIP>:<ポート>`は同じDockerエンジン上で実行させているので`localhost:5000`となります
`<任意のリポジトリ名>`には自分のアカウント名をつけました。Docker Hubの`<リポジトリ名>/<イメージ名>`と同じで個人や企業などを入れておけばよいでしょう
`docker images`でイメージ一覧を確認してみてください。ubuntu:14.04と同じコンテナIDで、あたらしいイメージ名が登録されていますね

```bash
$ docker images
REPOSITORY                     TAG                 IMAGE ID
ubuntu                         14.04               14b59d36bae0
localhost:5000/rsakao/ubuntu   14.04               14b59d36bae0
```

pushします

```bash
$ docker push localhost:5000/rsakao/ubuntu:14.04 
```

ネットワーク通信が正常であれば、pushが完了します

###pull
ついでにpullも試してみましょう
いったん先ほどのtagを削除します

```bash
$ docker rmi localhost:5000/rsakao/ubuntu:14.04
```
`docker images`でイメージ一覧から消えていることを確認してください
実際にpullしてみます

```bash
$ docker pull localhost:5000/rsakao/ubuntu:14.04
```
再度`docker images`でイメージ一覧を確認してください。pullできていたら成功です
pullしたあとは`docker tag`で名前を変更したりして使ってみてください

##DockerデーモンがTLS動作してる場合
Docker ToolBox、Docker Machineなどを使っている場合、DockerデーモンのTLS設定が有効となっています。そのためRegistryでTLS設定を有効にしていないとHTTPS通信ができず、pushやpullができません。
クライントとレジストリが同じDockerデーモン上で動作している場合はこの限りではありませんが、レジストリである限り複数人で使うことが多いと思います。
セキュアではありませんが、とりあえず動かしたい場合はDockerデーモン側で設定を変えて起動します。

Docker Machineで起動したDockerデーモンの場合、以下のようにします。

```bash
$ Docker-machine ssh default #Dockerデーモンが動いているサーバーに接続
$ sudo vi /var/lib/boot2docker/profile #ubuntuなどは/etc/default/dockerを編集
```

一行追加します。

```conf:/var/lib/boot2docker/profile
EXTRA_ARGS='
--label provider=virtualbox
--insecure-registry 192.168.0.1:5000 ←行追加
'
```

`192.168.0.1:5000`の部分は`<レジストリのIP>:<ポート>`です。
ubuntuなど/etc/default/dockerを編集する場合は`DOCKER_OPTS="--insecure-registry <レジストリのIP>:<ポート>"`と追記するみたいです（こちらは未検証）。

Dockerデーモンを再起動します。

```bash
$ sudo /etc/init.d/docker restart
```

あるいは

```bash
$ sudo service docker restart
```

以上でpush, pullができるようになります。

##ブラウザでレジストリを確認したい場合(docker-registry-frontend)
簡易的なレジストリコンテナですが、何が入っているか可視化したいことがあります。その場合は[docker-registry-frontend](https://github.com/kwk/docker-registry-frontend "GitHub")を使ってみましょう

GitHubによると

以下のように実行すれば動くことがわかります

```bash
$ docker run \
  -d \
  -e ENV_DOCKER_REGISTRY_HOST=ENTER-YOUR-REGISTRY-HOST-HERE \
  -e ENV_DOCKER_REGISTRY_PORT=ENTER-PORT-TO-YOUR-REGISTRY-HOST-HERE \
  -p 8080:80 \
  konradkleine/docker-registry-frontend:v2
```

`ENV_DOCKER_REGISTRY_HOST=`にはレジストリコンテナのIPを指定します。環境変数なので`localhost`はだめでした。IPにしてください。`ENV_DOCKER_REGISTRY_HOST=192.168.0.1`という形です
`ENV_DOCKER_REGISTRY_PORT=`にはポート番号を入れます。上記の例では5000番ですので`ENV_DOCKER_REGISTRY_PORT=5000`という形です

起動後はブラウザでアクセスしてみましょう
![スクリーンショット 2016-02-21 13.41.23.png](https://qiita-image-store.s3.amazonaws.com/0/94965/2a3b37fa-09d6-3ec1-218a-a0d5ed62c9b7.png "スクリーンショット 2016-02-21 13.41.23.png")

「Browse repositories」からリポジトリをたどることができます
![スクリーンショット 2016-02-21 13.41.53.png](https://qiita-image-store.s3.amazonaws.com/0/94965/202f9580-d435-cbd6-5e94-76852c2bc961.png "スクリーンショット 2016-02-21 13.41.53.png")

以上です