Dockerは Dockerfile という独自のDSLで記載されたファイルからDockerイメージを作成するのだが、
普段かいてるitamae使えないかなと思ったらどうやら Packerというものと組み合わえるといけるらしい
Packerを使ってChef/Puppet/AnsibleでDockerのイメージをつくる
ただ僕が普段使っているのはItamae。。。Packerでは現状対応してないという。
Packerとは?
VagrantとかTerafformとかを作っているHashicorp社製のソフトウェア
複数のプラットフォームのマシン、コンテナイメージを1つの設定ファイルから作成できる。
身近な例でいうと
AMIの作成をコマンド一発で作れるようになる。
他にもbuild先を切り替えるとGCEとかVMwareとかのイメージが作れるようになる
お題
rubyの2.3.1が動いていてrailsで rails new
したての時に出るwelcomeページを出す。
なおrailsのプロジェクトはローカルにある状態からスタートする。
※ rubyとかrailsは公式のdockerイメージがあるけど、今回は身近なものを題材にしたかっためこちらにしました
今回やったものはすべてここにpushしてあります
https://github.com/hatappi/packer-docker-sample
Dockerfile -> Dockerイメージ
Dockerに関してはrubyのDockerイメージがあるので、それに上乗せする形で作る。
やってることはだいたい見てだいたい分かるとは思う。
ADD?
RUN?
なんだろうはググってください
FROM ruby:2.3.1
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
RUN mkdir /work
WORKDIR /work
ADD ./rails /work
RUN bundle install
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
最終的にCMDでrails serverを指定しているのでrunした時にrails serverが立ち上がる
$ docker build -t [image name] .
$ docker run -p 3000:3000 [image name]
Packer -> Dockerイメージ
まず全体的な流れからいくと
ubuntuのイメージを落としてきて
- railsプロジェクトをアップロード
- rbenvをいれて2.3.1をインストール
- bundle install
を行う。
2からitamaeを使用する。
itamaeに関してはレシピごとマシンにアップロードして itamae local
する
Packerの構成
Packerには大きく builders と provisioners と post-processors で構成される。
- builders
- Packerのコアの部分。何を元に何を出力したいのかが記載される。今回はDockerなので元イメージは何か?出力パスは何か?を記載する
- provisioners
- プロビジョニングの設定。shellとかPuppet, Ansible, Chefなどの指定をここで行う。
- post-processors
- ここはbuildが終わった後の処理を記載する。今回だとdocker imageの名前を指定してimportしたり、S3にファイルをアップロードしたり出来る。
これらの設定をPackerでは一つのファイルに記載する。
Packerの設定ファイルのJSON
Packerではprovisionersでitamaeが提供されていないので、自分でやってあげる必要があって
itamaeとかのレシピをアップロードしてサーバー上で itamae local
してあげる流れになる
今回はrubyが入っていないイメージを選択したのでitamaeを動かすためにitamae_setup.shで一旦rubyをpackageからインストールしてます
{
"builders":[{
"type": "docker",
"image": "ubuntu:14.04.5",
"export_path": "image.tar"
}],
"provisioners": [
{
"type": "shell",
"inline": [
"mkdir -p /infra",
"chmod a+w /infra"
]
},
{
"type": "file",
"source": "./",
"destination": "/infra"
},
{
"type": "file",
"source": "../rails",
"destination": "/"
},
{
"type": "shell",
"inline": [
"sh /infra/scripts/ubuntu/setup.sh",
"cd /infra/itamae && bundle install --path vendor/bundle",
"cd /infra/itamae && bundle exec itamae local /infra/itamae/roles/ubuntu/default.rb",
"sh /infra/scripts/ubuntu/cleanup.sh"
]
}
],
"post-processors": [{
"type": "docker-import",
"repository": "packer-docker-sample/rails"
}]
}
Packer実行
command 一発
$ packer build manifest.json
あとは下記のようなコマンドを叩いてあげれば終わり
docker run -p 3000:3000 -w /rails -it [image name] /bin/bash -lc '/rails/bin/rails s -b 0.0.0.0'
まとめ
実はitamaeにはDockerイメージを作成する itamae docker
コマンドがある。
ただPackerはbuidlerの部分を変えてあげればAWSのAMIにもなるし、post-processorsを指定すれば
イメージをdocker hubにpushとかも出来る単にイメージを作成するだけではないので良さ気。
今回はrails serverするだけだったので結果的にDockerfileの方がシンプルになってしまったけど
設定ファイルかいたり細かいとこしだすときっとPacker + itamaeが良いじゃんってなるはず。
あと今回rubyを使うプロジェクトだったから良いものの毎回itamae localするために対象マシンにrubyをインストールするのは
時間もかかるし無駄だなと思う。でもitamaeは書きたい。