開発版 Docker & Docker Registry の検証環境を作って試してみる

Docker イメージのリポジトリをを自前で管理するための Docker Private Registry というものがあります。これまで [docker/docker-registry](https://github.com/docker/docker-registry/) にて Python で開発されていて、現在のバージョンは [0.9.1](https://github.com/docker/docker-registry/releases/tag/0.9.1) です。
この docker-registry、使っている Python の HTTP サーバが buggy なのか push/pull でよく失敗するという問題がありました…

ところで、この Docker Registry の次期バージョンは __Go__ でスクラッチから開発されています。リポジトリも __[docker/distrbution](https://github.com/docker/distribution/)__ に移りました。
最初のリリースバージョンは 2.0 になる予定で、しかも[リリース日予定は 2015-04-16（たぶん西海岸時間）](https://github.com/docker/distribution/wiki/docker-1.6-Project-Page)です。
なんだか期待が持てます :+1: 

この registry v2 ですが、API も v1 -> v2 に上がっているので 現在リリースされている __Docker 1.5 以下は対応していません（push/pull できない）。__ registry v2 と同時リリースされる Docker 1.6 から対応する予定です。

=== 2015-04-16 18:40 追記
一応 [README.md](https://github.com/docker/distribution/blob/master/README.md) には Docker __1.5+__ サポートするって書いてあるんですよね…

> An implementation of the Docker Registry HTTP API V2 for use with docker 1.5+.

ただ、手元の Docker 1.5.0 + registry v2.0.0-rc4 で検証したところ、以下のエラーで push できませんでした。

```bash
vagrant@vagrant:~$ docker push localhost:5000/wheezy
511136ea3c5a: Image push failed
FATA[0000] Error pushing to registry: mux: variable "wheezy" doesn't match, expected "^(?:[a-z0-9]+(?:[._-][a-z0-9]+)*/){1,4}[a-z0-9]+(?:[._-][a-z0-9]+)*$"
```

Docker 1.5+ の扱いについては [docker/distribution#327](https://github.com/docker/distribution/issues/327) で議論されています。待て続報…

=== 2015-04-17 02:00 追記

> 1.5 is not supported.
> Fixing the doc in #371
> [Blacklist 1.5 · Issue #327 · docker/distribution](https://github.com/docker/distribution/issues/327#issuecomment-93696863)

なので、Docker 1.6 リリースを待ちましょう :cry: 

=== 追記終わり
Docker 1.6 & registry v2 の組み合わせをいち早く検証してみたかったので、Ubuntu VM 上に開発版の Docker 一式をインストールして試してみました。

## Try Docker 1.6-rc & Docker Registry 2.0

### 必要なもの

- [Vagrant](https://www.vagrantup.com/) 
- [VirtualBox](https://www.virtualbox.org/)

### 試してみる

以下の `Vagrantfile` を用意

```ruby
# -*- mode: ruby -*-
# vi: set ft=ruby :

# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "opscode-ubuntu-14.04"
  config.vm.box_url = "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_ubuntu-14.04_chef-provisionerless.box"
end
```

VM 立ち上げ

```bash
$ vagrant up
$ vagrant ssh
```

開発版 Docker をインストール

```bash
vagrant@vagrant:~$ wget -qO- https://test.docker.com/ | sh
apparmor is enabled in the kernel and apparmor utils were already installed
/sbin/apparmor_parser
+ [ https://get.docker.com/ = https://test.docker.com/ ]
+ [ https://test.docker.com/ = https://test.docker.com/ ]
...
Remember that you will have to log out and back in for this to take effect!
vagrant@vagrant:~$ sudo docker version
Client version: 1.6.0-rc7
Client API version: 1.18
Go version (client): go1.4.2
Git commit (client): 7e26e41
OS/Arch (client): linux/amd64
Server version: 1.6.0-rc7
Server API version: 1.18
Go version (server): go1.4.2
Git commit (server): 7e26e41
OS/Arch (server): linux/amd64
```

sudo 打つのが面倒なので vagrant ユーザを docker グループに入れる
途中で一旦ログアウトする必要がある

```bash
vagrant@vagrant:~$ sudo usermod -aG docker vagrant
vagrant@vagrant:~$ logout # ログアウト必要！
$ vagrant ssh
vagrant@vagrant:~$ docker version
Client version: 1.6.0-rc7
Client API version: 1.18
Go version (client): go1.4.2
Git commit (client): 7e26e41
OS/Arch (client): linux/amd64
Server version: 1.6.0-rc7
Server API version: 1.18
Go version (server): go1.4.2
Git commit (server): 7e26e41
OS/Arch (server): linux/amd64
```

以降は [distribution/deploying.md](https://github.com/docker/distribution/blob/master/docs/deploying.md) 見つつ進めました。

Docker Registry 2.0 ビルド & 立ち上げ

```bash
vagrant@vagrant:~$ git clone https://github.com/docker/distribution.git
Cloning into 'distribution'...
remote: Counting objects: 4506, done.
remote: Compressing objects: 100% (8/8), done.
remote: Total 4506 (delta 3), reused 0 (delta 0), pack-reused 4498
Receiving objects: 100% (4506/4506), 1.84 MiB | 1.08 MiB/s, done.
Resolving deltas: 100% (2351/2351), done.
Checking connectivity... done.
vagrant@vagrant:~$ cd distribution/
vagrant@vagrant:~/distribution$ docker build -t registry .
Sending build context to Docker daemon 5.838 MB
Sending build context to Docker daemon
Step 0 : FROM golang:1.4
1.4: Pulling from golang
d338bb63f151: Pull complete
...
 ---> Running in c6546a92ca33
 ---> fcac87db3f28
Removing intermediate container c6546a92ca33
Successfully built fcac87db3f28
```

```bash
vagrant@vagrant:~/distribution$ docker run -d -p 5000:5000 --name registry registry
ad80dfee5660b12d7466c9db221e66eff51b4502cffca49c6376ff2b72b8b7f4
```

Registry 起動 & 疎通確認

```bash
vagrant@vagrant:~/distribution$ docker ps
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS                    NAMES
ad80dfee5660        registry:latest     "registry cmd/regist   50 minutes ago      Up 50 minutes       0.0.0.0:5000->5000/tcp   registry
vagrant@vagrant:~/distribution$ wget -qO- localhost:5000/v2/
{}
```

公式 Hello world イメージ落としてきて、Registry v2 に push してみる

```bash
vagrant@vagrant:~$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from hello-world
511136ea3c5a: Pull complete
31cbccb51277: Pull complete
e45a5af57b00: Already exists
hello-world:latest: The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security.
Digest: sha256:840559710d27cecc786ae6edc9ceb39e5d8697bb27b4c7917a404d7faaac83f0
Status: Downloaded newer image for hello-world:latest
Hello from Docker.
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (Assuming it was not already locally available.)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

For more examples and ideas, visit:
 http://docs.docker.com/userguide/
```

```bash

vagrant@vagrant:~/distribution$ docker tag hello-world:latest localhost:5000/hello-mine
vagrant@vagrant:~/distribution$ docker push localhost:5000/hello-mine
The push refers to a repository [localhost:5000/hello-mine] (len: 1)
e45a5af57b00: Image already exists
31cbccb51277: Image successfully pushed
511136ea3c5a: Image successfully pushed
Digest: sha256:a1b13bc01783882434593119198938b9b9ef2bd32a0a246f16ac99b01383ef7a
```

Registry v2 から pull して run してみる

```bash
vagrant@vagrant:~/distribution$ docker pull localhost:5000/hello-mine
latest: Pulling from localhost:5000/hello-mine

31cbccb51277: Pull complete
e45a5af57b00: Already exists
511136ea3c5a: Already exists
Digest: sha256:a1b13bc01783882434593119198938b9b9ef2bd32a0a246f16ac99b01383ef7a
Status: Downloaded newer image for localhost:5000/hello-mine:latest
```

```bash
vagrant@vagrant:~/distribution$ docker run localhost:5000/hello-mine
Hello from Docker.
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (Assuming it was not already locally available.)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

For more examples and ideas, visit:
 http://docs.docker.com/userguide/
```

:tada:

## REF

- [docker/docker](https://github.com/docker/docker)
- [docker/distribution](https://github.com/docker/distribution)
- [distribution/deploying.md](https://github.com/docker/distribution/blob/master/docs/deploying.md)