やっとdocker触り始めました。
まだ、うまく説明できるほどには馴染んでないけど。でも、凄い面白いなー。
って、Vagrant の Docker Provisioner 使おうとして。ハマった。これハマるくない?ちなみにProviderじゃなくてProvisionerの方ね。
特に誰かに何かを伝えるでもなく。イマココをだらだらと書いてみる。
docker provisionerをdockerのインストールだけに使う
shin1x1さんの記事(1年以上前の)を読みつつふむふむ。docker provisionerをdockerのインストールだけに使うって感じね。便利。1行書くだけでdocker使いたい放題!
ここでやめとけばよかったんや・・・。
docker provisionerを使ってみる
Docker - Provisioning - Vagrant Documentation
Vagrant.configure("2") do |config| config.vm.provision "docker" do |d| d.build_image "/vagrant/app", args: "-t bufferings/sample" d.run "bufferings/sample", args: "-v '/vagrant:/var/www' -p 1234:80" end end
こんな感じでprovisionしたら動くやろーって思って。(∩´∀`)∩ワーイうごいたー!
・・・って、これリロードしても動きっぱなしなんかね?vagrant reloadぽちっと。
おぉ・・・起動せんね。
そらそっか。provisionせんと呼ばれんよね・・・。
じゃ。こうするしか・・・。
Vagrant.configure("2") do |config| config.vm.provision "docker" , run: "always" do |d| d.build_image "/vagrant/app", args: "-t bufferings/sample" d.run "bufferings/sample", args: "-v '/vagrant:/var/www' -p 1234:80" end end
docker provisionerに
run: "always"
をつけた。えー。でもこれ、毎回ビルドされるんなんか嫌やなー。じゃ、こうするか。
Vagrant.configure("2") do |config| config.vm.provision "docker-build", type: "docker" do |d| d.build_image "/vagrant/app", args: "-t bufferings/sample" end config.vm.provision "docker-run", type: "docker", run: "always" do |d| d.run "bufferings/sample", args: "-v '/vagrant:/var/www' -p 1234:80" end end
ふむふむ。これで毎回コンテナは起動するけどビルドはせんようになったぞぅ。Dockerfile変更した時はvagrant provisionすればいいんかね。やってみるか。
∑(゚Д゚)ガーン
port 1234は使われとるよ。・・・って、そらそうか。コンテナ起動中や。しかしどうしようか。こうですか・・・。
Vagrant.configure("2") do |config| config.vm.provision "docker-build", type: "docker" do |d| d.build_image "/vagrant/app", args: "-t bufferings/sample" end config.vm.provision "shell", inline: "(実行中のコンテナがあったら停止するコマンド)" config.vm.provision "docker-run", type: "docker", run: "always" do |d| d.run "bufferings/sample", args: "-v '/vagrant:/var/www' -p 1234:80" end end
# すません。コマンド書くのめんどくさくなった。docker ps -qで起動中のコンテナがあれば、それをdocker stopにくわせて止める感じ。
なんかださいぞ!!あってるんかこれ?ま、動くしとりあえずはいっか。
ところで仕組みが気になった
どうやって、起動するコンテナを判別してるんだろー?とか。
d.build_imageは
config.vm.provision "docker" do |d| d.build_image "/vagrant/app", args: "-t bufferings/sample" end
これで、/vagrant/app/Dockefileを使ってイメージをビルドして、イメージのタグをargsで指定してる。
実装はこれ:
vagrant/client.rb at master · mitchellh/vagrant · GitHub
def build_images(images) @machine.communicate.tap do |comm| images.each do |path, opts| @machine.ui.info(I18n.t("vagrant.docker_building_single", path: path)) comm.sudo("docker build #{opts[:args]} #{path}") do |type, data| handle_comm(type, data) end end end end
docker buildしてるだけすね。
d.runはコンテナを起動する:
config.vm.provision "docker" do |d| d.run "bufferings/sample", args: "-v '/vagrant:/var/www' -p 1234:80" end
provisionerのソースはこんな感じ:
def run(containers) containers.each do |name, config| cids_dir = "/var/lib/vagrant/cids" config[:cidfile] ||= "#{cids_dir}/#{Digest::SHA1.hexdigest name}" @machine.ui.info(I18n.t("vagrant.docker_running", name: name)) @machine.communicate.sudo("mkdir -p #{cids_dir}") run_container({ name: name, original_name: name, }.merge(config)) end end
名前からハッシュファイル作って、中にコンテナIDを保持してるっぽい。
そのコンテナがあればstart。なければ作成するってか:
def run_container(config) raise "Container's cidfile was not provided!" if !config[:cidfile] id = "$(cat #{config[:cidfile]})" if container_exists?(id) start_container(id) else create_container(config) end end def start_container(id) if !container_running?(id) @machine.communicate.sudo("docker start #{id}") end end def container_running?(id) lookup_container(id) end def create_container(config) name = config[:name] # If the name is the automatically assigned name, then # replace the "/" with "-" because "/" is not a valid # character for a docker container name. name = name.gsub("/", "-") if name == config[:original_name] args = "--cidfile=#{config[:cidfile]} " args << "-d " if config[:daemonize] args << "--name #{name} " if name && config[:auto_assign_name] args << config[:args] if config[:args] @machine.communicate.sudo %[ rm -f #{config[:cidfile]} docker run #{args} #{config[:image]} #{config[:cmd]} ] end
ふむふむ。
てことは
変更してビルドしなおしたとしても、名前を変えない限り古い方のコンテナを使い続けるってことか。
んむー。なんかいけてない匂いがするなー。とはいえ、良い実装を考えるのも難しそうだな。
普通は、Dockerfileでビルドするんじゃなくて、Imageを事前にDockerHubにpushしといて使うんかな?
ふむ。ソース読むのにだいぶ疲れた。ruby力が必要だわ。
おは。