TL;DR
- Itamae レシピを Docker + Serverspec でテストする
- テストのためにDocker コンテナ上で
sshd
を実行したくない - CircleCI は
docker exec
使えないのでlxc-attach
を使う
ローカル環境 (OS X) からテストを実行する
必要なモノをインストールする
- docker
- docker-machine
- docker-machine-driver-xhyve
Homebrew などで適宜インストールしておいてください。
既にVirtualBox などを使っている場合は xhyve じゃなくても良いです。
cf. OS XのネイティブHypervisorを使うxhyveと、ネイティブDockerを立ち上げるdocker-machine-driver-xhyveを作った話
Docker コンテナを作成する
Docker Machine を作成して、コンテナを使う準備をします。スペックは適宜調整してください。
docker-machine create ci\
--driver xhyve\
--xhyve-memory-size 2048\
--xhyve-disk-size 5120\
--xhyve-cpu-count 1\
--xhyve-experimental-nfs-share;
Docker イメージをダウンロードする際にDNS が欲しいので適当に突っ込みます。
docker-machine ssh ci "sudo echo 'nameserver 8.8.8.8' > /etc/resolv.conf"
あとは、Docker コマンドを扱えるように docker-machine env ci
を確認して環境変数を設定してください。
コンテナを使ってテストを実行する
プロビジョニングのためにSSH サーバーを立てる場合、プロビジョニング用のSSH ユーザや鍵の追加でサーバー構成に差分が出るため、コンテナ内でローカルホストに向けて Itamae を実行しています。
SSH サーバーの構成差分が特に気にならなければ、SSH サーバーを立てる方法でも良いと思います。Docker コンテナ的にはSSH サーバー立てるなということもありますが、テストのためのコンテナなら良いと思います。
SSH 経由で動かすなら下記の記事などを参考にすると良いと思います。
CircleCI + Docker による Itamaeレシピの継続的インテグレーション
コンテナを定義する
コンテナ内で Itamae とServerspec を動かすため、Ruby と合わせてインストールします。Itamae のレシピは COPY
でコンテナ内に配置します。
FROM alpine
RUN apk update && apk upgrade
RUN apk add --no-cache ruby ruby-io-console ruby-json
RUN gem install itamae rake serverspec --no-ri --no-rdoc
COPY . /usr/local/provisioning
CMD ["tail", "-f", "/dev/null"]
コンテナ自体は特にプロセスを実行する必要が無いので、代わりに tail -f /dev/null
を実行させてテスト実行まで待機させています。 RUN
はなるべく1行にまとめて実行したほうが良いですが、読みづらいので分けて書いておきます。
cf. Alpine Linux で軽量な Docker イメージを作る
Itamae + Serverspec を実行する
イメージをビルドして動かした後、 docker exec
を使ってコンテナ上で Itamae とServerspec を動かすだけです。
docker build -t spec -f Dockerfile --no-cache .
docker run --name ci -it -d spec
docker exec -it ci /bin/sh -c 'cd /usr/local/provisioning && itamae local roles/ci.rb'
docker exec -it ci /bin/sh -c 'cd /usr/local/provisioning && rake spec'
CircleCI でテストを実行する
CircleCI は docker exec
に対応していないので、 lxc-attach
を使います。ローカルで構築した構成はそのまま使えるので、コマンドだけ置き換えればOK です。
machine:
services:
- docker
dependencies:
pre:
- docker build -t spec -f Dockerfile --no-cache .
- docker run --name ci -it -d spec
test:
pre:
- sudo lxc-attach -n "$(docker inspect --format '{{.Id}}' ci)" -- /bin/sh -c 'cd /usr/local/provisioning && itamae local roles/ci.rb'
override:
- sudo lxc-attach -n "$(docker inspect --format '{{.Id}}' ci)" -- /bin/sh -c 'cd /usr/local/provisioning && rake spec'
気になるところ
Docker コンテナに Ruby 環境 (Itamae と Serverspec) を作らなくて良いように、itamae
を lxc-attach
経由で実行できると良さそう。今のDocker イメージだとビルドに30秒くらいかかる。