Azure Functions でコンテナをデプロイしようとしてめちゃくちゃにハマったので供養。
発生した課題
Azure Functions で Linux コンテナを動かそうと思って、例えば Azure Functions Core Tools で Azure Functions プロジェクトを作成すると、以下のような Dockerfile が生成される。
$ func init --worker-runtime python --docker
FROM mcr.microsoft.com/azure-functions/python:4-python3.7
ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
AzureFunctionsJobHost__Logging__Console__IsEnabled=true
COPY requirements.txt /
RUN pip install -r /requirements.txt
COPY . /home/site/wwwroot
なるほど、環境変数 AzureWebJobsScriptRoot
で指定したディレクトリにアプリ関連ファイルを置けば良いのだな。
じゃあ今回は適当に /app/functions
へ置くことにする。
ENV AzureWebJobsScriptRoot=/app/functions
適当に関数を追加して、
@app.function_name(name="example")
@app.route(route="example", auth_level=func.AuthLevel.ANONYMOUS)
def test_function(req: func.HttpRequest) -> func.HttpResponse:
return func.HttpResponse("FOOOO!!!", status_code=200)
ローカル環境での動作確認 OK だったので、いざ Azure にデプロイするぞ!!
→ 全然動かない...。
プロセスは動いているっぽいのが、何を試しても No functions were found.
みたいなメッセージだけ出るだけ。エラーメッセージを出してほしいマジ。
原因
半日を溶かしてようやく見つけたのがこちら。
protected static string ResolveFunctionBaseProbingPath()
{
string basePath = null;
if (ScriptSettingsManager.Instance.IsAppServiceEnvironment)
{
string home = Environment.GetEnvironmentVariable(EnvironmentSettingNames.AzureWebsiteHomePath);
basePath = Path.Combine(home, "site", "wwwroot");
}
else
{
basePath = Environment.GetEnvironmentVariable(EnvironmentSettingNames.AzureWebJobsScriptRoot) ?? AppContext.BaseDirectory;
}
return Path.Combine(basePath, "bin");
}
IsAppServiceEnvironment
が真のとき、AzureWebJobsScriptRoot
を一切見てなくない???
今回デプロイしたのは Premium プランだけど、どう見ても App Service と同じ仕組みで動いているので IsAppServiceEnvironment
に該当してそう。
Issue もあった。
4年前から変わっていないっぽい...。
まとめ
コンテナを Azure Functions にデプロイするときは 環境変数 AzureWebJobsScriptRoot
によるパス変更は無意味。
おとなしく /home/site/wwwroot
に置こう...。