私はいつも Vagrant を使って boot2docker や CoreOS をローカルマシンに VM として立てて、いろいろテストしています。
で、テストの度に VM を再構築して、テストで使う Docker のイメージを Docker Hub からダウンロードすることになるんですが、遅い回線だと大変イライラします。
まあ、ローカルマシンは回線もメモリも制約があるから、クラウド使えよって話なんですが。。。
他の案としては、ローカルに Docker Registry を立てて、そこに置けばいいんじゃないのってことですよねー
が、最近 Docker Registry Mirror の存在を知って、これは!
ってなったので、使ってみることにしました。
Docker Hub のイメージをそのまま使いつつ、一度ダウンロードしたイメージはミラーにキャッシュされるので、次回からは超速で docker pull
出来るぜー!
使い方は簡単で、こちらに載っております。
https://github.com/docker/docker/blob/master/docs/sources/articles/registry_mirror.md
しかも、Docker Private Registry の機能もそのまま使える設定も出来るんですね。
さらに、ここまで書いて2、3日置いておいたんですが、
https://github.com/kwk/docker-registry-frontend
を発見して、試したので、一気にまとめることにしました。
例によって Vagrant でお手軽に立てる Vagrantfile も作りました。
VAGRANTFILE_API_VERSION = "2"
DOCKER_REGISTRY = "docker-registry-mirror"
DOCKER_REGISTRY_UI = "docker-registry-frontend"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.define "docker-registry-mirror"
config.vm.box = "yungsang/boot2docker"
config.vm.network :private_network, ip: "192.168.33.201"
config.vm.network :forwarded_port, guest: 2375, host: 2375, disabled: true
config.vm.synced_folder ".", "/vagrant"
config.vm.provision :shell do |sh|
sh.inline = <<-EOT
docker rm -f #{DOCKER_REGISTRY} 2> /dev/null || true
docker rm -f #{DOCKER_REGISTRY_UI} 2> /dev/null || true
EOT
end
config.vm.provision :docker do |d|
d.run "#{DOCKER_REGISTRY}",
image: "registry",
args: "-p 5000:5000 -e MIRROR_SOURCE=https://registry-1.docker.io -e MIRROR_SOURCE_INDEX=https://index.docker.io -e SQLALCHEMY_INDEX_DATABASE=sqlite:////tmp/registry/docker-registry.db -v /vagrant/registry:/tmp/registry"
d.run "#{DOCKER_REGISTRY_UI}",
image: "konradkleine/docker-registry-frontend",
args: "-p 80:80 --link #{DOCKER_REGISTRY}:#{DOCKER_REGISTRY} -e ENV_DOCKER_REGISTRY_HOST=#{DOCKER_REGISTRY} -e ENV_DOCKER_REGISTRY_PORT=5000"
end
config.vm.provision :shell, run: "always" do |sh|
sh.inline = <<-EOT
IS_RUNNING=$(docker inspect --format '{{.State.Running}}' #{DOCKER_REGISTRY} 2> /dev/null)
if [ "$IS_RUNNING" != "true" ] ; then
docker start #{DOCKER_REGISTRY}
fi
IS_RUNNING=$(docker inspect --format '{{.State.Running}}' #{DOCKER_REGISTRY_UI} 2> /dev/null)
if [ "$IS_RUNNING" != "true" ] ; then
docker start #{DOCKER_REGISTRY_UI}
fi
EOT
end
end
起動
$ git clone https://github.com/YungSang/docker-registry-mirror.git
$ cd docker-registry-mirror
$ vagrant up
Web UI は http://192.168.33.201/ でアクセス出来ます。
この IP アドレスは Vagrantfile 内の以下の行で設定を変更出来ます。
config.vm.network :private_network, ip: "192.168.33.201"
使う側の Docker デーモンの設定はそれぞれの OS に依存するので、サンプルを用意しました。
使い方
まず、上記サンプルの一つを使ってミラーのテストをしてみます。
$ cd samples/boot2docker
$ vagrant up
$ docker pull yungsang/busybox
これでミラーを通してイメージがダウンロードされ、ローカルにキャッシュされます。
場所は registry/images
の下です。ローカルマシンのフォルダーでも入っているのが確認出来ると思います。
$ docker rmi yungsang/busybox
$ docker pull yungsang/busybox
と、一度消してプルし直すと違いがわかると思います。
次に、Private Registry の機能をテストします。
$ docker tag yungsang/busybox 192.168.33.201:5000/busybox
$ docker push 192.168.33.201:5000/busybox
Private 用のアドレスのタグ Prefix を付けてプッシュします。
これで Private のレジストリに登録されます。
イメージは先程のものと同じなので増えませんが、registry/repositories
の下に library/busybox
が作られているのがわかると思います。
Web UI でも http://192.168.33.201/#/repository/library/busybox/ に現れるはずです。
工夫したところ
-
Vagrant の Synced Folder を使ってレジストリの永続化をしていますが、その Synced Folder は VM のブート後に設定されるので、
docker run --restart=alway
をやっても再起動時に上手くフォルダーを使えません。
そこで、今回の Vagrantfile では--restart=alway
を使わずに、手動で再起動しています。これで、vagrant destory & up
やvagrant reload
、vagrant provision
でもちゃんと意図した通りに動くようになりました。 -
Docker 公式の
registry
イメージのデフォルトでは、検索用のバックエンドに SQLite が使われていますが、パスが/tmp/docker-registry.db
になっているので、registry 用のフォルダと別になっているので、このままでは永続化の時に上手く行きません。
そこで、-e SQLALCHEMY_INDEX_DATABASE=sqlite:////tmp/registry/docker-registry.db
とし、registry 用フォルダーである/tmp/registry/
の下に持ってくることによって、問題無く永続化+ポータブルにすることが出来ました。