概要
以下の図のような E2E
テスト環境基盤 を構築しました。
これは以下からコードを clone
し bash deploy.sh
を実行すると環境が出来上がったりします。
※docker
, docker-compose
が使えることが前提です
なんでこんな面倒な構成をするんだという所もありますが、とりあえず環境を作ってみたという所が大きいです。
いつの間にやら docker-compose
の書き方も変わったりしていたのでいい勉強になりました。
ということでこの テスト環境基盤の説明・デプロイ方法と、 docker-compose.yml
の書き方を記事にしました。
ただし内容が多いので2つの記事に分けています。具体的には下記のようになっています。
この記事に書かれていること
- docker-compose の記載方法の説明
- version
- services
- image
- build
- context
- dockerfile
- args
- ports
- volumes
- links
- depends_on
- environment
- まとめ
もう一つの記事に書かれていること
Selenium, Jenkins, Ruby(Capybara) の E2E テスト環境基盤を Docker で構築したときの知見のまとめ(環境編)
-
Selenium
,Ruby Script
,Jenkins
によるE2Eテスト環境基盤の説明 - 上記コンテナ達のデプロイ方法
- 上記
Jenkins(docker)
の起動・初期設定・ジョブの実行 - まとめ
という事でこちらは 書き方編 になります。宜しくお願いします。
docker-compose の記載方法の説明
はじめに
docker-compose.yml
で登場する image
は以下の3種類です。
( tag
を指定しているのは tag
の upgrade
で動かなくなるのを避けるためです)
- selenium
- selenium/standalone-firefox-debug:3.0.1
- ruby
- ruby:2.4
- jenkins
- jenkins:2.32.1
これは docker-compose.yml
に以下のように記載され分割されています。
version: '2.0'
services:
selenium:
#...
ruby:
#...
jenkins:
#...
docker-compose up -d
を実行すれば docker-compose.yml
を読み込み、各イメージを作ってくれる訳です。
さて、今回 E2Eテスト環境基盤の構築のために作成した docker-compose.yml
は以下のようになっています。
これをもとに記載方法を説明していきます。
version: '2.0'
services:
# for e2e selenium
selenium:
image: selenium/standalone-firefox-debug:3.0.1
container_name: selenium
restart: always
ports:
- 5900:5900 #VNC
expose:
- 4444 #selenium
volumes:
- ./ruby/download:/home/seluser # for download file
# for scripts
ruby:
build:
context: ./ruby
dockerfile: Dockerfile
args:
- password=${DOCKER_PASSWORD}
container_name: ruby
restart: always
depends_on:
- selenium
volumes:
- ./ruby:/usr/src/app
environment:
- SELENIUM_HOST=${SELENIUM_HOST}
- SELENIUM_PORT=${SELENIUM_PORT}
# for execute tool
jenkins:
build: ./jenkins/
container_name: jenkins
restart: always
ports:
- "18080:8080"
- "50000:50000"
volumes:
- ./jenkins:/var/jenkins_home
environment:
- DOCKER_PASSWORD=${DOCKER_PASSWORD}
version
: 全てを取り締まる全知全能なるもの
version: '2.0'
version
は docker-compose.yml
の記載が version 1
のものか version 2
のものかを判定するために使われます。
今回は複数のコンテナを services
という項目内でまとめています。これは version 2
の記載方法になります。
例えばこれを version "1"
とかにするとエラーになります。
一番頭に書いておく大切なやつです。
services
: コンテナを統べる母なるもの
services:
selenium:
#...
ruby:
#...
jenkins:
#...
今回のように複数のコンテナを同時に起動したり、削除したりしたいときは、この services
を使うと実現ができます。
こうしてまとめていると docker-compose up
を実行すると selenium
, ruby
, jenkins
をそれぞれコンテナ化してくれます。
またコンテナを削除をするときもまとめて削除をしてくれたりします。
image
: 教えよ、汝の名を
services:
selenium:
image: selenium/standalone-firefox-debug:3.0.1
#...
image
にはどの Docker image
を使用するかを記載します。
ここで記載したイメージからコンテナを作成するのでとっても重要なものです。
例えば上記 selenium
の例では selenium/standalone-firefox-debug
という名前の付いたイメージの 3.0.1
のタグを付いたものを取得します。
タグというのはおおざっぱに言うとイメージの version
のようなものです。
例えば ruby
のイメージであれば ruby:2.3
とすると Ruby
の version
が 2.3
のイメージを取得できます。
タグは指定しなければ latest
という扱いになり、 latest (最新)
というタグのついたイメージが取得されます。
build
: 創りしは新たな命、吹き込むは次への希望
services:
ruby:
build:
context: ./ruby
dockerfile: Dockerfile
args:
- password=${DOCKER_PASSWORD}
build
は コンテナを作成するときの Dockerfile
を指定するオプションです。
context
や args
の子オプションを持ちますがこれらは省略可能です。
例えば下記のように記載するとカレントディレクトリ(docker-compose.yml
のあるディレクトリ)の Dockerfile
という名前のファイルを見つけに行きます。
services:
ruby:
build: .
context
には Dockerfile
が置かれているディレクトリの場所を記載します
dockefile
には イメージを build
する際のファイルを指定します。
args
には Dockerfile
に渡す引数を記載します。今回はコンテナ作成時の root
ユーザに設定するパスワードを passwaord
という名前の引数で渡しています。参考
よって今回私が記載した ruby
のイメージは ./ruby/Dockerfile
に $DOCKER_PASSWORD
を引数として渡したイメージを作っているということです。
container_name
: これは運命。其方を示す無二なるもの
services:
selenium:
container_name: selenium
container_name
でコンテナの名前を指定することができます。
通常コンテナを作成するときは、ランダムに友達のような名前がコンテナに割り振られます。
その名前を自分の好きな名前に指定ができるオプションです。
Docker
のコンテナの名前はとても大きな意味を持ちます。
例えばコンテナの名前は必ず一意で無ければなりません。これは様々な操作やオプション設定の際に名前を使用することがあるからです。
(これ、ちょっと前の version
だと使えなかったんですよねぇ……)
restart
: 不死なるもの。それは栄光か地獄か
services:
selenium:
restart: always
restart
オプションを付けるとコンテナを自動で起動することができます。
今回は常に再起動をする always
を指定していますが、回数や再起動をしないオプションも設定できます。
例えばホスト側を再起動した際に、通常コンテナは再起動しません。
docker ps
では見えなくなるので消えたかのように思いますが docker ps -a
とすると見えます。
眠っちゃってるんですね。
このときにホスト側が起動(Docker
が起動)したときに、自動でコンテナを起動できるので便利なオプションです。
ただしコンテナがエラーを起こして起動ができなかったときでも、 always
は健在です。
こんな時はコンテナは起動と停止を繰り返すリビングデッドみたいになります。
ports
: 深淵をのぞく時、深淵もまたこちらをのぞいているのだ
services:
selenium:
ports:
- 5900:5900
ports
は一言でいうとポートフォワディングです。<hostのPort>:<containerのPort>
という記載ルールでポート番号を記載します。
通常コンテナはポートを外部に公開しません。外部からコンテナ内部の特定のポートに接続をしたいときはこの設定を入れましょう。
ただしこの設定を入れると、ホストの外からもコンテナへ接続ができる状態にもなり、セキュリティ的に危険にさらされる可能性があります。
ポートフォワディングをするときはセキュリティ的に大丈夫かという観点を持ってやりましょう。
どうしてもセキュリティに関わるものをポートフォワディングしないといけないときは、ホスト側のポートの値を別の物にするのも手です。
expose
: モーゼは海を絶ち示した。我らの道はここなり
services:
selenium:
expose:
- 4444
expose
は指定したポートをコンテナの外へ公開するオプションです。
ただし ports
とは異なり、公開に制限があります。
例えば上記の設定では selenium
の 4444
ポートに接続できるのはホストと他のコンテナのみになります。
接続の際はコンテナのIPを取得してポートを指定する必要があります。
ports に比べて使い勝手がやや落ちるものの、セキュアな設定となります。
links
, depends_on
: 縁を紡ぎ虹を架ける。其方は独りではない
services:
selenium:
#...
ruby:
depens_on:
- selenium
links
, depends_on
はコンテナ間の接続のためのオプションで、ほぼ同じ意味合いです。
例えば上記のように ruby
と selenium
を接続させます。
こうすると ruby
コンテナから selenium
という名前で selenium
コンテナの IP
を参照することができるようになります。
これは ruby
コンテナの /etc/hosts
に記載が追加されるためです。
こうしておけば ruby
コンテナから ping
を以下のように飛ばしたりすることもできます。
ping selenium
また、 links
と depends_on
の違いですが、 depends_on
を指定していると、コンテナの作成順序をコントロールすることができるようになります。
つまり上記の設定は selenium
のコンテナが作成された後に ruby
のコンテナを作成し、そして接続の関係を作るというオプションになります。
volumes
: 同じ月を眺めていると思えば、孤独な闇夜も恐れずにすむ
services:
jenkins:
volumes:
- ./jenkins:/var/jenkins_home
volumes
オプションを使えばホストとコンテナ間で、指定したディレクトリを共有することができます。
これにより以下の3つが実現されます。
- 1.コンテナに接続しなくても、ホスト側で共有ディレクトリに行った編集がコンテナに反映される
- 2.コンテナに接続しなくてもコンテナのファイルをホスト側からすぐに参照できる
- 3.コンテナを廃棄した後にもデータがホスト側に残る
上記の jenkins
の volumes
設定は上記 3
のために入れています。
これをすることでもし jenkins
のコンテナを再作成しても、データを残すことができます。
※ 通常はコンテナを破棄すると中のデータもすべて削除されます
よって jenkins
のコンテナで設定したジョブや設定をいつまでも残すことができます。
逆に言うと本当に初期化したいときは volumes
で設定しているディレクトリのファイルをホスト側で削除したりする必要がありますね。
environment
: 活け、其方の名は……ノビタニアン!
services:
ruby:
environment:
- SELENIUM_HOST=${SELENIUM_HOST}
- SELENIUM_PORT=${SELENIUM_PORT}
environment
に記載を入れると、イメージからコンテナを作成するときに、環境変数をセットすることができます。
ちなみに docker-compose.yml
でホスト側で使っている環境変数を使いたいときは $VALUE
か ${VALUE}
でできます。
まとめ
-
Selenium
+Ruby Script
+Jenkins
による E2E自動テストの環境をDocker
にて構築しました。 - 構築には
docker-compose
を使い一元的に各コンテナを管理するようにしました。 - この記事には
docker-compose
の詳しい書き方を記載しました。
もしこの基盤の詳細やデプロイ方法を知りたいという方は下記をご参照ください。
Selenium, Jenkins, Ruby(Capybara) の E2E テスト環境基盤を Docker で構築したときの知見のまとめ(環境編)