ACI integration Compose features
Docker Compose’s integration for ECS and ACI is retiring in November 2023.
Compose - Azure Container Instances mapping
This document outlines the conversion of an application defined in a Compose file to ACI objects. At a high-level, each Compose deployment is mapped to a single ACI container group. Each service is mapped to a container in the container group. The Docker ACI integration does not allow scaling of services.
Compose fields mapping
The table below lists supported Compose file fields and their ACI counterparts.
- ✓: Implemented
- n: Not yet implemented
- x: Not applicable / no available conversion
|service.service.build||x||Ignored. No image build support on ACI.|
|service.command||✓||Override container Command. On ACI, specifying
|service.container_name||x||Service name is used as container name on ACI.|
|service.deploy.replicas||x||Only one replica is started for each service.|
|service.deploy.resources||✓||Restriction: ACI resource limits cannot be greater than the sum of resource reservations for all containers in the container group. Using container limits that are greater than container reservations will cause containers in the same container group to compete with resources.|
|service.deploy.labels||x||ACI does not have container-level labels.|
|service.domainname||✓||Mapped to ACI DNSLabelName. Restriction: all services must specify the same
|service.entrypoint||x||ACI only supports overriding the container command.|
|service.image||✓||Private images will be accessible if the user is logged into the corresponding registry at deploy time. Users will be automatically logged in to Azure Container Registry using their Azure login if possible.|
|service.labels||x||ACI does not have container-level labels.|
|service.networks||x||Communication between services is implemented by defining mapping for each service in the shared
|service.ports||✓||Only symmetrical port mapping is supported in ACI. See Exposing ports.|
|service.volumes||✓||Mapped to AZure File Shares. See Persistent volumes.|
|service.restart||x||Replaced by service.deployment.restart_policy|
|driver||✓||See Persistent volumes.|
Container logs can be obtained for each container with
docker logs <CONTAINER>.
The Docker ACI integration does not currently support aggregated logs for containers in a Compose application, see https://github.com/docker/compose-cli/issues/803.
When one or more services expose ports, the entire ACI container group will be exposed and will get a public IP allocated. As all services are mapped to containers in the same container group, only one service cannot expose a given port number. ACI does not support port mapping, so the source and target ports defined in the Compose file must be the same.
When exposing ports, a service can also specify the service
domainname field to set a DNS hostname.
domainname will be used to specify the ACI DNS Label Name, and the ACI container group will be reachable at
Docker volumes are mapped to Azure file shares. Only the long Compose volume format is supported meaning that volumes must be defined in the
Volumes are defined with a name, the
driver field must be set to
driver_options must define the storage account and file share to use for the volume.
A service can then reference the volume by its name, and specify the target path to be mounted in the container.
services: myservice: image: nginx volumes: - mydata:/mount/testvolumes volumes: mydata: driver: azure_file driver_opts: share_name: myfileshare storage_account_name: mystorageaccount
The short volume syntax is not allowed for ACI volumes, as it was designed for local path bind mounting when running local containers. A Compose file can define several volumes, with different Azure file shares or storage accounts.
Credentials for storage accounts will be automatically fetched at deployment time using the Azure login to retrieve the storage account key for each storage account used.
Secrets can be defined in compose files, and will need secret files available at deploy time next to the compose file.
The content of the secret file will be made available inside selected containers, by default under
External secrets are not supported with the ACI integration.
services: nginx: image: nginx secrets: - mysecret1 db: image: mysql secrets: - mysecret2 secrets: mysecret1: file: ./my_secret1.txt mysecret2: file: ./my_secret2.txt
The nginx container will have secret1 mounted as
/run/secrets/mysecret1, the db container will have secret2 mounted as
A target can also be specified to set the name of the mounted file or by specifying an absolute path where to mount the secret file
services: nginx: image: nginx secrets: - source: mysecret1 target: renamedsecret1.txt db: image: mysql secrets: - source: mysecret1 target: /mnt/dbmount/mysecretonmount1.txt - source: mysecret2 target: /mnt/dbmount/mysecretonmount2.txt secrets: mysecret1: file: ./my_secret1.txt mysecret2: file: ./my_secret2.txt
In this example the
nginx service will have its secret mounted to
db will have 2 files (
Both of them with be mounted in the same folder (
Note: Relative file paths are not allowed in the target
Note: Secret files cannot be mounted in a folder next to other existing files
CPU and memory reservations and limits can be set in compose. Resource limits must be greater than reservation. In ACI, setting resource limits different from resource reservation will cause containers in the same container group to compete for resources. Resource limits cannot be greater than the total resource reservation for the container group. (Therefore single containers cannot have resource limits different from resource reservations)
services: db: image: mysql deploy: resources: reservations: cpus: '2' memory: 2G limits: cpus: '3' memory: 3G web: image: nginx deploy: resources: reservations: cpus: '1.5' memory: 1.5G
In this example, the db container will be allocated 2 CPUs and 2G of memory. It will be allowed to use up to 3 CPUs and 3G of memory, using some of the resources allocated to the web container. The web container will have its limits set to the same values as reservations, by default.
A health check can be described in the
healthcheck section of each service. This is translated to a
LivenessProbe in ACI. If the health check fails then the container is considered unhealthy and terminated.
In order for the container to be restarted automatically, the service needs to have a restart policy other than
none to be set. Note that the default restart policy if one isn’t set is
services: web: image: nginx deploy: restart_policy: condition: on-failure healthcheck: test: ["CMD", "curl", "-f", "http://localhost:80"] interval: 30s timeout: 10s retries: 3 start_period: 40s
Note: that the
test command can be a
string or an array starting or not by
CMD-SHELL. In the ACI implementation, these prefixes are ignored.