AzureFileStorageのエミュレータにlocalhostじゃないIPを使ってコンニチワ

'17/9/21追記
IPを使っても、結局エミュレータにアクセスするマシンを仮想化で外に置いたら、エミュレータが使えなくなった。だから外の環境からエミュレータを使うのは無理かも。
********


Azure Storage Emulatorにコンテナ内からつなごうとして、結局リバースプロキシを立てた話

 少し前に、開発に使うAzureのストレージエミュレータがローカルからしか使えん、けどアプリはDockerコンテナにしたいから、Fiddlerでリバースプロキシするってのを書いた。書いておいて、やっぱFiddlerを開発の度に立ち上げるのもアレだなーと思ったので、一般的なサーバソフトで、まずはNginXで同じことをやってみることにした。今回は.NET CoreでC#によるエミュレータへの書き込み、ブラウザで書き込んだファイルの読み出しまでやる。

 .NET CoreのC#で、Azureのストレージエミュレータにアクセスして、適当なテキストファイルを書き込むコードを用意する。
using Microsoft.WindowsAzure.Storage;

using Microsoft.WindowsAzure.Storage.Blob;

using System;
using System.IO;
using System.Threading.Tasks;

namespace PlayAzureStorage
{
class Program
{
private static async Task Func2Async()
{
var accountName = "devstoreaccount1";
var key = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==";
var connectionString = $"AccountName={accountName};"
+ $"AccountKey={key};"
+ $"BlobEndpoint=http://192.168.11.17:20000/devstoreaccount1;";
//+ "BlobEndpoint=http://127.0.0.1:1000/devstoreaccount1;";

var account = CloudStorageAccount.Parse(connectionString);
Console.WriteLine("connect: " + account.BlobStorageUri);
var blobClient = account.CreateCloudBlobClient();
var container = blobClient.GetContainerReference("test");
var isCreated = await container.CreateIfNotExistsAsync();
if (isCreated)
{
var permissions = await container.GetPermissionsAsync();
permissions.PublicAccess = BlobContainerPublicAccessType.Container;
await container.SetPermissionsAsync(permissions);
}

var name = "foo.txt";
using (var stream = File.OpenRead(name))
{
var blockBlob = container.GetBlockBlobReference(name);
blockBlob.Properties.CacheControl = "public, max-age=2678400";
blockBlob.Properties.ContentType = "text/plain";
await blockBlob.UploadFromStreamAsync(stream);
Console.WriteLine("Uploaded.");
}
}


static void Main(string[] args)
{
Func2Async().Wait();
}
}
}

 適当なテキストファイルfoo.txtをプロジェクトに用意しておく。あと接続文字列にあるIPとポート番号は自分の環境に合ったもので。今回はリバプロで、ポート20000に来たものをポート10000に飛ばす。

 NginXを落としてきて、解凍したディレクトリ内にあるnginx.confをリバプロとして動作するように書き換える。その辺に転がってるリバプロサンプルを書き換えて、外部からのC#コードによる書き込みを実行したところ二度エラーが出た。一つはヘッダをもとのままになるように設定することで解決した。もう一つはNginXがデフォではHTTPのバージョンを1.0に書き換えてしまうためにエラーになったので、バージョン1.1で動くように設定。
 最終的に設定ファイルは下記のとおり。
nginx.conf

worker_processes 1;

events {
worker_connections 1024;
}

http {
sendfile on;

upstream app_servers {
server 127.0.0.1:10000;
}

server {
listen 20000;

location / {
proxy_pass http://app_servers;
proxy_http_version 1.1;
proxy_set_header Host $host;
}
}
}

 nginx.confを用意したら、"start nginx"で起動しておく。

 まずストレージエミュレータを起動する。次に、用意しておいたC#コードを実行して、ストレージエミュレータへの書き込みを実行してみる。エラーなく処理が終了するはず。エラーが出てくる場合、Azureのライブラリがエラーを出すので、本来エミュレータから送られてくるエラーメッセージはそのままでは見られない。ここらはFiddlerを使ってキャプチャしておけば、デバッグに役立つ。


 ストレージエミュレータへの書き込みが成功したら、ブラウザからそのファイルを参照してみる。
http://192.168.11.17:20000/devstoreaccount1/test/foo.txt

成功。

 Azureを使ったWebアプリの開発をしたいが、その開発環境で使うストレージエミュレータがローカルからのアクセスしか受け付けないので、NginXでリバプロを立てて外部(Dockerのコンテナ内を想定)からのアクセスを受け付けるようにしてみた。うまくいった。
 しかしこれ、けっこうメンドウだったのでエミュレータがコンテナで用意できたらなーと思っている。
comment: 0