What runs where
| Azure service | Local stand-in | Your local workflow |
|---|---|---|
| Container Apps | Docker Compose with the app’s images | Run your services together with healthchecks and published ports |
| Blob Storage | Azurite | Use local Blob Storage on port 10000 |
| Azure Functions (container) | Functions base image | Run the amd64 Functions image through Rosetta |
| AKS | kubectl and k9s against AKS; kwok for a local API | Build and test locally, then use kubectl and k9s with your cluster |
Container Apps: test the containers, not a simulator
A Container App runs one or more containers with environment variables, secrets, an ingress port, probes and scale rules. The containers are the part that breaks, and they behave the same on your Mac as in Azure when you run the same image. Scale rules, revisions and managed identity stay in Azure; everything inside the container you can test locally.
Run an Azure Container App’s containers locally with Compose and Azurite
- Describe the app in Compose. Write one Compose service per container in your Container App (the main container and any sidecars), with the same images, environment variables, ingress port and health probes.
- Add Azurite for storage. Add a service from
mcr.microsoft.com/azure-storage/azuritepublishing ports 10000 (Blob), 10001 (Queue) and 10002 (Table), and point the app’s storage connection string at it. - Pin amd64 where needed. Set
platform: linux/amd64on any service whose image has no arm64 build, such as the Azure Functions base images. It runs through Rosetta. - Start and wait. Run
docker compose up -d --wait. It returns when every service with a healthcheck is healthy. - Test, then push. Call the app on
localhost. When it works, log in withaz acr login --name REGISTRY, tag the image anddocker pushit for Container Apps or AKS.
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’s well-known development account key is in Microsoft’s Azurite documentation; copy it from there. Inside the Compose network the app reaches Azurite by service name (azurite:10000), and from your Mac it is on localhost:10000.
Azurite on Oxcart
Azurite is Microsoft’s open-source Azure Storage emulator, with Blob, Queue and Table (Table in preview) on ports 10000 to 10002. We started the Blob service and called it from the 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) The 403 is the right answer to a request without a signature: the endpoint is up and reachable. Your SDK, with the development connection string, signs its requests.
Azure Functions in a container
The Azure Functions base images we tested publish only an amd64 build, so a plain build on an Apple silicon Mac fails with “no match for platform in manifest”. Build and run them as linux/amd64; Oxcart runs them through 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 In our run an HTTP-triggered function answered from x86_64 about 13 seconds after docker run, with the Functions host log showing the route mapped and the call succeeding. Pass --platform linux/amd64 on docker run too: a locally built amd64-only image is found only when the platform is given. Azure Functions Core Tools can then deploy the same image with func azurecontainerapps deploy or func kubernetes deploy.
Push to Azure Container Registry
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 Build for the architecture your Container Apps environment or AKS node pool runs. Pushing a multi-platform image from Oxcart is not supported, so push one tag per architecture or publish multi-arch manifests from CI.
AKS from your Mac
az aks get-credentials --resource-group RG --name CLUSTER adds AKS to your kubeconfig so you can use kubectl and k9s from macOS. Develop your services locally with Oxcart and deploy the same images to AKS. For local API and controller testing, kwok runs on Oxcart with a real control plane and simulated nodes. See the Kubernetes on a Mac guide for these workflows.
Why run it on Oxcart
Local testing only pays off if the loop is short. Oxcart measured 42 ms for docker run --rm and 77 ms to stop and remove 20 containers, the fastest of the three runtimes we tested. Outbound connections from containers are opened by your Mac, so a VPN or private endpoint route into your Azure network applies to them as well. See container networking on a Mac.
Questions
Is there a local emulator for Azure Container Apps?
We found no official local Container Apps emulator in Microsoft’s documentation as of October 2026; Microsoft points to az containerapp up for deploying from local source and to Aspire for local orchestration. A Container App is a set of containers, so the practical local stand-in is the same containers in a Compose project, with Azurite for storage.
Does Azurite run on an Apple silicon Mac?
Yes. On Oxcart, docker run -d -p 10000:10000 mcr.microsoft.com/azure-storage/azurite azurite-blob --blobHost 0.0.0.0 started Azurite 3.37.0, and its Blob endpoint answered on localhost:10000.
Can I run Azure Functions in a container on a Mac?
Yes, with --platform linux/amd64. The Azure Functions Python base image we tested (mcr.microsoft.com/azure-functions/python:4-python3.12) has no arm64 build, so a plain build fails with “no match for platform in manifest”. Built and run as linux/amd64 on Oxcart, it ran through Rosetta and an HTTP-triggered function answered on localhost.
How do I push to Azure Container Registry from a Mac?
Run az acr login --name REGISTRY, then docker tag and docker push REGISTRY.azurecr.io/app:TAG. On Oxcart, credentials stored through docker login go to the macOS Keychain.
How do I develop for AKS on my Mac?
Build and test your app and its dependencies locally with Oxcart. Connect kubectl and k9s to AKS with az aks get-credentials, and use kwok on Oxcart to check manifests against a local Kubernetes API with simulated nodes. See Kubernetes on a Mac.
What about the Cosmos DB emulator?
Microsoft publishes a Linux-based Cosmos DB emulator image (vNext, API for NoSQL). We have not tested it on Oxcart, so try it on your project during the free trial before relying on it.
Sources and method
- Examples tested with Oxcart 0.1.2, Mac17,14, macOS 27.2, 2026-10-10 (Azurite 3.37.0 Blob, Azure Functions Python 4 image as linux/amd64, 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 (no local emulator found): https://learn.microsoft.com/en-us/azure/container-apps/quickstart-code-to-cloud. Cosmos DB Linux emulator: https://learn.microsoft.com/en-us/azure/cosmos-db/emulator-linux. Checked 2026-10-10.
- Container speed: Oxcart 0.1.2, 2026-10-10, Apple M5 Max, 8 CPUs and 12 GiB, medians of five samples; the other runtimes were measured earlier the same day on the same Mac and harness with the docker 29.4 client.