Что где работает
| Сервис Azure | Локальный аналог | Локальный рабочий процесс |
|---|---|---|
| Container Apps | Docker Compose с образами приложения | Запускайте сервисы вместе с проверками состояния и опубликованными портами |
| Blob Storage | Azurite | Используйте локальный Blob Storage на порту 10000 |
| Azure Functions (контейнер) | Базовый образ Functions | Запускайте образ Functions для amd64 через Rosetta |
| AKS | kubectl и k9s для AKS; kwok для локального API | Собирайте и тестируйте локально, затем используйте kubectl и k9s с вашим кластером |
Container Apps: проверяйте контейнеры, а не симулятор
Container App запускает один или несколько контейнеров с переменными окружения, секретами, входным портом, пробами и правилами масштабирования. Именно контейнеры могут ломаться, а при использовании того же образа они ведут себя на Mac так же, как в Azure. Правила масштабирования, ревизии и управляемая идентификация остаются в Azure; всё внутри контейнера можно проверить локально.
Запустите контейнеры Azure Container App локально через Compose и Azurite
- Опишите приложение в Compose. Создайте сервис Compose для каждого контейнера Container App (основного и всех sidecar-контейнеров) с теми же образами, переменными окружения, входным портом и проверками состояния.
- Добавьте Azurite для хранилища. Добавьте сервис из
mcr.microsoft.com/azure-storage/azurite, опубликуйте порты 10000 (Blob), 10001 (Queue) и 10002 (Table) и направьте на него строку подключения к хранилищу приложения. - Явно задайте amd64, где нужно. Укажите
platform: linux/amd64для сервисов без образа arm64, например базовых образов Azure Functions. Они работают через Rosetta. - Запустите и подождите. Выполните
docker compose up -d --wait. Команда завершается после готовности всех сервисов с проверками состояния. - Проверьте, затем отправьте. Обратитесь к приложению на
localhost. Когда всё работает, войдите черезaz acr login --name REGISTRY, назначьте тег образу и отправьте его черезdocker pushдля Container Apps или 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 указан в документации Microsoft по Azurite; скопируйте его оттуда. В сети Compose приложение обращается к Azurite по имени сервиса (azurite:10000), а с Mac — по localhost:10000.
Azurite в Oxcart
Azurite — эмулятор Azure Storage с открытым кодом от Microsoft, с Blob, Queue и Table (Table в предварительной версии) на портах от 10000 до 10002. Мы запустили сервис 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, поэтому обычная сборка на Mac с Apple silicon выдаёт «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 В нашем запуске функция с HTTP-триггером ответила на x86_64 примерно через 13 секунд после docker run; лог хоста Functions показал настроенный маршрут и успешный вызов. Передавайте --platform linux/amd64 и команде docker run: локально собранный образ только для amd64 находится лишь при указании платформы. Затем Azure Functions Core Tools может развернуть тот же образ через func azurecontainerapps deploy или func kubernetes deploy.
Отправьте в 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 Собирайте для архитектуры среды Container Apps или пула узлов AKS. Отправка мультиплатформенного образа из Oxcart не поддерживается, поэтому отправляйте тег для каждой архитектуры или публикуйте мультиархитектурные манифесты через CI.
AKS с вашего Mac
az aks get-credentials --resource-group RG --name CLUSTER добавляет AKS в kubeconfig для работы с kubectl и k9s из macOS. Разрабатывайте сервисы локально в Oxcart и развёртывайте те же образы в AKS. Для локальной проверки API и контроллеров kwok работает в Oxcart с настоящей плоскостью управления и имитацией узлов. Эти процессы описаны в руководстве по Kubernetes на Mac.
Зачем запускать в Oxcart
Локальное тестирование окупается, только если цикл короткий. Oxcart показал 42 ms для docker run --rm и 77 ms для остановки и удаления 20 контейнеров — лучший результат из трёх протестированных сред. Исходящие соединения контейнеров открывает Mac, поэтому VPN или маршрут к частной конечной точке сети Azure действуют и для них. См. сети контейнеров на Mac.
Вопросы
Есть ли локальный эмулятор Azure Container Apps?
По состоянию на октябрь 2026 года мы не нашли официального локального эмулятора Container Apps в документации Microsoft; она указывает az containerapp up для развёртывания из локального кода и Aspire для локальной оркестрации. Container App — набор контейнеров, поэтому практичный локальный аналог — те же контейнеры в проекте Compose с Azurite для хранилища.
Работает ли Azurite на Mac с Apple silicon?
Да. В 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.
Можно ли запускать Azure Functions в контейнере на Mac?
Да, с --platform linux/amd64. Проверенный базовый образ Python Azure Functions (mcr.microsoft.com/azure-functions/python:4-python3.12) не имеет сборки arm64, поэтому обычная сборка выдаёт «no match for platform in manifest». Собранный и запущенный как linux/amd64 в Oxcart, он работал через Rosetta, а функция с HTTP-триггером ответила на localhost.
Как отправить образ в Azure Container Registry с Mac?
Выполните az acr login --name REGISTRY, затем docker tag и docker push REGISTRY.azurecr.io/app:TAG. В Oxcart учётные данные, сохраняемые через docker login, попадают в Связку ключей macOS.
Как разрабатывать для AKS на Mac?
Собирайте и тестируйте приложение с зависимостями локально в Oxcart. Подключите kubectl и k9s к AKS через az aks get-credentials, а kwok в Oxcart используйте для проверки манифестов на локальном Kubernetes API с имитацией узлов. См. Kubernetes на Mac.
А эмулятор Cosmos DB?
Microsoft публикует образ эмулятора Cosmos DB на Linux (vNext, API for NoSQL). Мы не проверяли его в Oxcart, поэтому попробуйте на своём проекте в бесплатный пробный период, прежде чем полагаться на него.
Источники и методика
- Примеры проверены с Oxcart 0.1.2, Mac17,14, macOS 27.2, 2026-10-10 (Blob Azurite 3.37.0, образ Azure Functions Python 4 как 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 (локальный эмулятор не найден): 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, медианы пяти замеров; остальные среды измерены ранее в тот же день на том же Mac и тем же набором тестов с клиентом docker 29.4.