Docker VM Extension for Microsoft Azure 🐳
Go Shell Makefile
Latest commit 1b970c8 Jan 23, 2017 @boumenot boumenot committed on GitHub Merge pull request #120 from boumenot/pr-integration-tests
integration-tests: auto-generate certificates
Failed to load latest commit information.
Godeps Override docker-compose timeout for big images Oct 15, 2015
doc Deployment pipeline integration Aug 23, 2016
integration-test Generate Docker certificates at test time Jan 23, 2017
metadata Update change log, bump version 1.2.2. Jan 21, 2017
pkg Add support for CoreOS's rename Jan 19, 2017
scripts Use exec to redirect headless logs in enable op Feb 29, 2016
testdata Add testdata and metadata Jun 4, 2015
vendor/ Override docker-compose timeout for big images Oct 15, 2015
.gitignore Generate Docker certificates at test time Jan 23, 2017
Dockerfile Import new extension code Jun 4, 2015
LICENSE Fix LICENSE copyright statement Jul 27, 2016
Makefile Add manifest.xml to extension bundle Oct 20, 2016 Update change log, bump version 1.2.2. Jan 21, 2017
handlersettings.go Merge branch 'master' into mooncake Oct 13, 2016
main.go pkg/vmextension: refactor for reusability Jul 22, 2016
op-disable.go Use godep with GO15VENDOREXPERIMENT, vendor yaml.v2 Sep 15, 2015
op-enable.go Update InstallDocker Oct 27, 2016
op-enable_test.go Use godep with GO15VENDOREXPERIMENT, vendor yaml.v2 Sep 15, 2015
op-install.go Move install step to enable step Sep 18, 2015
op-uninstall.go Move install step to enable step Sep 18, 2015
op-update.go Use godep with GO15VENDOREXPERIMENT, vendor yaml.v2 Sep 15, 2015
op.go Use godep with GO15VENDOREXPERIMENT, vendor yaml.v2 Sep 15, 2015

Azure Virtual Machine Extension for Docker

This repository contains source code for the Microsoft Azure Docker Virtual Machine Extension.

The source code is meant to be used by Microsoft Azure employees publishing the extension and the source code is open sourced under Apache 2.0 License for reference. You can read the User Guide below.

Docker VM extension can:

  • Install latest stable version of Docker Engine on your Linux VM
  • If provided, configures Docker daemon to listen on specified port, with given certs
  • Launches a set of containers using docker-compose (intended for running a static set of containers for monitoring, security etc.)

User Guide

1. Configuration schema

1.1. Public configuration keys

Schema for the public configuration file for the Docker Extension looks like this:

  • docker: (optional, JSON object)
    • port: (optional, string) the port Docker listens on
    • options: (optional, string array) command line options passed to the Docker engine
  • compose: (optional, JSON object) the docker-compose.yml file to be used, converted to JSON. If you are considering to embed secrets as environment variables in this section, please see the "environment" key described below. This feature is not intended for managing a dynamic set of containers, it is intended for starting a static set of bootstrap containers for monitoring, security or orchestrator agents. Please do not manage your containers through this feature.
  • compose-environment (optional, JSON object) Environment variables for docker-compose.
  • azure-environment (optional, string) Azure environment. Valid values are "AzureCloud" and "AzureChinaCloud". The default is "AzureCloud".

A minimal simple configuration would be an empty json object ({}) or a more advanced one like this:

        "port": "2376",
        "options": ["-D", "--dns="]
    "compose": {
        "cache" : {
            "image" : "memcached",
            "ports" : ["11211:11211"]
        "web": {
            "image": "ghost",
            "ports": ["80:2368"]
    "compose-environment": {
        "COMPOSE_PROJECT_NAME": "blog",
        "COMPOSE_HTTP_TIMEOUT": "600"

NOTE: It is not suggested to specify "port" unless you are going to specify "certs" configuration (described below) as well. This can open up the Docker engine to public internet without authentication.

1.2. Protected configuration keys

Schema for the protected configuration file stores the secrets that are passed to the Docker engine looks like this:

  • environment: (optional, JSON object) Key value pairs to store environment variables to be passed to docker-compose securely. By using this, you can avoid embedding secrets in the unencrypted "compose" section.
  • certs: (optional, JSON object)
    • ca: (required, string): base64 encoded CA certificate, passed to the engine as --tlscacert
    • cert: (required, string): base64 encoded TLS certificate, passed to the engine as --tlscert
    • key: (required, string): base64 encoded TLS key, passed to the engine as --tlskey
  • login: (optional, JSON object) login credentials to log in to a Docker Registry
    • server: (string, optional) registry server, if not specified, logs in to Docker Hub
    • username: (string, required)
    • password: (string, required)
    • email: (string, required)

In order to encode your existing Docker certificates to base64, you can run:

$ cat ~/.docker/ca.pem | base64

An advanced configuration that configures TLS for Docker engine and logs in to Docker Hub account would look like this:

    "environment" : {
        "SECRET_ENV": "<<secret-value>>",
        "MYSQL_ROOT_PASSWORD": "very-secret-password"
    "certs": {
        "ca": "<<base64 encoded ~/docker/ca.pem>>",
        "cert": "<<base64 encoded ~/docker/cert.pem>>",
        "key": "<<base64 encoded ~/docker/key.pem>>"
    "login": {
        "username": "myusername",
        "password": "mypassword",
        "email": ""

2. Deploying the Extension to a VM

Using Azure CLI: Once you have a VM created on Azure and configured your pub.json and prot.json (in section 1.1 and 1.2 above), you can add the Docker Extension to the virtual machine by running:

$ azure vm extension set 'yourVMname' DockerExtension Microsoft.Azure.Extensions '1.1' \
--public-config-path pub.json  \
--private-config-path prot.json

In the command above, you can change version with '*' to use latest version available, or '1.*' to get newest version that does not introduce non- breaking schema changes. To learn the latest version available, run:

$ azure vm extension list

You can also omit --public-config-path and/or --private-config-path if you do not want to configure those settings.

3. Using Docker Extension in ARM templates

You can provision Docker Extension in Azure Resource templates by specifying it just like a resource in your template. The configuration keys go to "settings" section and (optionally) protected keys go to "protectedSettings" section.

Example resource definition:

  "type": "Microsoft.Compute/virtualMachines/extensions",
  "name": "[concat(variables('vmName'), '/DockerExtension'))]",
  "apiVersion": "2015-05-01-preview",
  "location": "[parameters('location')]",
  "dependsOn": [
    "[concat('Microsoft.Compute/virtualMachines/', variables('vmName'))]"
  "properties": {
    "publisher": "Microsoft.Azure.Extensions",
    "type": "DockerExtension",
    "typeHandlerVersion": "1.1",
    "autoUpgradeMinorVersion": true,
    "settings": {},
    "protectedSettings": {}

You can find various usages of this at the following gallery templates:

Supported Linux Distributions

  • CoreOS 899 and higher
  • Ubuntu 13 and higher
  • CentOS 7.1 and higher
  • Red Hat Enterprise Linux (RHEL) 7.1 and higher

Other Linux distributions are currently not supported and extension is expected to fail on unsupported distributions.


After adding the extension, it can usually take a few minutes for the extension to make it to the VM, install docker and do other things.

You can find the extension and Azure Linux agent logs here:

  • /var/log/azure-docker-extension-enable.log
  • /var/log/waagent.log
  • /var/log/azure/Microsoft.Azure.Extensions.DockerExtension/**/docker-extension.log

If you are going to open an issue, please provide these log files.


# 1.2.2 (2017-01-21)
- Add suport for the CoreOS rename (gh#116).

# 1.2.1 (2016-11-15) (released in Azure China only)
- Add support for Azure China by modifying the download URLs to point to the
  mirrors hosted by (gh#112)

# 1.2.0 (2016-08-19)
- Fix: On CentOS start dockerd as -H=unix:// instead of -H=fd:// as
  install script has removed socket activation. (gh#104)
- Prefer 'dockerd' in systemd unit files over 'docker daemon'. docker-engine has
  migrated to this. This is why we are releasing a minor version for the extension
  this time and not a hotfix so that existing VMs don’t automatically get this and
  old versions of docker will not work with dockerd.

# 1.1.1606092330 (2016-06-09)
- Introduced “compose-environment” public configuration to pass additional unencrypted
  environment variables to docker-compose for fine tuning. (gh#87, gh#85)
- Better error messages for docker-compose failures indicating the log path. (gh#86)

# 1.1.1604142300 (2016-04-14)
- Fix: docker v1.11 release has broken docker-compose 1.5 from pulling private images.
  Upgrading to docker-compose 1.6.2 and dropping support for docker-engine <1.9.1 (gh#80)

# 1.1.1602270800 (2016-02-28)
- Fix: extension crash while collecting “yum install” output.

# 1.1.1601140348 (2016-01-13)
- Fix: eliminate redundant restarts of docker-engine on CoreOS if configuration
  is not changed.

# 1.1.1601070410 (2016-01-06)
- Fix: eliminate redundant restarting of docker-engine. This avoids restart of
  docker-engine service (and thus containers) when (1) VM boots (2) waagent
  calls extension's enable command in case of GoalState changes such as Load
  Balancer updates.
- Fix: Write .status file before forking into background in 'enable' command.
  This is a workaround for waagent 2.1.x.

# 1.1.1512180541 (2015-12-17)
- Security fix: prevent clear-text registry credentials from being logged.

# 1.1.1512090359 (2015-12-08)
- Introduced secure delivery of secrets through "environment" section of
  protected configuration to be passed to docker-compose. Users do not have
  to embed secrets in the "compose" section anymore.

# 1.0.1512030601 (2015-12-02)
- Added support for CentOS and Red Hat Enterprise Linux (RHEL).

# 1.0.1512020618 (2015-12-01)
- Bumped docker-compose version from v1.4.1 to v1.5.1.
- Added retry logic around installation as a mitigation for a VM scale set

# 1.0.1510142311 (2015-10-14)
- Configured docker-compose timeout to 15 minutes to prevent big images
  from failing to be pulled down intermittently due to network conditions.

# 1.0.1509171835 (2015-09-18)
- Move 'install' stage to 'enable' step so that installation is not killed by
  5-minute waagent timeout on slow regions and distros (such as Ubuntu LTS)
  with many missing dependency packages.
- Bump docker-compose to v1.4.0 from v1.3.2.
- Extension now uninstalls docker-compose on 'uninstall' stage.

# 1.0.1509160543 (2015-09-16)
- Workaround for undesirable behavior in WALA: Write .seqnum file to /tmp to
  prevent multiple simultaneous calls to the extension with the same sequence

# 1.0.1508121604 (2015-08-12)
- Replaced '--daemon' flag with daemon due to breaking behavior introduced in
  docker-1.8.0 release.

# 1.0.1507232004 (2015-07-23)
- Updating the apt package name for uninstall step.

# 1.0.1507151643 (2015-07-15)
- Bump docker-compose to v1.3.2 from v1.2.0. (gh#41)

# 1.0.1507110733 (2015-07-11)
- Workaround for a bug caused from docker-compose to crash with error
  'write /dev/stderr: broken pipe'

# 1.0.1507101636 (2015-07-10)
- Bug fix (gh#38). Blocking on install step instead of forking and running in

# 1.0.1507020203 (2015-07-01)
- Better docker-compose integration and prevent duplicate container creations
  between reboots.
- Fork and run in background install/enable steps to avoid waagent time limits.

# 1.0.1506280321 (2015-06-27)
- "certs" that are not base64-encoded are also accepted now. This provides more
  backwards compatibility with the existing format in the old extension.
- Docker certs are now overwritten on every 'enable' run using the extension
- Placed certs server-cert.pem/server-key.pem are renamed to cert.pem/key.pem to
  be consistent with Docker's nomenclature. The change should be automatically
  picked up upon reboot.

# 1.0.1506141804 (2015-06-14)
- Privacy Policy link update

# 1.0.1506090235 (2015-06-09)
- Bug fix

# 1.0.1506041832 (2015-06-04)
- Initial release

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact with any additional questions or comments.