Azure DevOpsを使って、PHPコンテナをWeb App for Containersに簡単デプロイ

何度もつぶやいたことがある気がするけど、予定が詰まっているときに限って仕事と関係ないコードを書いてしまい、結局ブログまで書き始めてしまった渡辺です。

2019-03-03追記

記事執筆時点ではDeploy to slotが正常に動作しなかったのですが、Azure App Service Deploy タスクの4.*がリリースされていたのでこちらを使うように変更したところ、正常にデプロイできました!

Azure DevOps

azure.microsoft.com

CI/CDを実現するためのサービスで、以下のような機能が含まれています。

  • Azure Boards - かんばんボード、バックログダッシュボードなど...
  • Azure Pipelines - CI/CDを実行するサービス
  • Azure Repos - Git Repositoryサービス
  • Azure Test Plans - 探索的テスト ツール(?)
  • Azure Artifacts - パッケージ管理ツール(?)

今回は、Azure Test Plans/Azure Artifactsは試していないのでよくわかってないです...。

Azure DevOps Projectの作成

Azure DevOps Projectの作成を開始すると下記のように、ウィザード形式で設定が進みます。

f:id:kaz_29:20190113170315j:plain
Runtimeの選択

  • 次にFrameworkの選択です。Simple PHP/Larabelが選択できますが、今回はSimple PHPを選択します。

f:id:kaz_29:20190113170551j:plain
Frameworkの選択

  • 次にDploy先のサービスを選択します。今回はDocker Containerを使用しますので、Web App for Containersを選択します。

f:id:kaz_29:20190113170727j:plain
Serviceの選択

  • 最後に、プロジェクトの設定をします。

f:id:kaz_29:20190113171043j:plain
プロジェクトの設定

  • Additional settings をクリックすると、Containerや、Container Registryの細かな設定ができます。

f:id:kaz_29:20190113171639j:plain
Additional settings

設定が完了すると、いろいろとデプロイが進みAzure Portalに以下のような画面が現れます。

f:id:kaz_29:20190113172801j:plain
DevOps Projects

画面右上の、エンドポイントURLをクリックするとdeployされたサイトを見ることができます。

f:id:kaz_29:20190113173041j:plain
作成直後のWebサイト

ここまでで、10数分くらいですかね。これで、リポジトリからPipeline経由でデプロイされる環境ができちゃいます。簡単ですね。

Simple PHPの中身を覗いてみる

sshでcloneするには、Azure Reposの右上にある Clone をクリックすると出てくる画面で、Manage SSH keys に遷移すると公開鍵を登録することができます。

f:id:kaz_29:20190113181341j:plain
Azure Repos

Simple PHPをdeployすると初期状態では、リポジトリには下記のようなシンプルなPHPアプリが生成されています。

$ tree -L 2 .
.
├── Application
│   ├── Dockerfile
│   ├── LICENSE
│   ├── Readme.md
│   ├── composer.json
│   ├── css
│   ├── fonts
│   ├── img
│   └── index.php
└── ArmTemplates
 ├── container-webapp-template.json
 └── containerRegistry-template.json

ちょっと中身を覗いてみましょう。

Application/composer.json

application-insightsのパッケージだけが含まれている、シンプルなアプリ

{
    "require": {
        "microsoft/application-insights": "*"
    }
}

Application/Dockerfile

PHPコミュニティ公式の 7.0.6-apache をベースにしているようです。 いくつかのaptパッケージ、php拡張、composerコマンドをインストールして、composer installしています。

FROM php:7.0.6-apache
LABEL maintainer="Azure App Service Container Images <appsvc-images@microsoft.com>"
RUN apt-get update -y && apt-get install -y openssl zip unzip git
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN docker-php-ext-install pdo mbstring

COPY . /var/www/html/
RUN composer install

Application/index.php

autoloadして、application-insightsにリクエストログ投げているだけのほぼ静的なページです。

<?php
    require_once 'vendor/autoload.php';
    $app_insights_instrumentation = getenv('APPINSIGHTS_INSTRUMENTATIONKEY');
    $telemetryClient = new \ApplicationInsights\Telemetry_Client();
    $telemetryClient->getContext()->setInstrumentationKey($app_insights_instrumentation);
    $telemetryClient->trackRequest('Server Requests','Azure DevOps Project', time());
    $telemetryClient->flush();
?>

<!DOCTYPE html>
<html lang="en">

...

ArmTemplates/

ArmTemplates以下には、Container RegistryとWeb Appのプロビジョニングに使用するarm templateが保存されています。

要は、80でWebサーバさえ上がっていればOKそうです。~/Application/ って配置がちょっと気になりますが...。

Azure DevOps内の流れ

初期状態では、Pipeline内にはBuilds/Releasesの2つにpipelineが設定されています。

Build

Buildには以下のようなpipelineが設定されています。

  • materブランチの更新をトリガーに実行される
  • Container Registoryを作成する
  • コンテナをbuild
  • コンテナをContainer Registryにpush

f:id:kaz_29:20190113181533j:plain
Pipelines/Build

Releases

Releasesには以下のようなpipelineが設定されています。

  • Builds完了をトリガーに実行される
  • Web App for Containerを作成する
  • コンテナをdeployする

f:id:kaz_29:20190113181619j:plain
Pipelines/Releases

デプロイのオプションには、slotにデプロイさせる設定などがありますね。

まとめ

こんな感じで、単純なWebアプリをデプロイするpipelineがすごく簡単に構築できます。 他のサービスの構築やPipeline内でテスト、静的解析を実行したり、B/G deploymentをするなど、普段別サービスを使ってやっていることを置き換えていろいろ試してみようと思います。

おまけ

slotを使って、B/G deploymentをしようとしたのですが、staging slotにdeployする設定にしたのにproduction slotにもデプロイされてしまう謎挙動が発生して解決できていません (;_; 2019-03-03修正