Dockerからの記事
前書き
継続的統合(CI)は、開発者が可能な限り頻繁にコードを統合し、すべてのコミットが_自動化されたビルド_によって共有リポジトリにマージされる前後にテストされるプラクティスを指します。
CIは開発プロセスを高速化し、本番環境での重大な問題のリスクを最小限に抑えますが、設定は簡単ではありません。自動ビルドは、*ランタイム依存関係*のインストールと*外部サービス*の構成がローカル環境と開発環境と異なる場合がある異なる環境で実行されます。
Dockerは、環境の標準化の問題を簡素化することを目的としたコンテナ化プラットフォームであるため、アプリケーションの展開も標準化できます(https://www.digitalocean.com/community/tutorials / the-docker-ecosystem-an-overview-of-containerization [Dockerの詳細])。 開発者の場合、Dockerを使用すると、ローカルコンテナでアプリケーションコンポーネントを実行することにより、ローカルマシンで運用環境をシミュレートできます。 これらのコンテナは、アプリケーションや基盤となるOSに関係なく、https://github.com/docker/compose [Docker Compose]を使用して簡単に自動化できます。
このチュートリアルでは、Docker Composeを使用してCIワークフローの自動化を示します。
Docker化された「Hello world」タイプのPythonアプリケーションとBashテストスクリプトを作成します。 Pythonアプリケーションを実行するには2つのコンテナーが必要です。1つはアプリ自体用で、もう1つはアプリの依存関係として必要なストレージ用のRedisコンテナーです。
その後、テストスクリプトは独自のコンテナーでDocker化され、テスト環境全体が* docker-compose.test.yml *ファイルに移動されるため、すべてのテスト実行が新鮮で均一なアプリケーション環境で実行されていることを確認できます。
このアプローチは、アプリケーションをテストするたびに、依存関係を含めて、アプリケーションの同一の新しいテスト環境を構築する方法を示しています。
したがって、テスト対象のアプリケーションおよび基盤となるインフラストラクチャとは無関係に、CIワークフローを自動化します。
必要条件
開始する前に、次のものが必要です。
-
Ubuntu 14.04サーバー
-
sudo特権を持つ非rootユーザー。 これを設定するには、https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-14-04 [tutorial]に従ってください。
-
Dockerおよびhttps://www.digitalocean.com/community/tutorials/how-に精通しているto-install-and-use-docker-compose-on-ubuntu-14-04 [Docker Compose];このチュートリアルでソフトウェアをインストールするため、リンクは参照用です
-
テスト、テスト、その他の(自動化された)テスト
ステップ1-Dockerのインストール
サーバーでDockerがまだ使用できない場合、最も簡単な方法は、公式のDockerインストールスクリプトをダウンロードして実行することです。このスクリプトは、sudoパスワードの入力を求めます/ how-to-install-and-use-docker-getting-started [here]):
wget -qO- https://get.docker.com/ | sh
Dockerでの作業を簡単にするために、次のコマンドを使用してユーザーを* docker *グループに追加します。
sudo usermod -aG docker $(whoami)
ログアウトしてからサーバーにログインし、ユーザーの* docker *グループをアクティブにします。
ステップ2-Docker Composeのインストール
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-「Hello World」Pythonアプリケーションを作成する
このステップでは、このセットアップでテストできるアプリケーションのタイプの例として、単純なPythonアプリケーションを作成します。
以下を実行して、アプリケーションの新しいフォルダーを作成します。
cd ~
mkdir hello_world
cd hello_world
_nano_を使用して新しいファイル `+ app.py +`を編集します。
nano app.py
次のコンテンツを追加します。
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 `はhttp://flask.pocoo.org/[Flask]に基づいたRedisデータサービスに接続するWebアプリケーションです。 行 ` visits = redis.incr( 'counter')`は訪問数を増やし、この値をRedisに保持します。 最後に、訪問数を含む ` Hello World +`メッセージがHTMLで返されます。
このアプリケーションには、2つの依存関係、「+ Flask 」と「 Redis +」があり、最初の2行で確認できます。 これらの依存関係は、アプリケーションを実行する前に定義する必要があります。 新しいファイルを編集します。
nano requirements.txt
内容を追加します。
requirements.txt
Flask
Redis
ステップ4-「Hello World」アプリケーションをドッキングする
Dockerは、「+ Dockerfile +」というファイルを使用して、特定のアプリケーションのDockerイメージを構築するために必要な手順を示します。 新しいファイルを編集します。
nano Dockerfile
次の内容を追加します。
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 +
:「Hello World」アプリケーションイメージが公式の+ 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 +`ファイルには、「Hello World」アプリケーションのメインコンポーネントをビルドするために必要なすべての情報が含まれています。
依存関係
次に、例のより洗練された部分に進みます。 このアプリケーションでは、外部サービスとしてRedisが必要です。 これは、従来のLinux環境では毎回同じ方法で設定するのが難しいタイプの依存関係ですが、Docker Composeを使用すると毎回繰り返し設定できます。
`+ docker-compose.yml +`ファイルを作成して、Docker Composeの使用を開始しましょう。
新しいファイルを編集します。
nano docker-compose.yml
次の内容を追加します。
docker-compose.yml
web:
build: .
dockerfile: Dockerfile
links:
- redis
ports:
- "80:80"
redis:
image: redis
このDocker Composeファイルは、2つのDockerコンテナーで「Hello World」アプリケーションをローカルに起動する方法を示しています。
2つのコンテナ、「+ web 」と「 redis +」を定義します。
-
+ web +`は `+ build`コンテキストに現在のフォルダーを使用し、作成したばかりの
+ Dockerfile`ファイルからPythonアプリケーションをビルドします。 これは、Pythonアプリケーション専用に作成したローカルDockerイメージです。 `+ redis `コンテナIPにアクセスするために、 ` redis +`コンテナへのリンクを定義します。 また、UbuntuサーバーのパブリックIPを使用して、インターネットからポート80をパブリックにアクセスできるようにします -
`+ redis `は、 ` redis +`という名前の標準のパブリックDockerイメージから実行されます。
ステップ5-「Hello World」アプリケーションをデプロイする
この手順では、アプリケーションを展開し、最終的にはインターネット経由でアクセスできるようにします。 アプリケーションを何度も同じ方法でデプロイできるため、デプロイメントワークフローの目的上、これを開発環境、ステージング環境、または運用環境のいずれかと見なすことができます。
`+ 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行目は、 `+ docker-compose.yml +`ファイルで指定されているように、デーモンモード( `+ -d +
)で `+ web `および ` redis +`コンテナを実行します。
次を実行して、アプリケーションコンテナが作成されたことを確認します。
docker ps
これにより、「+ helloworld_web_1 」と「 helloworld_redis_1 +」という名前の2つの実行中のコンテナが表示されます。
アプリケーションが起動していることを確認してみましょう。 次を実行することで、 `+ helloworld_web_1 +`コンテナのIPを取得できます。
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アドレスにアクセスして、ブラウザーから「Hello World」アプリケーションにアクセスすることもできます。
独自のアプリケーション用にカスタマイズする方法
独自のアプリケーションを設定するための鍵は、独自のDockerコンテナーにアプリを配置し、独自のコンテナーから各依存関係を実行することです。 次に、例に示すように、Docker Composeを使用してコンテナ間の関係を定義できます。 Docker Composeの詳細については、https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-compose-on-ubuntu-14-04 [Docker Composeの記事]をご覧ください。
複数のコンテナでアプリケーションを実行する方法の別の例については、https://www.digitalocean.com/community/tutorials/how-to-install-wordpress-and-phpmyadmin-with-docker-composeの実行に関するこの記事をお読みください。 -on-ubuntu-14-04 [Docker Composeを使用したWordPressおよびphpMyAdmin]。
ステップ6-テストスクリプトを作成する
次に、Pythonアプリケーション用のテストスクリプトを作成します。 これは、アプリケーションのHTTP出力をチェックする単純なスクリプトです。 このスクリプトは、継続的インテグレーションの展開プロセスの一部として実行する可能性があるテストの種類の例です。
新しいファイルを編集します。
nano test.sh
次の内容を追加します。
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 +`は、「Hello World」アプリケーションの基本的なWeb接続をテストします。 cURLを使用して訪問数を取得し、テストに合格したかどうかのレポートを作成します。
ステップ7-テスト環境を作成する
アプリケーションをテストするには、テスト環境を展開する必要があります。 そして、*ステップ5 *で作成したライブアプリケーション環境と同一であることを確認します。
まず、新しいDockerfileファイルを作成して、テストスクリプトをDocker化する必要があります。 新しいファイルを編集します。
nano Dockerfile.test
次の内容を追加します。
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化されると、複製可能で不可知な方法で実行できます。
次のステップは、テストコンテナを「Hello World」アプリケーションにリンクすることです。 Docker Composeが再び助けになります。 新しいファイルを編集します。
nano docker-compose.test.yml
次の内容を追加します。
docker-compose.test.yml
sut:
build: .
dockerfile: Dockerfile.test
links:
- web
web:
build: .
dockerfile: Dockerfile
links:
- redis
redis:
image: redis
Docker Composeファイルの後半では、前の `+ docker-compose.yml `ファイルと同じ方法で、メインの ` web `アプリケーションとその ` redis `依存関係をデプロイします。 これは、「 web 」および「 redis 」コンテナを指定するファイルの一部です。 唯一の違いは、「 web +」コンテナがポート80を公開しないため、テスト中にアプリケーションがパブリックインターネット経由で利用できなくなることです。 したがって、アプリケーションとその依存関係は、実際の展開とまったく同じ方法で構築されていることがわかります。
`+ docker-compose.test.yml `ファイルは、統合テストの実行を担当する ` sut `コンテナー(testsの下の_systemの名前)も定義します。 ` sut `コンテナは、現在のディレクトリを ` build `ディレクトリとして指定し、 ` Dockerfile.test `ファイルを指定します。 ` web `コンテナにリンクしているため、アプリケーションコンテナのIPアドレスは ` test.sh +`スクリプトからアクセス可能です。
独自のアプリケーション用にカスタマイズする方法
`+ docker-compose.test.yml +`には、多数の外部サービスと複数のテストコンテナーが含まれている場合があります。 Dockerは、すべてのコンテナが基盤となるOSを共有するため、これらすべての依存関係を単一のホストで実行できます。
アプリケーションで実行するテストがさらにある場合は、上記の `+ Dockerfile.test +`ファイルと同様に、追加のDockerfileを作成できます。
次に、追加のDockerfilesを参照して、 `+ docker-compose.test.yml `ファイルの ` sut +`コンテナの下に追加のコンテナを追加できます。
ステップ8-「Hello World」アプリケーションをテストする
最後に、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とDocker Composeのおかげで、アプリケーションの構築方法( + Dockerfile +
)、ローカル環境の展開方法( + docker-compose.yml +
)、テストイメージの構築方法( ` + Dockerfile.test + )、およびアプリケーションのテスト(統合)テストの実行方法(
+ docker-compose.test.yml + `)。
特に、テストに `+ docker-compose.test.yml +`ファイルを使用する利点は、テストプロセスが次のとおりであることです。
-
自動化可能:ツールが `+ docker-compose.test.yml +`を実行する方法は、テスト対象のアプリケーションに依存しません
-
軽量:数百の外部サービスを展開可能 複雑な(統合)テスト環境をシミュレートする単一のホスト
-
アグノスティック:CIプロバイダーのロックインを回避し、テストを任意の場所で実行できます インフラストラクチャおよびDockerをサポートするすべてのOS
-
* Immutable *:ローカルマシンに合格したテストはCIツールに合格します
このチュートリアルでは、単純な「Hello World」アプリケーションをテストする方法の例を示します。
ここで、独自のアプリケーションファイルを使用し、独自のアプリケーションテストスクリプトをDockerizeし、独自の `+ docker-compose.test.yml +`を作成して、新鮮で不変の環境でアプリケーションをテストします。