Deploy Docker To Azure

Deploy Docker To Azure

Reading time1 min
#Cloud#DevOps#Containers#Azure#Docker#ACI

Deploying Docker Containers to Azure Without Orchestration Overhead

Critically, not all workloads belong on an orchestrator. For many small services, event-driven processes, and dev/prototype environments, Kubernetes introduces needless complexity. Azure Container Instances (ACI) provides a low-friction alternative: single- or multi-container deployments via a true serverless experience, billed down to the second.


Why Use ACI Instead of Kubernetes or Virtual Machines?

Kubernetes: designed for robust, scalable, distributed systems. But for stateless APIs, ad-hoc data processors, or ephemeral tools? Overkill.

Virtual Machines: fully customizable, but you manage OS lifecycle, patching, and VM sprawl. Not great for short-lived or variable workloads.

ACI bridges the gap: Immediate container lift, minimal ops burden.

Core features:

  • On-demand container execution. No VM or orchestrator prep.
  • Granular billing—CPU, memory, and seconds.
  • Simple exposure: built-in DNS, easily accessed via public FQDN.
  • Integration: Azure CLI, ARM/Bicep, or Portal. Azure DevOps and GitHub Actions support native ACI steps.

Direct Example—Minimal HTTP Container Deployment

There’s no need for theory if the process takes 2 minutes. Assume the following:

  • Azure CLI 2.53.1 or newer (az --version)
  • Docker image: mcr.microsoft.com/azuredocs/aci-helloworld (public, <30MB pull, HTTP GET returns a greeting)
  • Azure account (resource group location: eastus)

A deployment sequence:

az login

az group create --name aci-rg --location eastus

az container create \
  --resource-group aci-rg \
  --name helloworld-acidemo \
  --image mcr.microsoft.com/azuredocs/aci-helloworld \
  --dns-name-label helloworld-acidemo-$RANDOM \
  --ports 80

Result:
ACI schedules container creation and assigns a DNS name:
helloworld-acidemo-<suffix>.eastus.azurecontainer.io

Query status (ensure ProvisioningState == Succeeded):

az container show \
  --resource-group aci-rg \
  --name helloworld-acidemo \
  --query '{FQDN:ipAddress.fqdn,State:provisioningState}' \
  --output table

Access via standard browser or curl. Example output should resemble:

Welcome to Azure Container Instances!

Side note: DNS labels under each Azure region must be globally unique. A collision yields Code: Conflict or similar.


Deploying Custom Images

Prerequisite: Image must be accessible—either via Docker Hub or a private Azure Container Registry (ACR).

Example using Docker Hub:

docker build -t mydockerhubuser/mywebapp:1.3.0 .
docker push mydockerhubuser/mywebapp:1.3.0

az container create \
  --resource-group aci-rg \
  --name mywebapp-prod \
  --image mydockerhubuser/mywebapp:1.3.0 \
  --dns-name-label mywebapp-prod-$RANDOM \
  --ports 8080 \
  --environment-variables ENV=production LOG_LEVEL=warn

Note: For ACR-hosted images, set --registry-login-server, --registry-username, --registry-password.


Practical Tips and Common Pitfalls

Persistent storage:
By default, containers are stateless. For write persistence:

az container create \
  ... \
  --azure-file-volume-share-name myshare \
  --azure-file-volume-account-name <storage_account> \
  --azure-file-volume-account-key <key> \
  --azure-file-volume-mount-path /mnt/data

Logs and Debug:
Retrieve real-time output:

az container logs --resource-group aci-rg --name mywebapp-prod

For interactive troubleshooting:

az container exec --resource-group aci-rg --name mywebapp-prod --exec-command "/bin/sh"

Resource Limits:
CPU and memory are capped per container group (as of June 2024: up to 16GB RAM, 4vCPU). For anything beyond, consider AKS or batch solutions.

Networking:
Single group isolation. VNet integration is possible, but adds complexity; public IP + port exposure suffices for dev/test.

Scaling:
No horizontal scaling within ACI itself. For scale-out and load balancing, incorporate ACI into Azure Container Apps or behind Application Gateway—but then you’re approaching orchestrator territory.


Known Issues and Trade-Offs

  • ACI container startup sometimes spikes 5–15 seconds, especially for large images or first pull after region cold start.
  • No internal service discovery. One container group = one instance endpoint.
  • Quota errors can surface (Code: ResourceQuotaExceeded) if container limits per region (default 100 groups/region) are reached.
  • Inbound traffic only on explicitly opened ports. Unexposed ports are blocked (good for isolation, but can confuse if a web service runs on 8080 and you forget --ports 8080).

Conclusion

For projects requiring minimal bootstrapping, per-second billing, and cloud-based container hosting—without orchestrator or VM headaches—ACI often outpaces AKS or VMSS (Virtual Machine Scale Sets). Its simplicity comes with limits, but for event-driven jobs, short-lived workers, or nimble public endpoints, the trade-off is advantageous.


Not Perfect: Some custom networking and scaling scenarios will require AKS, Container Apps, or external automation.

Non-obvious tip: You can use ACI as a build runner for ephemeral CI jobs—GitHub Actions and Azure DevOps both allow task-level ACI containers, reducing both cost and queue time for self-hosted runners.


Skip the bloat where you can. For fast deployments and controlled costs, ACI earns its place in the Azure container toolbox.