Azure FunctionsのDocker版をローカルで起動する

Azure Functions で「なでしこ」が動くとか「COBOL」が動くとかという記事があったハズなのだが、これ難しいのでは?とは思っていたが、実は内部で Docker が動いているだけだった、という話。

Azure でサーバーレスなFunction Appを作るときに、現状ではWindows環境にすると「dotnet」と「node」、「java」が選べるようになっている。それぞれ VM 環境を Azure 側で用意してそれの上で動かすのだから、このあたりの環境は Azure = Microsoft 社が用意するんだろうなぁというのが想像できる。

image

もうひとつ、Linux 環境というのがあって、こっちは .NET と JavaScript と python が選べる。Windows のほうに python のがないのは何故?とか PHP は何処で動かすのか?と不思議に思っていたのだが、実は PHP のようなほかの言語は、Linux 環境での「Docker イメージ」のほうに作ることになる。

image

Function App は内部的には App Service と同じなので、つまりは VM 上で動いている。App Service のほうは、HTTP プロトコルの受け口から作るけど、Function App の場合は MVC でいうところの Controller のメソッドが直接呼び出される形になっている、と思えばいい。

となると、この「Docker イメージ」というやつは、

  • 内部で、HTTP サーバーが起動している
  • クライアントHTTP リクエストをすると、内部の MVC の Controller らしきものが起動される。
  • Function Appの「関数」として、static なコードが呼び出される。

というスタイルになればいい。実は「内部の MVC の Controller らしきもの」のように分離されてなくても、単純に HTTP リクエストで呼び出されたときにレスポンスを返す、という通常の HTTP サーバーがあればいいのだ。

Ubuntu で func init してみる

Ubuntu 上で、Function Appを作るために「func init」することができる。このときに docker スイッチを付けると、Dockerfile を作ってくれる。

func init –docker

作成された Dockerfile を見てみると、


FROM microsoft/dotnet:2.1-sdk AS installer-env

COPY . /src/dotnet-function-app
RUN cd /src/dotnet-function-app && \
mkdir -p /home/site/wwwroot && \
dotnet publish *.csproj --output /home/site/wwwroot

FROM mcr.microsoft.com/azure-functions/dotnet:2.0
ENV AzureWebJobsScriptRoot=/home/site/wwwroot

COPY --from=installer-env ["/home/site/wwwroot", "/home/site/wwwroot"]

となっている。これは .NET 環境(C#)なのだが、なるほど、dotnet コマンドでビルドして publish しているだけだ。*.csproj なプロジェクトは所謂 ASP.NET MVC プロジェクトみたいなものなので、ここで適当な関数が呼びだされていることになる。

試しに func start host してみる

func start host してみよう。

image

のように、普通に azure function のエミュレータが起動する。つまり、Docker の中身は azure function と同じなわけだ。まあ、同じだからいいんだけど。

docker build して docker run する

Dockerfile があるのだから、ローカルな Linux 環境でも実行ができるはずだ。Ubuntu に docker を入れた状態で、

sudo docker build -t moonmile/azure-docker:ver0.2 .

のようにビルドをすると、ビルドができる。Nuget で関連するアセンブリも持ってくる。

image

次のように docker で実行する。

sudo docker run -it -p 8000:80  moonmile/azure-docker:ver0.2

image

すると、http://localhost:8000/api/HttpTrigger1?name=masuda でアクセスできるようになる。

注意しないといけないのは、関数が呼び出されるときに AuthorizationLevel.Function のままだと、ユーザー名/パスワードを要求されるので(Basic認証なのか?)、AuthorizationLevel.Anonymous に設定して、匿名でもアクセスできるようにする。

自前の Dockerfile が作れる?

そんな訳で、.NET 環境の場合は、AzureWebJobsScriptRoot=/home/site/wwwroot なところでルートが指定されているから、このあたりで外側から指定の関数を呼び出されているんだろうなあ、ということが想像できる。

となると、PHP とか他のプログラム言語で構築する場合も、HTTP リクエスト受け付けるように Dockerfile を作ってやれば、Azure Functionsの中身を「自分で使いやすい言語」に切り替えられるだろう、ってことが分かる。Linux 環境に限られるのだが。

カテゴリー: 開発, Azure パーマリンク