Ubuntu14.04でDockerおよびDockerComposeを使用して継続的インテグレーションテスト環境を構成する方法
Dockerからの記事
序章
継続的インテグレーション(CI)は、開発者が コードをできるだけ頻繁に統合し、自動ビルドによって共有リポジトリにマージされる前後にすべてのコミットがテストされるプラクティスを指します。
CIは開発プロセスをスピードアップし、本番環境での重大な問題のリスクを最小限に抑えますが、セットアップは簡単ではありません。 自動ビルドは、ランタイム依存関係のインストールと外部サービスの構成がローカルおよび開発環境とは異なる可能性がある別の環境で実行されます。
Docker は、環境標準化の問題を単純化して、アプリケーションのデプロイも標準化できるようにすることを目的としたコンテナー化プラットフォームです( Docker の詳細をご覧ください)。 開発者の場合、Dockerを使用すると、ローカルコンテナーでアプリケーションコンポーネントを実行することにより、ローカルマシンで本番環境をシミュレートできます。 これらのコンテナは、アプリケーションや基盤となるOSに関係なく、 DockerComposeを使用して簡単に自動化できます。
このチュートリアルでは、Docker Composeを使用して、CIワークフローの自動化を示します。
Docker化された「Helloworld」タイプのPythonアプリケーションとBashテストスクリプトを作成します。 Pythonアプリケーションを実行するには、2つのコンテナーが必要です。1つはアプリ自体用で、もう1つはアプリの依存関係として必要なストレージ用のRedisコンテナーです。
次に、テストスクリプトが独自のコンテナーでDocker化され、テスト環境全体が docker-compose.test.yml ファイルに移動されるため、すべてのテスト実行が新鮮で統一された状態で実行されていることを確認できます。アプリケーション環境。
このアプローチは、アプリケーションをテストするたびに、依存関係を含め、アプリケーションに対して同一の新しいテスト環境を構築する方法を示しています。
したがって、テスト対象のアプリケーションや基盤となるインフラストラクチャとは関係なく、CIワークフローを自動化します。
要件
始める前に、次のものが必要になります。
-
Ubuntu14.04サーバー
-
sudo権限を持つroot以外のユーザー。 このチュートリアルに従って、これを設定できます
-
DockerおよびDockerComposeにある程度精通している。 このチュートリアル中にソフトウェアをインストールするため、リンクは参照用です
-
テスト、テスト、その他の(自動化された)テスト!テストしてCIを開発ワークフローに適用することの利点についてすでに確信しているはずです。
ステップ1—Dockerをインストールします
サーバーでDockerがまだ利用できない場合、最も簡単な方法は、公式のDockerインストールスクリプトをダウンロードして実行することです。このスクリプトは、sudoパスワードの入力を求めます(Docker のインストールの詳細については、こちらを参照してください)。
- wget -qO- https://get.docker.com/ | sh
Dockerの操作を簡単にするために、次のコマンドを使用してdockerグループにユーザーを追加します。
- sudo usermod -aG docker $(whoami)
ログアウトしてからサーバーにログインし、ユーザーのdockerグループをアクティブ化します。
ステップ2—DockerComposeをインストールします
Docker Composeは、宣言型アプローチを使用してマルチコンテナーアプリケーションを定義および実行するためのオープンソースツールです。 Docker Composeをインストールするには、次のコマンドを実行します。
- sudo apt-get update
- sudo apt-get -y install python-pip
- sudo pip install docker-compose
それを確認する docker-compose
以下を実行することにより、正しくインストールされます。
- docker-compose --version
次のように表示されます。
docker-compose version 1.6.2, build 4d72027
これはあなたに言うべきです docker-compose
インストールしたバージョン。
ステップ3—「HelloWorld」Pythonアプリケーションを作成する
このステップでは、このセットアップでテストできるアプリケーションの種類の例として、単純なPythonアプリケーションを作成します。
次のコマンドを実行して、アプリケーション用の新しいフォルダーを作成します。
- cd ~
- mkdir hello_world
- cd hello_world
新しいファイルを編集する app.py
nano を使用:
- nano app.py
次のコンテンツを追加します。
from flask import Flask
from redis import Redis
app = Flask(__name__)
redis = Redis(host="redis")
@app.route("/")
def hello():
visits = redis.incr('counter')
html = "<h3>Hello World!</h3>" \
"<b>Visits:</b> {visits}" \
"<br/>"
return html.format(visits=visits)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=80)
app.py
は、Redisデータサービスに接続するFlaskに基づくWebアプリケーションです。 この線 visits = redis.incr('counter')
訪問数を増やし、Redisでこの値を維持します。 最後に、 Hello World
訪問数を含むメッセージがHTMLで返されます。
このアプリケーションには2つの依存関係があります。 Flask
と Redis
、最初の2行で確認できます。 これらの依存関係は、アプリケーションを実行する前に定義する必要があります。 新しいファイルを編集します。
- nano requirements.txt
内容を追加します。
Flask
Redis
ステップ4—「HelloWorld」アプリケーションをDocker化する
Dockerはというファイルを使用します Dockerfile
特定のアプリケーションのDockerイメージを構築するために必要な手順を示します。 新しいファイルを編集します。
- nano Dockerfile
次の内容を追加します。
FROM python:2.7
WORKDIR /app
ADD requirements.txt /app/requirements.txt
RUN pip install -r requirements.txt
ADD app.py /app/app.py
EXPOSE 80
CMD ["python", "app.py"]
各行の意味を分析してみましょう。
FROM python:2.7
:「HelloWorld」アプリケーションイメージが公式から作成されていることを示しますpython:2.7
DockerイメージWORKDIR /app
:Dockerイメージ内の作業ディレクトリをに設定します/app
ADD requirements.txt /app/requirements.txt
:ファイルを追加しますrequirements.txt
DockerイメージにRUN pip install -r requirements.txt
:アプリケーションをインストールしますpip
依存関係ADD app.py /app/app.py
:アプリケーションのソースコードをDockerイメージに追加しますEXPOSE 80
:アプリケーションがポート80(標準のパブリックWebポート)で到達できることを示しますCMD ["python", "app.py"]
:アプリケーションを起動するコマンド
これ Dockerfile
ファイルには、「HelloWorld」アプリケーションのメインコンポーネントを構築するために必要なすべての情報が含まれています。
依存関係
次に、例のより洗練された部分に進みます。 このアプリケーションでは、外部サービスとしてRedisが必要です。 これは、従来のLinux環境では毎回同じ方法で設定するのが難しいタイプの依存関係ですが、Docker Composeを使用すると、毎回繰り返し可能な方法で設定できます。
を作成しましょう docker-compose.yml
DockerComposeの使用を開始するファイル。
新しいファイルを編集します。
- nano docker-compose.yml
次の内容を追加します。
web:
build: .
dockerfile: Dockerfile
links:
- redis
ports:
- "80:80"
redis:
image: redis
このDockerComposeファイルは、「HelloWorld」アプリケーションを2つのDockerコンテナーでローカルに起動する方法を示しています。
2つのコンテナを定義します。 web
と redis
.
-
web
現在のフォルダを使用しますbuild
コンテキスト、およびからPythonアプリケーションを構築しますDockerfile
作成したファイル。 これは、Pythonアプリケーション専用に作成したローカルDockerイメージです。 それはへのリンクを定義しますredis
にアクセスするためのコンテナredis
コンテナIP。 また、UbuntuサーバーのパブリックIPを使用してインターネットからポート80にパブリックアクセスできるようにします -
redis
名前の付いた標準のパブリックDockerイメージから実行されますredis
ステップ5—「HelloWorld」アプリケーションをデプロイする
このステップでは、アプリケーションをデプロイし、最終的にインターネット経由でアクセスできるようにします。 アプリケーションを何度も同じ方法でデプロイできるため、デプロイメントワークフローの目的上、これは開発環境、ステージング環境、または実稼働環境のいずれかと見なすことができます。
The docker-compose.yml
と Dockerfile
ファイルを使用すると、以下を実行してローカル環境の展開を自動化できます。
- docker-compose -f ~/hello_world/docker-compose.yml build
- docker-compose -f ~/hello_world/docker-compose.yml up -d
最初の行は、からローカルアプリケーションイメージを構築します Dockerfile
ファイル。 2行目は web
と redis
デーモンモードのコンテナ(-d
)、で指定されているように docker-compose.yml
ファイル。
以下を実行して、アプリケーションコンテナが作成されていることを確認します。
- docker ps
これにより、2つの実行中のコンテナが表示されます。 helloworld_web_1
と helloworld_redis_1
.
アプリケーションが起動していることを確認しましょう。 のIPを取得できます helloworld_web_1
実行することによるコンテナ:
- WEB_APP_IP=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' helloworld_web_1)
- echo $WEB_APP_IP
Webアプリケーションが適切なメッセージを返していることを確認します。
- curl http://${WEB_APP_IP}:80
これは次のようなものを返すはずです:
<h3>Hello World!</h3><b>Visits:</b> 1<br/>
訪問数は、このエンドポイントに到達するたびに増加します。 UbuntuサーバーのパブリックIPアドレスにアクセスして、ブラウザーから「HelloWorld」アプリケーションにアクセスすることもできます。
独自のアプリケーションに合わせてカスタマイズする方法
独自のアプリケーションを設定するための鍵は、アプリを独自のDockerコンテナーに配置し、各依存関係を独自のコンテナーから実行することです。 次に、例に示すように、DockerComposeを使用してコンテナ間の関係を定義できます。 Docker Composeについては、このDockerComposeの記事で詳しく説明しています。
複数のコンテナでアプリケーションを実行する方法の別の例については、DockerComposeを使用したWordPressとphpMyAdminの実行に関するこの記事をお読みください。
ステップ6—テストスクリプトを作成する
次に、Pythonアプリケーションのテストスクリプトを作成します。 これは、アプリケーションのHTTP出力をチェックする単純なスクリプトになります。 スクリプトは、継続的インテグレーションデプロイメントプロセスの一部として実行する可能性のあるテストの種類の例です。
新しいファイルを編集します。
- nano test.sh
次の内容を追加します。
sleep 5
if curl web | grep -q '<b>Visits:</b> '; then
echo "Tests passed!"
exit 0
else
echo "Tests failed!"
exit 1
fi
test.sh
「HelloWorld」アプリケーションの基本的なWeb接続をテストします。 cURLを使用して、訪問数を取得し、テストに合格したかどうかを報告します。
ステップ7—テスト環境を作成する
アプリケーションをテストするには、テスト環境をデプロイする必要があります。 また、ステップ5で作成したライブアプリケーション環境と同じであることを確認したいと思います。
まず、新しいDockerfileファイルを作成して、テストスクリプトをDocker化する必要があります。 新しいファイルを編集します。
- nano Dockerfile.test
次の内容を追加します。
FROM ubuntu:trusty
RUN apt-get update && apt-get install -yq curl && apt-get clean
WORKDIR /app
ADD test.sh /app/test.sh
CMD ["bash", "test.sh"]
Dockerfile.test
公式を拡張します ubuntu:trusty
インストールするイメージ curl
依存関係、追加 tests.sh
画像ファイルシステムに、 CMD
Bashでテストスクリプトを実行するコマンド。
テストがDocker化されると、複製可能で不可知論的な方法で実行できます。
次のステップは、テストコンテナを「HelloWorld」アプリケーションにリンクすることです。 ここで、DockerComposeが再び助けになります。 新しいファイルを編集します。
- nano docker-compose.test.yml
次の内容を追加します。
sut:
build: .
dockerfile: Dockerfile.test
links:
- web
web:
build: .
dockerfile: Dockerfile
links:
- redis
redis:
image: redis
Docker Composeファイルの後半では、メインがデプロイされます web
アプリケーションとその redis
前と同じように依存関係 docker-compose.yml
ファイル。 これは、ファイルの一部であり、 web
と redis
コンテナ。 唯一の違いは、 web
コンテナはポート80を公開しなくなったため、テスト中はアプリケーションをパブリックインターネット経由で利用できなくなります。 したがって、実際のデプロイメントとまったく同じ方法でアプリケーションとその依存関係を構築していることがわかります。
The docker-compose.test.yml
ファイルはまた定義します sut
統合テストの実行を担当するコンテナ(テスト対象システムにちなんで名付けられました)。 The sut
コンテナは、現在のディレクトリを build
ディレクトリと私たちを指定します Dockerfile.test
ファイル。 それはにリンクします web
コンテナなので、アプリケーションコンテナのIPアドレスにアクセスできます test.sh
脚本。
独自のアプリケーションに合わせてカスタマイズする方法
ご了承ください docker-compose.test.yml
数十の外部サービスと複数のテストコンテナが含まれる場合があります。 すべてのコンテナーが基盤となるOSを共有するため、Dockerはこれらすべての依存関係を単一のホストで実行できます。
アプリケーションで実行するテストがさらにある場合は、次のように、それらのテスト用に追加のDockerfileを作成できます。 Dockerfile.test
上記のファイル。
次に、下にコンテナを追加できます。 sut
のコンテナ docker-compose.test.yml
追加のDockerfileを参照するファイル。
ステップ8—「HelloWorld」アプリケーションをテストする
最後に、Dockerのアイデアをローカル環境からテスト環境に拡張すると、次のコマンドを実行して、Dockerを使用してアプリケーションをテストする自動化された方法が得られます。
- docker-compose -f ~/hello_world/docker-compose.test.yml -p ci build
このコマンドは、によって必要とされるローカルイメージを構築します docker-compose.test.yml
. 使用していることに注意してください -f
指す docker-compose.test.yml
と -p
特定のプロジェクト名を示します。
次に、以下を実行して、新しいテスト環境を起動します。
- docker-compose -f ~/hello_world/docker-compose.test.yml -p ci up -d
の出力を確認してください sut
実行することによるコンテナ:
- docker logs -f ci_sut_1
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 42 100 42 0 0 3902 0 --:--:-- --:--:-- --:--:-- 4200
Tests passed!
そして最後に、の終了コードを確認します sut
テストに合格したかどうかを確認するためのコンテナ:
- docker wait ci_sut_1
0
このコマンドの実行後、 $?
になります 0
テストに合格した場合。 それ以外の場合、アプリケーションテストは失敗しました。
他のCIツールは、コードリポジトリのクローンを作成し、これらのいくつかのコマンドを実行して、実行時の依存関係や外部サービス構成を気にすることなく、アプリケーションの最新ビットでテストに合格しているかどうかを確認できます。
それでおしまい! 実稼働環境と同じ新しく構築された環境でテストを正常に実行しました。
結論
DockerとDockerComposeのおかげで、アプリケーションの構築方法を自動化することができました(Dockerfile
)、ローカル環境をデプロイする方法(docker-compose.yml
)、テストイメージの作成方法(Dockerfile.test
)、および(統合)テストの実行方法(docker-compose.test.yml
)任意のアプリケーション用。
特に、を使用する利点 docker-compose.test.yml
テスト用のファイルは、テストプロセスが次のとおりです。
- 自動化可能:ツールが実行する方法
docker-compose.test.yml
テスト対象のアプリケーションから独立しています - 軽量:数百の外部サービスを単一のホストにデプロイして、複雑な(統合)テスト環境をシミュレートできます
- 不可知論者:CIプロバイダーのロックインを回避し、テストは任意のインフラストラクチャおよびDockerをサポートする任意のOSで実行できます
- Immutable :ローカルマシンで合格したテストはCIツールで合格します
このチュートリアルでは、単純な「HelloWorld」アプリケーションをテストする方法の例を示します。
次に、独自のアプリケーションファイルを使用し、独自のアプリケーションテストスクリプトをDocker化して、独自のアプリケーションを作成します。 docker-compose.test.yml
新鮮で不変の環境でアプリケーションをテストします。