Visual Web Developer 2010 Expressによる開発
今回は、アップロードしたVHDをマウントし、MySQLが起動できることを確認してみます。VHDをマウントするには、WebRoll.dll(やWorkerRole.dll)内にマウントするための処理を記述しておく必要があります。WebRole.dllは、C#ソースコードのWebRole.csをビルドして作成します。
ただ、これまで利用してきたWindows Azure PDT(Windows Azure Tools for Eclispeを組み込んだEclipse PDT)では、WebRole.csの作成やビルドができません。また、Windows Azure PDTには、プロジェクト作成時にAzureドライブを利用するための設定画面があるのですが、そこで設定を行なっても、エラーが出てうまく動きません。
そこで、今回は、第2回 でインストールしたVisual Web Developer 2010 Express(VWD)を利用して、WebRole.csの作成と、Azureへデプロイするパッケージの作成を行います。基本的な操作やファイル構成はWindows Azure PDTと大きく変わりありません。また、VWDでPHPを利用する際に必要となるファイルもこれまで利用していたものを流用することができます。
IISでPHPを動作させる
まず、PHPをIIS上で動作させるように設定します。VWDを起動し、ファイルメニューから、新規プロジェクトを作成します。プロジェクトには、「 Visual C#」の「Cloud」から「Windows Azure Project」を選択します(図1 ) 。
図1 Visual Web Developer 2010 Expressで、Windows Azure Projectを作成
すると、図2 のような画面が表示されるので、「 ASP.NET Web Role」を選択し、OKを押します。
図2 Windows Azure Project(ASP.NET Web Role)を作成
しばらくするとVWDの画面が表示されますので、画面右側のソリューションエクスプローラーにPHP関連フォルダを追加します。具体的には、以下のように、第5回 で作成した、phpフォルダをWebRole1下に配置します(Windows Explorerで各フォルダをコピーし、ソリューションエクスプローラー上でペーストします) 。
また、今回はMySQLの動作確認のために、phpMyAdminよりも軽量な管理ツールであるAdminerを利用してみます。AdminerのWebサイト からファイルをダウンロードし、ファイル名をindex.phpに変更して、admnierフォルダ下に保存し、プロジェクトに追加します。
図3 プロジェクトにphpとAdminerフォルダを追加
フォルダをコピーしたら、php.iniのプロパティから、ビルドアクションをコンテンツに変更します。
また、PHPをCGIとして動作させるための設定ファイルとなるWeb.config、Web.roleconfig、および、index.phpを追加します。これらもWindows Azure PDTが自動生成したものが流用できます。phpフォルダを追加したのと同じように、WebRole1にコピー&ペーストし、図4 のように配置します。
図4 Web.config、Web.roleconfig、index.phpを追加
それぞれのファイルは以下のような内容です。index.phpについては、MySQLへのログインで必要になるIPアドレスを知るために、サーバ変数LOCAL_ADDRを出力するように設定しておきます。
リスト1 Web.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.webServer>
<fastCgi>
<application fullPath="%RoleRoot%\approot\php\php-cgi.exe" />
</fastCgi>
</system.webServer>
</configuration>
リスト2 Web.roleconfig
<?xml version="1.0"?>
<configuration>
<system.diagnostics>
<trace>
<listeners>
<add type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener,
Microsoft.WindowsAzure.Diagnostics, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" name="AzureDiagnostics">
<filter type="" />
</add>
</listeners>
</trace>
</system.diagnostics>
<system.webServer>
<!-- DO NOT REMOVE: PHP FastCGI Module Handler -->
<handlers>
<clear />
<add name="PHP via FastCGI"
path="*.php"
verb="*"
modules="FastCgiModule"
scriptProcessor="%RoleRoot%\approot\php\php-cgi.exe"
resourceType="Unspecified" />
<add name="StaticFile" path="*" verb="*" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Read" />
</handlers>
<!-- Example WebRole IIS 7 Configation -->
<defaultDocument>
<files>
<clear />
<add value="index.php" />
</files>
</defaultDocument>
</system.webServer>
</configuration>
リスト3 index.php
<html>
<body>
<p>LOCAL_ADDR: <?php echo $_SERVER["LOCAL_ADDR"]; ?></p>
</body>
</html>
IISでPHPを動作させるための設定は以上です。
VHDをマウントするWebRole.csの作成
次に、MySQLを格納したVHDをAzureにマウントするためのWebRole.csを作成します。ソリューションエクスプローラーからWebRole.csを開き、以下のように変更します。
リスト4 WebRole.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.StorageClient;
namespace WebRole1
{
public class WebRole : RoleEntryPoint
{
private CloudDrive AzureDrive;
public override bool OnStart()
{
// 構成設定の初期値を設定
string connString = RoleEnvironment.GetConfigurationSettingValue("WindowsAzureStorageConnectionString");
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connString);
// Azureドライブのマウント
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer blobContainer = blobClient.GetContainerReference("mysql");
AzureDrive = storageAccount.CreateCloudDrive(blobContainer.GetPageBlobReference("disk.vhd").Uri.ToString());
string driveLetter = AzureDrive.Mount(0, DriveMountOptions.Force);
return base.OnStart();
}
public override void OnStop()
{
// Azureドライブのアンマウント
AzureDrive.Unmount();
base.OnStop();
}
}
}
ロールの初期化時にOnStart()、終了時にOnStop()メソッドがそれぞれ実行される仕組みです。ここでは、ストレージアカウントの情報を「WindowsAzureStorageConnectionString」から読み取り、「 mysql」コンテナの「disk.vhd」をマウントする処理を行なっています。
Windows Azureドライブを利用するためには「Microsoft.WindowsAzure.CloudDrive.dll」が必要になりますが、デフォルトではプロジェクトに含まれていないので「参照設定」( 図5 )を右クリックして「追加」を選択し、Microsoft.WindowsAzure. CloudDrive.dllを指定します。ファイルは、Azure SDKのインストール先のref内にあります(C:\Program Files\Windows Azure SDK\v1.x\ref) 。
図5 参照設定にMicrosoft.WindowsAzure.CloudDriveを追加
MySQLを起動するスタートアップタスクを作成
次に、マウントしたドライブからMySQLを起動するための処理を追加します。エディタなどでリスト5 の内容のファイルを作成し、startup.cmdとして保存します。
リスト5 startup.cmd
@echo off
netsh advfirewall firewall add rule name="mysqld" dir=in action=allow program="f:\mysql\bin\mysqld.exe" enable=yes
schtasks /Create /SC MINUTE /MO 10 /TN MySQL /TR "f:\mysql\bin\mysqld.exe" /RU "NT AUTHORITY\NETWORKSERVICE" /F
ここでは、Fドライブにマウントされたmysql.exeをファイアウォールの例外に追加し、タスクスケジューラーでmysqld.exeを起動しています。このstartup.cmdをVWDのプロジェクトに追加し、startup.cmdのプロパティから「出力ディレクトリーにコピー」( Copy to Output Directory)を「常にコピー」( Copy always)を選択します(図6 ) 。これでapproot\binディレクトリにコピーされるようになります。
図6 startup.cmdをプロジェクトに追加し、Copy to Output Directoryプロパティを「Copy always」に
Azure上でstartup.cmdを実行するには、ServiceDefinition.csdefに設定を記述する必要があります。ServiceConfiguration.cscfgと合わせて編集していきます。
ServiceConfiguration.cscfgとServiceDefinition.csdefの編集
まず、ServiceConfiguration.cscfgですが、VWDでは、ServiceConfiguration.cscfgをローカル環境とクラウド環境で使い分けられるようになっていますので、ここではServiceConfiguration.Cloud.cscfgを編集します。具体的には、マウントするストレージアカウントとして追加した「WindowsAzureStorageConnectionString」の情報をリスト6のように記述します。
前回作成したストレージアカウント「samplestorage001」とそれに対応するプライマリアクセスキー(******と略記)を利用しています。なお、これらは、ソリューションエクスプローラーからGUIで追加することもできます。
リスト6 ServiceConfiguration.Cloud.cscfgの内容
<?xml version="1.0" encoding="utf-8"?>
<ServiceConfiguration serviceName="WindowsAzureProject1" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration" osFamily="1" osVersion="*">
<Role name="WebRole1">
<Instances count="1" />
<ConfigurationSettings>
<Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" value="UseDevelopmentStorage=true" />
<Setting name="WindowsAzureStorageConnectionString" value="DefaultEndpointsProtocol=http;AccountName=samplestorage001;AccountKey=******" /> <!-- ←この行を追加 -->
</ConfigurationSettings>
</Role>
</ServiceConfiguration>
ServiceDefinition.csdefのほうにも、WindowsAzureStorageConnectionStringの定義が必要です。また、先に触れたスタートアップタスクも登録します。内容は、リスト7 のようになります。
リスト7 ServiceDefinition.csdefの内容
<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="WindowsAzureProject2" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
<WebRole name="WebRole1" vmsize="ExtraSmall">
<Startup>
<Task commandLine="startup.cmd" taskType="background" executionContext="elevated"></Task> <!-- スタートアップタスクの登録 -->
</Startup>
<Endpoints>
<InputEndpoint name="Endpoint1" protocol="http" port="80" />
</Endpoints>
<Imports>
<Import moduleName="Diagnostics" />
</Imports>
<ConfigurationSettings>
<Setting name="WindowsAzureStorageConnectionString" /> <!-- 定義の追加 -->
</ConfigurationSettings>
</WebRole>
</ServiceDefinition>
my.iniの編集とdataのコピー
最後に、前回作成したVHD内のmy.iniを編集し、第4回 で行ったようにmysqlのユーザーやデータベースを追加したdataディレクトリをコピーしておきます。
my.iniで編集する箇所は、basedirとdatadirです。ここでは以下のように設定します。
リスト8 my.iniの変更点
basedir="F:/mysql/"
datadir="F:/mysql/data/"
パッケージの作成とデプロイ後の確認
準備が整いましたので、パッケージを作成して、デプロイしてみましょう。VWDでパッケージを作成する場合、ソリューションエクスプローラーで、プロジェクト名を右クリックし、「 パッケージ」を選択します。
図7 パッケージの作成
ビルドが終わると、Windowsエクスプローラーが自動的に開きますので、cspkgと、cscfgを管理ポータルからデプロイします。デプロイが終わったら、ブラウザで確認します。トップページにはLOCAL_ADDRで表示されたIPアドレスが表示されているので、それをコピーし、adminerディレクトリを開きます。
図8 Adminerのログイン画面
先ほどコピーしたIPアドレスと、前回作成したユーザー、パスワードでログインします。無事、ログインできたら、図9 のような画面が表示されます。
図9 Adminerログイン後の画面
以上で、Azure上でMySQLを起動する方法の紹介は終わりです。
なお、今回の方法は、ドライブレターをF: に固定していたり、MySQLの起動をタスクスケジューラーで行っていたりするなど、汎用性がありません。実際にはドライブを動的に変更できるようにし、MySQLをWindowsのサービスとして起動するほうがよいでしょう。この辺りは、こちらの資料「モバイルアプリを Azure で作る - 【 データを保存する】 」が参考になります。
次回からは、Windows Azure上のPHPやMySQLを使って、簡単なサービスを作成していきます。