はじめに
今回はコンテナ化されたWebアプリケーションをApp Service上で実行することのできる「Web App for Containers」について説明します。
App Serviceでコンテナ化アプリを実行する「Web App for Containers」とは
AzureでWebアプリケーションをデプロイする際の選択肢としてApp Serviceがあります。App ServiceにはDockerによってコンテナ化されたWebアプリケーションを実行することができる「Web App for Containers」と呼ばれる機能があります。
Web App for Containersとは
Web App for ContainersはApp Service上でコンテナ化されたWebアプリケーションをデプロイおよび実行することのできるサービスです。
App Serviceでも、.NET、Java、Node.js、PHP、Rubyで実装されたアプリケーションをWebアプリケーションとして公開できますが、これらの言語以外で実装されたWebアプリケーションをApp Serviceで実行したい場合にも、アプリケーションをコンテナ化することでWeb App for Containersで実行できます。これによってローカルマシンなどの開発環境で構築し、テストしたDockerコンテナをそのままApp Service上にデプロイできるようになります。
Web App for Containersにデプロイできるコンテナは、一つのDockerイメージを使った「単一コンテナ」のパターンと、Docker Composeを使い複数のコンテナをまとめて実行する「複数コンテナ」のパターンの2通りがあります。Docker Composeおよび複数コンテナによるWeb App for Containersへのデプロイについては、次回詳しく紹介します。
また、コンテナイメージは、これまで紹介したAzure Container Registry(ACR)やDocker HubからWeb App for Containersへプルすることができます。
Web App for Containersを使うメリット
前述の通り、Web App for ContainersはDockerコンテナを実行できるサービスのため、コンテナ化アプリケーションが持つメリットを活かせます。コンテナとしてコードと設定ファイルをパッケージ化することで異なる環境でも一貫性のある状態でアプリケーションを実行できます。
またWeb App for ContainersはApp Serviceの利用形態の一つのため、PaaSであるApp Serviceが持つ機能や特徴をそのまま享受できます。負荷分散や自動スケールといったWebアプリケーションの実行時に有用な機能であったり、継続的インテグレーション/継続的デプロイ(CI/CD)などのDevOps関連の機能を多く持っています。
Web App for ContainersでWebアプリのコンテナを動かしてみよう
ここからは実際にWeb App for ContainersにWebアプリケーションをデプロイしていく手順について確認していきます。
まずは単一のコンテナを作成し、Web App for Containers上で動作させる場合の手順について説明していきます。単一コンテナの場合は、これまでと同様にDockerfileを使ってDockerイメージを作成していきます。
サンプルWebアプリケーションの実装
Web App for Containers上で動作することができるWebアプリケーションの言語やフレームワークについては特に制限はありませんが、今回はPython用の軽量なWebアプリケーションフレームワークである「Flask」を使った簡単なWebアプリをサンプルとして作成していきます。まずはコンテナ上で動作させたいアプリケーションの実装を行います。任意のディレクトリ(programs等)を作成し、その中にapp.pyファイルを作成します。
コンテナ上で動作するWebアプリケーションの実装(app.py)
# Flaskのインポート・・・①
from flask import Flask
# Flaskの使用・・・②
app = Flask(__name__)
# 公開するAPIの定義・・・③
@app.route('/')
def hello():
return 'Hello World!'
# アプリケーションの起動(外部公開できる状態で起動)・・・④
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
PythonスクリプトをWebアプリケーションとして公開できるようにするために、Flaskのインポート(①)および初期化を行います(②)。次にWebアプリのルート(/)にアクセスされた場合に「Hello World!」と応答するようにAPIを定義・実装します(③)。最後にアプリケーションを外部公開可能な形式で起動するための設定を行います(④)。
次に、上記のPythonアプリケーションを動作させるために必要な依存ライブラリを定義するファイルrequirements.txtを、app.pyと同じディレクトリに作成します。
Webアプリに必要な依存関係の定義(requirements.txt)
flask
今回はFlaskを使ってWebアプリケーションを構築するため、必要な依存ライブラリとして「flask」と記述します。このrequirements.txtは次に作成するDockerfile内で参照します。上記2ファイルと同じディレクトリにDockerfileを作成します。
Flaskアプリ用のDockerfile(Dockerfile)
# ベースイメージとしてpythonを使用する・・・①
FROM python:3.4-alpine
# アプリケーションの配置と依存関係のインストール・・・②
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
# 公開するポートの指定・・・③
EXPOSE 5000
# 起動時のコマンドの指定・・・④
CMD ["python", "app.py"]
Pythonのアプリケーションを実行するコンテナを作成するため、FROM命令にはpythonのイメージを指定します(①)。ADD命令で実装したアプリケーション(app.py)およびrequirements.txtをコンテナ上の「/code」ディレクトリに追加します。WORKDIR命令で「/code」ディレクトリに移動後、RUN命令でpipコマンドを実行します(②)。pipコマンドはPythonの依存関係を解決するコマンドで、-rオプションで指定したファイルに記述された依存ライブラリをインストールします。ここで先程作成したrequirements.txtを指定します。Flaskではデフォルトで5000番ポートでWebアプリケーションを起動するため、EXPOSE命令でコンテナの5000番ポートを公開します(③)。最後にCMD命令でコンテナ起動時に実行するコマンドとしてpythonコマンドを指定します(④)。
Webアプリケーションをローカルマシンで動作確認する
アプリケーションの実装およびDockerfileが準備できたら、ローカルマシン上のDockerを使って動作確認をしてみましょう。docker buildコマンドでDockerイメージを作成します。
WebアプリケーションのDockerイメージの作成
$ docker build -t zerokara-webapp:latest .
ここでは「zerokara-webapp」というイメージ名と「latest」というタグを付けてイメージを作成しました。このイメージを使い、docker runコマンドでコンテナを起動してみます。
Webアプリケーションのコンテナの起動
$ docker run -p 80:5000 zerokara-webapp:latest
* Serving Flask app "app" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 397-363-158
docker runコマンドの実行後、Flaskの起動ログ(Serving Flask app...)が表示されれば起動は成功です。docker runコマンドの-pオプションでローカルマシンの80番ポートをコンテナ上の5000番にフォワードするように設定しているため、ブラウザから「http://localhost」でWebアプリケーションにアクセスすることができます。
図のように「Hello World!」がブラウザ上に表示されていれば動作確認は完了です。
Web App for Containersへのデプロイ
ローカルマシン上のDockerでWebアプリケーションの動作確認ができたら、Web App for Containersにアプリをデプロイしていきます。まずはDockerイメージをコンテナレジストリ(ACR)へプッシュします。ACRは、前回まで使用していたものをそのまま利用する前提とします。Web App for ContainsersがACRからイメージを参照するためには、前回紹介したAzure Container Instances(ACI)と同様にACRの管理者ユーザーが有効である必要があります。管理者ユーザーはACRの「アクセスキー」メニュー内の「管理者ユーザー」を有効に設定変更することで利用可能となります。コンテナレジストリへのログインが完了している状態で以下のコマンドを実行します。
Dockerイメージをプッシュ
$ docker tag zerokara-webapp:latest zerokara.azurecr.io/zerokara-webapp:latest
$ docker push zerokara.azurecr.io/zerokara-webapp:latest
これでDockerイメージはACRへプッシュされました。続いて、App Serviceを作成します。Azureポータルから「App Service」のメニューを選択します。
App Serviceのダッシュボードが表示されたら、画面左上の「作成」あるいは画面下部の「App Serviceの作成」を選択します。
App Serviceの新規作成画面で必要な項目を入力していきます。
「サブスクリプション」および「リソースグループ」は任意のものを選択します。「名前」に任意の名称を入力し、「公開」で「Dockerコンテナー」を選択します。「Dockerコンテナー」を選択することで、App ServiceをWeb App for Containersとして使用できるようになります。「オペレーティングシステム」は「Linux」を選択、「地域」は「Japan East」を選択します。
App Servcieプランは、App Serviceが使用するCPUやメモリ等のリソースなどを管理するリソースです。先程選択したリソースグループと地域に既存のApp Serviceプランが存在しない場合は、ここで新規作成をします。「Linuxプラン」の項目に、自動的に新規作成するApp Serviceプランの名称が設定されています。名称を変更したい場合は、「新規作成」という項目から変更することができます。「SKUとサイズ」にある「サイズを変更します」というリンクから、App Serviceプランのスペックを変更することができます。今回はサンプルアプリのデプロイ用途のため、無料枠である「Free F1」を選択します。
ここまで入力ができたら、画面下部の「次: Docker >」というボタンを選択します。
App Serviceの新規作成画面の「Docker」タブでは、Web App for Containersとしてデプロイするコンテナについての情報を入力していきます。
「オプション」では単一コンテナ形式のアプリか複数コンテナ形式のアプリかを選択することができます。今回は1つのDockerイメージのみで稼働するWebアプリを作成したので、「単一コンテナー」を選択します。「イメージソース」では、プルするDockerイメージの取得元を決定します。作成したDockerイメージは先程ACRへプッシュしたため、「Azure Container Registry」を選択します。
「Azure コンテナー レジストリのオプション」というセクションが表示されたら、ACRからプルするDockerイメージの情報を入力します。「レジストリ」にはACR作成時に使用したレジストリ名を選択します。「イメージ」および「タグ」には、先程作成したDockerイメージの名前とタグを入力します。
ここまで入力ができたら、「確認および作成」ボタンを選択し、入力内容を確認して「作成」を選択します。
しばらく待つとApp Serviceの作成が完了します。作成したApp Serviceの画面へ遷移すると公開用URLが表示されています。
このURLを選択して、Webアプリにアクセスできるか確認します。なお、App ServiceプランでFree F1のサイズを選択している場合は、スペックを抑えた構成のためApp Serviceの起動に少々時間がかかります。
図のようにApp ServiceのURLにアクセスして、Webアプリケーションが正しく応答を返していることを確認することができました。
Web App for Containersのコンテナ起動に関するログの確認
Web App for Containersにコンテナをデプロイ後、正常にWebアプリケーションが応答していない場合などに問題の原因を調査したい時はコンテナの起動に関するログを確認することができます。App Serviceのメニューから「デプロイ センター」を選択し、「ログ」タブを表示します。
この画面では、コンテナの起動に関するログがリアルタイムで出力されます。以下は、Web App for Containerでのコンテナ起動に成功した際のログの抜粋です。
コンテナ起動ログの例
①ACRからのDockerイメージのプル
2022-04-12T08:00:30.933Z INFO - Pulling image: zerokara.azurecr.io/zerokara-webapp:latest
2022-04-12T08:00:31.529Z INFO - latest Pulling from zerokara-webapp
2022-04-12T08:00:31.542Z INFO - Digest: sha256:ec797f56347087fef52e44836462ef7a6c9e715c2117242de5394f3bc8e8c519
2022-04-12T08:00:31.551Z INFO - Status: Image is up to date for zerokara.azurecr.io/zerokara-webapp:latest
2022-04-12T08:00:31.590Z INFO - Pull Image successful, Time taken: 0 Minutes and 0 Seconds
〜中略〜
②コンテナの起動
2022-04-12T08:00:31.692Z INFO - Starting container for site
2022-04-12T08:00:31.692Z INFO - docker run -d -p 5000:5000 --name zerokara_0_75f864e2 -e WEBSITES_ENABLE_APP_SERVICE_STORAGE=false -e WEBSITE_SITE_NAME=zerokara -e WEBSITE_AUTH_ENABLED=False -e PORT=5000 -e WEBSITE_ROLE_INSTANCE_ID=0 -e WEBSITE_HOSTNAME=zerokara.azurewebsites.net -e WEBSITE_INSTANCE_ID=caa2960fddab8849baa9843951606b1466737c205f3a8deb48d0f815679a8e87 zerokara.azurecr.io/zerokara-webapp:latest
〜中略〜
③
2022-04-12T08:00:44.810Z INFO - Container zerokara_0_75f864e2 for site zerokara initialized successfully and is ready to serve requests.
①のセクションでは、ACRにあるDockerイメージをWeb App for Container上にプルする際のログが出力されています。App Service作成時に設定したイメージ名およびタグのDockerイメージをプルしていることが分かります。
②のセクションではコンテナの起動を行っています。ローカルマシンで実行した際と同様に、docker runコマンドを使ってコンテナを起動していることが分かります。ローカルマシンでの実行時に比べてコマンドのオプションが増えていますが、これはWeb App for Containers上でコンテナを実行するために必要な追加のパラメーターを自動的にApp Service側で補完しているためです。
③のセクションにはコンテナの起動結果が表示されています。Dockerイメージのプルおよびコンテナの起動が正常に完了した場合に出力されます。異常があった場合は原因となるエラーのログが出力されるため、その情報をもとにトラブルシューティングを行っていくことになります。
まとめ
今回はApp Service上でコンテナ化されたWebアプリケーションを実行できるWeb App for Containersについて概要と単一コンテナをデプロイする方法について紹介しました。次回も引き続きWeb App for Containersを使い、複数コンテナで構築したWebアプリケーションのデプロイ方法やCI/CDの方法について紹介する予定です。
WINGSプロジェクト 秋葉龍一著/山田祥寛監修
<WINGSプロジェクトについて>テクニカル執筆プロジェクト(代表山田祥寛)。海外記事の翻訳から、主にWeb開発分野の書籍・雑誌/Web記事の執筆、講演等を幅広く手がける。一緒に執筆をできる有志を募集中