どこで何を動かすか
| Azureサービス | ローカルでの代替 | ローカルのワークフロー |
|---|---|---|
| Container Apps | アプリのイメージをDocker Composeで実行 | ヘルスチェックと公開ポートを使い、サービスをまとめて実行 |
| Blob Storage | Azurite | ポート10000でローカルBlob Storageを利用 |
| Azure Functions(コンテナ) | Functionsベースイメージ | Rosetta経由でamd64 Functionsイメージを実行 |
| AKS | kubectlとk9sでAKSへ接続、ローカルAPIにはkwok | ローカルでビルド・テスト後、kubectlとk9sでクラスターを操作 |
Container Apps:シミュレーターではなくコンテナをテストする
Container Appは、環境変数、シークレット、イングレスのポート、プローブ、スケールルールを設定した1つ以上のコンテナを実行します。問題が起きるのはコンテナの部分であり、同じイメージならMacでもAzureでも同じように動きます。スケールルール、リビジョン、マネージドIDはAzure側に残りますが、コンテナ内部はすべてローカルでテストできます。
ComposeとAzuriteでAzure Container Appのコンテナをローカル実行
- Composeでアプリを定義します。 Container App内の各コンテナ(メインとサイドカー)に対応するComposeサービスを作り、同じイメージ、環境変数、イングレスのポート、正常性プローブを設定します。
- ストレージにAzuriteを追加します。
mcr.microsoft.com/azure-storage/azuriteのサービスを追加して、10000(Blob)、10001(Queue)、10002(Table)を公開し、アプリのストレージ接続文字列をそこに向けます。 - 必要なサービスをamd64に固定します。 Azure Functionsベースイメージなど、arm64ビルドがないイメージを使うサービスには
platform: linux/amd64を設定します。Rosetta経由で実行されます。 - 起動して待ちます。
docker compose up -d --waitを実行します。ヘルスチェックのあるすべてのサービスが正常になると戻ります。 - テストしてからpushします。
localhostでアプリを呼び出します。動作を確認したらaz acr login --name REGISTRYでログインし、イメージにタグを付け、Container AppsやAKS向けにdocker pushします。
services:
web:
image: myregistry.azurecr.io/web:2.1.0
environment:
AZURE_STORAGE_CONNECTION_STRING: >-
DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=REPLACE_WITH_AZURITE_DEV_KEY;BlobEndpoint=http://azurite:10000/devstoreaccount1;
ports: ["8080:8080"]
depends_on: [azurite]
azurite:
image: mcr.microsoft.com/azure-storage/azurite
ports: ["10000:10000", "10001:10001", "10002:10002"] Azuriteの既知の開発用アカウントキーはMicrosoftのAzuriteドキュメントからコピーしてください。Composeネットワーク内ではサービス名(azurite:10000)でアクセスし、Macからはlocalhost:10000を使います。
OxcartでAzuriteを使う
AzuriteはMicrosoftのオープンソースAzure Storageエミュレーターです。ポート10000〜10002でBlob、Queue、Table(Tableはプレビュー)を提供します。Blobサービスを起動し、Macから呼び出しました。
docker run -d -p 10000:10000 mcr.microsoft.com/azure-storage/azurite \
azurite-blob --blobHost 0.0.0.0
curl -i "http://127.0.0.1:10000/devstoreaccount1?comp=list"
# 403 AuthorizationFailure, Server: Azurite-Blob/3.37.0 (expected for an unsigned request) 署名のないリクエストに403が返るのは正常です。エンドポイントが稼働し、アクセスできていることを示します。開発用接続文字列を使うSDKは、リクエストに署名します。
コンテナでAzure Functionsを使う
テストしたAzure Functionsベースイメージはamd64ビルドのみで、AppleシリコンMacでそのままビルドすると「no match for platform in manifest」で失敗します。linux/amd64としてビルド・実行すれば、OxcartがRosetta経由で動かします。
# Dockerfile
FROM mcr.microsoft.com/azure-functions/python:4-python3.12
ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
AzureFunctionsJobHost__Logging__Console__IsEnabled=true \
AzureWebJobsFeatureFlags=EnableWorkerIndexing
COPY . /home/site/wwwroot
docker build --platform linux/amd64 -t my-func .
docker run -d --platform linux/amd64 -p 7071:80 my-func
curl localhost:7071/api/hello 実行時には、docker runから約13秒後にHTTPトリガーの関数がx86_64環境で応答し、Functionsホストのログでルートのマッピングと呼び出しの成功を確認しました。docker runにも--platform linux/amd64を渡してください。ローカルでビルドしたamd64専用イメージは、プラットフォームを指定した場合にだけ見つかります。その後、Azure Functions Core Toolsのfunc azurecontainerapps deployまたはfunc kubernetes deployで同じイメージをデプロイできます。
Azure Container Registryにpushする
az acr login --name myregistry
docker buildx build --platform linux/amd64 --load -t myregistry.azurecr.io/web:2.1.0 .
docker push myregistry.azurecr.io/web:2.1.0 Container Apps環境やAKSノードプールのアーキテクチャ向けにビルドします。Oxcartからのマルチプラットフォームイメージのpushは未対応なので、アーキテクチャごとにタグをpushするか、CIでマルチアーキテクチャマニフェストを公開してください。
MacからAKSを使う
az aks get-credentials --resource-group RG --name CLUSTERでAKSをkubeconfigに追加すると、macOSからkubectlやk9sを使えます。Oxcartでサービスをローカル開発し、同じイメージをAKSにデプロイします。ローカルでAPIやコントローラーをテストする場合は、Oxcart上のkwokが実際のコントロールプレーンとシミュレートしたノードを提供します。これらのワークフローはMacでKubernetesを使うガイドをご覧ください。
Oxcartで動かす理由
ローカルテストは、反復を短くできてこそ役立ちます。Oxcartはdocker run --rmが42 ms、20コンテナの停止・削除が77 msで、テストした3つのランタイムの中で最速でした。コンテナの外向き接続はMacが開くので、AzureネットワークへのVPNやプライベートエンドポイントのルートも適用されます。Macのコンテナネットワークをご覧ください。
よくある質問
Azure Container Appsのローカルエミュレーターはありますか?
2026年10月時点で、Microsoftのドキュメントに公式のローカルContainer Appsエミュレーターは見つかりませんでした。Microsoftは、ローカルソースからのデプロイにはaz containerapp up、ローカルオーケストレーションにはAspireを案内しています。Container Appはコンテナの集合なので、同じコンテナをComposeプロジェクトで動かし、ストレージにAzuriteを使うのが実用的なローカル代替です。
AzuriteはAppleシリコンMacで動きますか?
はい。Oxcartでdocker run -d -p 10000:10000 mcr.microsoft.com/azure-storage/azurite azurite-blob --blobHost 0.0.0.0を実行するとAzurite 3.37.0が起動し、Blobエンドポイントがlocalhost:10000で応答しました。
MacのコンテナでAzure Functionsを動かせますか?
はい。--platform linux/amd64を使います。テストしたAzure Functions Pythonベースイメージ(mcr.microsoft.com/azure-functions/python:4-python3.12)にはarm64ビルドがなく、そのままでは「no match for platform in manifest」でビルドに失敗します。Oxcartでlinux/amd64としてビルド・実行するとRosetta経由で動き、HTTPトリガーの関数がlocalhostで応答しました。
MacからAzure Container Registryにpushするには?
az acr login --name REGISTRY、続いてdocker tagとdocker push REGISTRY.azurecr.io/app:TAGを実行します。Oxcartでは、docker loginで保存する認証情報はmacOSキーチェーンに入ります。
MacでAKS向けに開発するには?
Oxcartでアプリと依存サービスをローカルでビルド・テストします。az aks get-credentialsでkubectlとk9sをAKSに接続し、Oxcart上のkwokを使って、シミュレートしたノードを持つローカルKubernetes APIでマニフェストを確認します。MacでKubernetesを使うをご覧ください。
Cosmos DBエミュレーターはどうですか?
MicrosoftはLinuxベースのCosmos DBエミュレーターイメージ(vNext、API for NoSQL)を公開しています。Oxcartでは未テストなので、依存する前に無料試用期間中にご自身のプロジェクトで試してください。
出典と測定方法
- 例はOxcart 0.1.2、Mac17,14、macOS 27.2で2026-10-10にテストしました(Azurite 3.37.0 Blob、linux/amd64のAzure Functions Python 4イメージ、Compose)。
- Azurite: https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite。Azure Functions Core Tools: https://learn.microsoft.com/en-us/azure/azure-functions/functions-run-local。Container Apps(ローカルエミュレーターは見つからず): https://learn.microsoft.com/en-us/azure/container-apps/quickstart-code-to-cloud。Cosmos DB Linuxエミュレーター: https://learn.microsoft.com/en-us/azure/cosmos-db/emulator-linux。2026-10-10確認。
- コンテナの速度:Oxcart 0.1.2、2026-10-10、Apple M5 Max、8 CPU・12 GiB、5回測定の中央値。他のランタイムは同日のそれ以前に、同じMacと測定ハーネスでdocker 29.4クライアントを使って測定しました。