Docker Registryを構築する

# はじめに
本記事は、Docker Registryを使用して、プライベートレジストリ環境を構築する手順について記載しています。

本記事の環境は以下になります。
手元のMacBook Airがクライアントで、iMacがプライベートレジストリ環境になります。

![Docker.png](https://qiita-image-store.s3.amazonaws.com/0/221759/6f83e4ef-560e-26a6-3b76-cc3ec89d253d.png)

## Docker Registry
Docker Registryは、Dockerイメージを一元管理するためのリポジトリサービスです。
公式のDocker Hubでは、CentOSなど各種Linuxディストリビューションの公式イメージや、有志で作成されたイメージなどが配布されています。

公式イメージの「registry」を使用することで、プライベートレジストリ環境を構築することができます。

現在、registryはVersion2.0系が主流で、Go言語で実装されています。

## Docker Registryの構築
### イメージのダウンロード（registry）
はじめに、registryイメージをダウンロードします。

- ダウンロードするイメージの確認  
`docker search registry`

```console
NAME                                    DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
registry                                The Docker Registry 2.0 implementation for s…   2454                [OK]                
konradkleine/docker-registry-frontend   Browse and modify your Docker registry in a …   213                                     [OK]
hyper/docker-registry-web               Web UI, authentication service and event rec…   161                                     [OK]
atcol/docker-registry-ui                A web UI for easy private/local Docker Regis…   113                                     [OK]
distribution/registry                   WARNING: NOT the registry official image!!! …   57                                      [OK]
marvambass/nginx-registry-proxy         Docker Registry Reverse Proxy with Basic Aut…   44                                      [OK]
jhipster/jhipster-registry              JHipster Registry, based on Netflix Eureka a…   41                                      [OK]
google/docker-registry                  Docker Registry w/ Google Cloud Storage driv…   37                                      
confluentinc/cp-schema-registry         Official Confluent Docker Images for Schema …   29                                      
joxit/docker-registry-ui                Docker registry v2 web User Interface           23                                      [OK]
klausmeyer/docker-registry-browser      Web Interface for the Docker Registry HTTP A…   17                                      [OK]
openshift/origin-docker-registry        The integrated OpenShift V3 registry            13                                      
deis/registry                           Docker image registry for the Deis open sour…   12                                      
landoop/schema-registry-ui              UI for Confluent's Schema Registry              7                                       [OK]
parabuzzle/docker-registry-ui           Docker registry frontend for registry v2        6                                       
quiq/docker-registry-ui                 Docker Registry UI                              5                                       
anoxis/registry-cli                     You can list and delete tags from your priva…   5                                       [OK]
elasticio/docker-registry-ecs           Docker image to run Docker private registry …   4                                       [OK]
allingeek/registry                      A specialization of registry:2 configured fo…   4                                       [OK]
webhippie/registry                      Docker images for registry                      1                                       [OK]
aibaars/docker-registry2-gcs            Docker Registry2 w/ Google Cloud Storage dri…   1                                       
yammer/docker-registry-cache            Simple docker registry cache using squid-pro…   1                                       [OK]
convox/registry                                                                         0                                       
lorieri/registry-ceph                   Ceph Rados Gateway (and any other S3 compati…   0                                       
torchbox/kube-registry-proxy            kube-registry-proxy fork with correct timeou…   0                                       [OK]
```

- イメージのダウンロード  
`docker pull registry`

```console
Using default tag: latest
latest: Pulling from library/registry
169185f82c45: Pull complete 
046e2d030894: Pull complete 
188836fddeeb: Pull complete 
832744537747: Pull complete 
7ceea07e80be: Pull complete 
Digest: sha256:870474507964d8e7d8c3b53bcfa738e3356d2747a42adad26d0d81ef4479eb1b
Status: Downloaded newer image for registry:latest
```

- イメージの確認    
`docker images`

```console
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
registry            latest              d0eed8dad114        3 weeks ago         25.8MB
centos              latest              1e1148e4cc2c        2 months ago        202MB
```

### コンテナの起動
次に、ダウンロードしたregistryイメージをもとにレジストリ用のコンテナを起動します。
レジストリは5000番ポートを使用します。

- コンテナの起動  
`docker run -d -p 5000:5000 registry`

```console
e4a6f960fdb3c79250a4baf90e84c96bcebedd86c023900bb3786f32828ae0b8
```

- コンテナの起動確認   
`docker ps --format "{{.ID}}\t{{.Image}}\t{{.Ports}}"`

```console
e4a6f960fdb3	registry	0.0.0.0:5000->5000/tcp
```

これでプライベートレジストリ環境が構築できました。

### イメージのアップロード
構築したレジストリ環境にアップロードするためのイメージを作成します。
**（※）本記事の環境はMac**

本記事では例として、CentOSののベースイメージにnginxをインストールします。
なお、nginxをインストールするためには、nginx用レポジトリの追加が必要になるため、[公式](https://nginx.org/en/linux_packages.html#mainline)を参考にして、レポジトリファイルの内容をコピーして作成します。

- Dockerfileの作成   
`vi Dockerfile`

```docker
# イメージの取得
FROM centos:latest

# 作成者情報
MAINTAINER 0.1 https://twitter.com/Brutus08159681

# Nginx用レポジトリファイルのコピー
ADD nginx.repo /etc/yum.repos.d/

# Nginxのインストール
RUN ["yum", "-y", "install", "nginx"]

# Nginxの自動起動設定
RUN ["systemctl", "enable", "nginx.service"]
```

- nginx.repoの作成   
`vi nginx.repo`

```ini
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
```

- Dockerファイルのビルド    
`docker build -t webserver .`

```console
Sending build context to Docker daemon  10.75kB
Step 1/5 : FROM centos:latest
 ---> 1e1148e4cc2c
Step 2/5 : MAINTAINER 0.1 https://twitter.com/Brutus08159681
 ---> Running in 4d7ff271e184
Removing intermediate container 4d7ff271e184
 ---> 360f621826fd
Step 3/5 : ADD nginx.repo /etc/yum.repos.d/
 ---> 065d346e93ad
Step 4/5 : RUN ["yum", "-y", "install", "nginx"]
 ---> Running in db772f205c5a
Loaded plugins: fastestmirror, ovl

//途中省略

Installed:
  nginx.x86_64 1:1.14.2-1.el7_4.ngx                                             

Dependency Installed:
  make.x86_64 1:3.82-23.el7            openssl.x86_64 1:1.0.2k-16.el7           

Complete!
Removing intermediate container db772f205c5a
 ---> a5dc224331c9
Step 5/5 : RUN ["systemctl", "enable", "nginx.service"]
 ---> Running in cb98e1b1ec8a
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service, pointing to /usr/lib/systemd/system/nginx.service.
Removing intermediate container cb98e1b1ec8a
 ---> afd46670157f
Successfully built afd46670157f
Successfully tagged webserver:latest
```

プライベートレジストリにアップロードするために、先ほど作成したイメージにタグを付けます。

- タグ付け  
`docker tag webserver localhost:5000/nginx`  
`docker images`

```console
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
webserver              latest              bc4ced76a58a        2 minutes ago       284MB
localhost:5000/nginx   latest              bc4ced76a58a        2 minutes ago       284MB
registry               latest              d0eed8dad114        3 weeks ago         25.8MB
centos                 latest              1e1148e4cc2c        2 months ago        202MB
```

タグ付けしたイメージをプライベートレジストリ環境にアップロードします。

- イメージのアップロード（コンテナのプライベートレジストリ）   
`docker push localhost:5000/nginx`

```console
The push refers to repository [localhost:5000/nginx]
eecb714a1eec: Pushed 
f12d083c2a5d: Pushed 
fbf94d353010: Pushed 
071d8bd76517: Layer already exists 
latest: digest: sha256:ec84796f9312457e9afd0a0b3fff1ee40e52512f4f3b83dbaee8a7e728971ee4 size: 1155
```
イメージのアップロードが完了したので、確認のため、ローカルに保存したイメージを削除します。

`docker rmi webserver`

```console
Untagged: webserver:latest
```

`docker rmi localhost:5000/nginx`

```
Untagged: localhost:5000/nginx:latest
Untagged: localhost:5000/nginx@sha256:ec84796f9312457e9afd0a0b3fff1ee40e52512f4f3b83dbaee8a7e728971ee4
Deleted: sha256:afd46670157fa5608642dae40aaad502eb69787bb0494536d9774089f7e44d8d
Deleted: sha256:edfe82b3e83ea6e3fbcb29ba5d801f7a00d5cc6cd1c650fe519d00fbea6a34f7
Deleted: sha256:a5dc224331c9be59615fdf8101d188ed56dd6052176c744f07d1bbdb23109464
Deleted: sha256:313c7c3089ee43faf482383dcb1e04e35cef648c566332239a86920fb4921d1e
Deleted: sha256:065d346e93ad13542b6790324f0ca7766335730334d0d39200948239737164a6
Deleted: sha256:d24e00ece851f250e549c84f3e2165f952cee2bf43c913dd1328023e8888bb81
Deleted: sha256:360f621826fd1ad8823e54e70a586a37cbdea1c9844b6b9f7b00853537931548
```

`docker images`

```console
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
registry            latest              d0eed8dad114        3 weeks ago         25.8MB
centos              latest              1e1148e4cc2c        2 months ago        202MB
```

### イメージのダウンロード（プライベートレジストリ環境→nginxのイメージ）
プライベートレジストリ環境にあるレジストリ用のコンテナから、先ほどアップロードしたnginxのイメージをダウンロードします。

- コンテナのプライベートレジストリ環境からダウンロード   
`docker pull localhost:5000/nginx`

```console
latest: Pulling from nginx
a02a4930cb5d: Already exists 
53cacbc24ea9: Pull complete 
6743d7a92897: Pull complete 
0b2d1befb17c: Pull complete 
Digest: sha256:ec84796f9312457e9afd0a0b3fff1ee40e52512f4f3b83dbaee8a7e728971ee4
Status: Downloaded newer image for localhost:5000/nginx:latest
```

- イメージの確認   
`docker images`

```console
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
localhost:5000/nginx   latest              afd46670157f        3 minutes ago       284MB
registry               latest              d0eed8dad114        3 weeks ago         25.8MB
centos                 latest              1e1148e4cc2c        2 months ago        202MB
```

 - コンテナの起動    
 `docker run --privileged --name "test1" -d -p 8080:80 localhost:5000/nginx /sbin/init`
 - nginxの起動確認   
 ブラウザからローカルホストの8080にアクセスします。
<img width="2048" alt="スクリーンショット 2019-02-23 20.40.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/221759/e256106c-c9be-51bf-4613-5d35d4bd7d94.png">


**「Welcome to nginx!」の画面が表示されればOKです。**

### 他のDockerクライアントからのダウンロード
他のDockerがインストールされているクライアントから、プライベートレジストリ環境にあるイメージをダウンロードする手順について解説します。

プライベートレジストリ環境のイメージをダウンロードする場合は、docker pullコマンドの引数にプライベートレジストリ環境のIP:5000/取得イメージ名を指定するだけですが、ホスト側で証明書の設定をしていないと以下のようにエラーが出力されます。

`docker pull プライベートレジストリ環境のIP:5000/nginx`

```console
Using default tag: latest
Error response from daemon: Get https://プライベートレジストリ環境のIPアドレス:5000/v2/: http: server gave HTTP response to HTTPS client
```

ホスト側で証明書を使用しないでHTTP接続する場合は、以下の設定を行います。
**（※）本記事の環境はMac**

クライアン側のDockerアイコンをクリックして、preferencesのDeamonタブを開きます。
![スクリーンショット 2019-02-23 21.08.24.png](https://qiita-image-store.s3.amazonaws.com/0/221759/80c078a4-ad62-bf3c-c9a0-8161504101b2.png)

insecure-registries:の「+」をクリックし、プライベートレジストリ環境のIP:5000を追加します。最後に、「Apply & Restart」をクリックします。

![スクリーンショット 2019-02-23 21.15.36.png](https://qiita-image-store.s3.amazonaws.com/0/221759/9e5c767a-a39f-28fc-854c-3407a0e78d44.png)


Docker再起動後、再度、docker pullコマンドを実行すると、イメージがダウンロードできます。

```console
Using default tag: latest
latest: Pulling from nginx
a02a4930cb5d: Pull complete 
53cacbc24ea9: Pull complete 
6743d7a92897: Pull complete 
0b2d1befb17c: Pull complete 
Digest: sha256:ec84796f9312457e9afd0a0b3fff1ee40e52512f4f3b83dbaee8a7e728971ee4
Status: Downloaded newer image for プライベートレジストリ環境のIPアドレス:5000/nginx:latest
```

# おわりに
プライベートレジストリ環境を構築することで、統一したイメージを使用した開発ができるので、Dockerの持ち味をより引き出せます。

## 参考
- [Docker Registry](https://docs.docker.com/registry/)
- [Test an insecure registry](https://docs.docker.com/registry/insecure/)