Overview

App Service Plans on Linux allows you to quickly deploy and run any Linux-based application. While creating your web applications you can choose between a few options. You can select already prepared environment and just deploy your source code there or you can easily populate the web app with already created docker image.

Your docker images can have different sources. It can be:

  • Docker Hub
  • Azure Container Registry
  • Some other private registry

Although it’s very easy to select the image in the portal, I’m sure it’s very desirable to be able to set that in code. There are lots of examples for Azure CLI tool, but if you prefer or need to use PowerShell I hope you will find this post helpful.

What needs to be set

Regardless of the type of your registry, you will always need to set:

  • image and tag name (using special property field)
  • port on which your application will be running (app setting)

Please note:

You can specify docker image as app setting too, but this won’t work if docker image was already specified in Azure portal.

Additionally, if your image is private you will need to provide docker registry details. All of that can be set using app settings too.

Deployment slots

It’s very popular to use Web Apps with deployment slots. In my example function, I’ve updated the code so you will be able to specify the name of your slot.

Code

Let’s see the implementation plus some examples of how to use it.

Function Set-DockerImageForWebApp {

    param(
        [Parameter(Mandatory = $true)] [string] $ResourceGroup,
        [Parameter(Mandatory = $true)] [string] $WebApplicationName,
        [Parameter(Mandatory = $true)] [string] $DockerImage,
        [Parameter(Mandatory = $true)] [string] $WebApplicationPortNumber,
        [Parameter(Mandatory = $false)] [switch] $IsPrivateRegistry = $false,
        [Parameter(Mandatory = $false)] [string] $RegistryUrl,
        [Parameter(Mandatory = $false)] [string] $RegistryUserName,
        [Parameter(Mandatory = $false)] [string] $RegistryPassword,
        [Parameter(Mandatory = $false)] [switch] $UseDeploymentSlot = $false,
        [Parameter(Mandatory = $false)] [string] $DeploymentSlotName = "production"
    )

    $resourceType = "Microsoft.Web/sites/config"
    if ($UseDeploymentSlot) {
        $resourceType = "Microsoft.Web/sites/slots/$DeploymentSlotName/config";
    }

    $resource = Get-AzureRmResource -ResourceGroupName $ResourceGroup -ResourceType $resourceType -ResourceName $WebApplicationName -ApiVersion 2016-08-01
    $resource.Properties.linuxFxVersion = "DOCKER|$DockerImage"
    $resource | Set-AzureRmResource -Force -ApiVersion 2016-08-01

    $website = (Get-AzureRmWebAppSlot -ResourceGroupName $ResourceGroup  -Name $WebApplicationName -Slot $DeploymentSlotName)
    
    $settings = $website.SiteConfig.AppSettings

    $settingsAsHashTable = @{}
    ForEach ($keyValuePair in $settings) {
        $settingsAsHashTable[$keyValuePair.Name] = $keyValuePair.Value
    }
    $settingsAsHashTable["WEBSITES_PORT"] = $WebApplicationPortNumber

    if ($IsPrivateRegistry) {
        $settingsAsHashTable["DOCKER_REGISTRY_SERVER_URL"] = $RegistryUrl
        $settingsAsHashTable["DOCKER_REGISTRY_SERVER_USERNAME"] = $RegistryUserName
        $settingsAsHashTable["DOCKER_REGISTRY_SERVER_PASSWORD"] = $RegistryPassword
    }

    Set-AzureRmWebAppSlot -ResourceGroupName $ResourceGroup  -Name $WebApplicationName -Slot $DeploymentSlotName -AppSettings $settingsAsHashTable
}

Example usage:

Docker hub image

Set-DockerImageForWebApp -ResourceGroup "SomeRG" -WebApplicationName "SomeApp" `
                         -DockerImage "grafana/grafana:5.0.0-beta1" `
                         -WebApplicationPortNumber 3000

Private azure registry

Set-DockerImageForWebApp -ResourceGroup "SomeRG" -WebApplicationName "SomeApp" `
                         -DockerImage "some-url.azurecr.io/image:1" `
                         -WebApplicationPortNumber 3000 `
                         -IsPrivateRegistry `
                         -RegistryUrl "https://some-url.azurecr.io" `
                         -RegistryPassword "some-password" `
                         -RegistryUserName "some-registry"

Please note:

If you’re using azure registry - remember to add https at the beginning of registry url value.

Deployment slot example

Set-DockerImageForWebApp -ResourceGroup "SomeRG" -WebApplicationName "SomeApp" `
                         -DockerImage "grafana/grafana:5.0.0-beta1" `
                         -WebApplicationPortNumber 3000 `
                         -UseDeploymentSlot -DeploymentSlotName "test"