しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

Azure Functions Linux の Custom Image でベースとして利用可能な Docker Image について

Azure Functions の Linux では標準で用意されている Docker Image をベースにして、独自に必要なパッケージをインストールして実行環境をカスタマイズ出来るようになっています。

ドキュメントでは Custom Image と呼ばれていますが、Azure Portal から Azure Functions を作成する時に Docker Container を選ぶと自動的にこれになります。

ちなみに Custom Image が使えるのは App Service Plan と Functions Premium を選んだ時のみです。作成時に Consumption を選ぶとコードのみデプロイして、標準の Docker Image 上で動く形になります。

少し前に書いた VS Code の Dev Container を使った開発と親和性が高いので、Custom Image を組み合わせるとビルドとデプロイ周りを簡略化出来ます。

Azure Functions Core Tools を使って Dockerfile を生成すると、大体の言語では同じような内容で出来上がるので、今回は Python 3.8 を題材に説明をしていきます。

生成された Dockerfile は以下のような内容になっています。

# To enable ssh & remote debugging on app service change the base image to the one below
# FROM mcr.microsoft.com/azure-functions/python:3.0-python3.8-appservice
FROM mcr.microsoft.com/azure-functions/python:3.0-python3.8

ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
    AzureFunctionsJobHost__Logging__Console__IsEnabled=true

COPY requirements.txt /
RUN pip install -r /requirements.txt

COPY . /home/site/wwwroot

先頭のコメントにあるように、App Service 上で SSH を使ってコンテナーへ接続する場合には、ベースとなる Docker Image を変更する必要があります。

このベースとなる Docker Image のタグにはいくつか種類があるので、以下で簡単にまとめました。

  • 3.0-python3.8-slim
    • 必要最低限のパッケージのみ
  • 3.0-python3.8
    • Chrome headless 依存関係入り
  • 3.0-python3.8-appservice
    • Chrome headless 依存関係と SSH サポート入り
  • 3.0-python3.8-appservice-stage*
    • Function デプロイ時に Code を選んだ場合に使われるイメージ
    • カスタムコンテナー向けには利用しない

どれを使っていいのかわからない場合は、デフォルトの 3.0-python3.8 を使っておけばよいです。ただしこのイメージには Chrome headless の実行に必要な依存関係が入っているので 3.0-python3.8-slim よりサイズが大きくなっています。このサフィックスのルールは他の言語でも同じです。*1

デバッグなどで実行中コンテナーに SSH でログインしたい場合には 3.0-python3.8-appservice を一時的に使うようにすればよいでしょう。運用フェーズに入ると SSH ログインは必要ないと思うので、忘れないように戻しておきたいところです。

最近は Docker Desktop の UI が分かりやすいので、それぞれのイメージサイズの違いを軽く載せておきます。

f:id:shiba-yan:20210702224220p:plain

今回の Python 3.8 に限っては slim とそれ以外で 400MB 近くの差がありました。初回の docker pull にかかる時間に直接影響してくる部分なので、特に Functions Premium を使う場合には意識しておきたいです。

ぶっちゃけ slim を使ってもまあまあ大きいという印象ですが、Azure Functions Runtime 自体が Self contianed かつ R2R ビルドされているのもあり 300MB 近いので大幅に減らすのは難しそうです。共通部分はキャッシュされると開発体験は向上するはずなので今後に期待。

これらの Docker Image の元となる Dockerfile は以下のリポジトリで管理されています。

今は若干非効率な部分もあるように見えますが、いろいろと今後も改善予定はあるようなので期待しつつ、改善ポイントがあれば Issue や PR で貢献したいと思っています。

これらのベースとなる Docker Image は今は 3.0 で基本統一されていますが、Azure Functions Runtime のバージョニング変更に伴って今後は 3.13.2 のようにマイナー部分が増えます。

既に 3.1.0 はリリースされていますが、次のバージョンが 3.2.0 もしくは 3.1.1 になるのかが若干怪しいので、Docker Image のタグ指定には少し気を付ける必要がありそうです。

常にマイナー部分が増えていく形になると、使用する Azure Functions Runtime のバージョンを明示的に Dockerfile で書く必要があるので若干面倒になりそうです。

Windows や Consumption の場合は FUNCTIONS_EXTENSION_VERSION~3 にすることで、これまで通り常に最新の Azure Functions Runtime v3.x を利用できます。

*1:ただし .NET Core 3.1 向けの 3.0 と 3.0-slim のように同じイメージを指しているタグもある