Edit

Share via


Continuous deployment with custom containers in Azure App Service

This article explains how to configure continuous integration and continuous delivery (CI/CD) for a custom container image from managed Azure Container Registry repositories or Docker Hub.

Go to the Deployment Center

In the Azure portal, go to the management pane for your Azure App Service app.

On the sidebar menu under Deployment, select Deployment Center > Settings.

Select the code source

From the Source dropdown menu, select the deployment source based on the following criteria:

  • Container registry sets up CI/CD between your container registry and App Service.
  • Select the GitHub Actions option if you maintain the source code for your container image in GitHub. New commits to your GitHub repository trigger the deploy action, which can run docker build and docker push directly to your container registry. It then updates your App Service app to run the new image. For more information, see How CI/CD works with GitHub Actions.

If you select GitHub Actions, select Authorize and follow the authorization prompts. If you previously authorized with GitHub, you can deploy from a different user's repository by selecting Change Account.

After you authorize your Azure account with GitHub, select the Organization, Repository, and Branch to deploy from.

Configure registry settings

Configure registry settings

Note

Sidecar containers will succeed multi-container (Docker Compose) apps in App Service. To get started, see Tutorial: Configure a sidecar container for custom containers in Azure App Service.

To deploy a multi-container (Docker Compose) app, select Docker Compose in Container Type. If you don't see the Container Type dropdown list, scroll back up to Source and select Container Registry.

In Registry source, select the location of your container registry. If it's not Azure Container Registry or Docker Hub, select Private registry.

Note

If your multi-container (Docker Compose) app uses more than one private image, make sure the private images are in the same private registry and are accessible with the same user credentials. If your multi-container app uses only public images, select Docker Hub, even if some images aren't in Docker Hub.

Follow the next steps by selecting the tab that matches your choice.

The Registry dropdown list displays the registries in the same subscription as your app. Select the registry you want.

To deploy from a registry in a different subscription, select Private registry in Registry source instead.

To use managed identities to lock down Azure Container Registry access, see:

Select the Image and Tag to deploy. You can type the startup command in Startup File.

Choose the next step based on the Container Type value:

  • Docker Compose: Select the registry for your private images. Select Choose file to upload your Docker Compose file, or just paste the contents of your Docker Compose file into Config.
  • Single Container: Select the values for Image and Tag that you want to deploy. You can type the startup command in Startup File.

App Service appends the string in Startup File to the end of the docker run command (as the [COMMAND] [ARG...] segment) when your container starts.

Enable CI/CD

Enable CI/CD

App Service supports CI/CD integration with Azure Container Registry and Docker Hub. To enable CI/CD integration, select On in Continuous deployment.

Note

If you select GitHub Actions in Source, you don't see this option because CI/CD is handled directly by GitHub Actions. Instead, you see a Workflow Configuration section, where you can select Preview file to inspect the workflow file. Azure commits this file into your selected GitHub source repository to handle build and deploy tasks. For more information, see How CI/CD works with GitHub Actions.

When you enable this option, App Service adds a webhook to your repository in Azure Container Registry or Docker Hub. Your repository posts to this webhook whenever you update your selected image with docker push. The webhook causes your App Service app to restart and run docker pull to get the updated image.

To ensure that the webhook functions properly, enable the Basic Auth Publishing Credentials option within your web app. If you don't, you might receive a "401 unauthorized" error for the webhook.

To verify whether the Basic Auth Publishing Credentials option is enabled, go to Configuration > General Settings in your web app. Look for the Platform Setting section, and then select the Basic Auth Publishing Credentials option.

For other private registries, you can manually post to the webhook or as a step in a CI/CD pipeline. In Webhook URL, select the Copy button to get the webhook URL.

Select Save to save your settings.

Note

Support for multi-container (Docker Compose) apps is limited. For Azure Container Registry, App Service creates a webhook in the selected registry with the registry as the scope. A docker push to any repository in the registry (including the ones not referenced by your Docker Compose file) triggers an app restart. You might want to modify the webhook to a narrower scope. Docker Hub doesn't support webhooks at the registry level. You must manually add the webhooks to the images specified in your Docker Compose file.

How CI/CD works with GitHub Actions

If you select GitHub Actions from the Select code source dropdown menu, App Service sets up CI/CD in the following ways:

  • It deposits a GitHub Actions workflow file into your GitHub repository to handle build and deploy tasks to App Service.
  • It adds the credentials for your private registry as GitHub secrets. The generated workflow file runs the Azure/docker-login action to sign in with your private registry. It then runs docker push to deploy to it.
  • It adds the publishing profile for your app as a GitHub secret. The generated workflow file uses this secret to authenticate with App Service. It then runs the Azure/webapps-deploy action to configure the updated image, which triggers an app restart to pull in the updated image.
  • It captures information from the workflow run logs and displays it on the Logs tab in your app's Deployment Center.

You can customize the GitHub Actions build provider in the following ways:

  • Customize the workflow file after it generates in your GitHub repository. To trigger an app restart, the workflow must end with the Azure/webapps-deploy action. For more information, go to Workflow syntax for GitHub Actions.
  • If the selected branch is protected, you can still preview the workflow file without saving the configuration. Add it and the required GitHub secrets into your repository manually. This method doesn't give you log integration with the Azure portal.
  • Instead of a publishing profile, deploy by using a service principal in Microsoft Entra ID.

Authenticate with a service principal

This optional configuration replaces the default authentication with publishing profiles in the generated workflow file.

Generate a service principal by using the az ad sp create-for-rbac command in the Azure CLI. In the following example, replace <subscription-id>, <group-name>, and <app-name> with your own values. Save the entire JSON output for the next step, including the top-level {}.

az ad sp create-for-rbac --name "myAppDeployAuth" --role contributor \
                            --scopes /subscriptions/<subscription-id>/resourceGroups/<group-name>/providers/Microsoft.Web/sites/<app-name> \
                            --json-auth

Important

For security, grant the minimum required access to the service principal. The scope in the previous example is limited to the specific App Service app and not the entire resource group.

In GitHub, go to your repository, and then select Settings > Secrets > Add a new secret. Paste the entire JSON output from the Azure CLI command into the secret's value field. Give the secret a name like AZURE_CREDENTIALS.

In the workflow file generated by the Deployment Center, revise the azure/webapps-deploy step with code similar to the following example:

- name: Sign in to Azure 
# Use the GitHub secret you added
- uses: azure/login@v1
    with:
    creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Deploy to Azure Web App
# Remove publish-profile
- uses: azure/webapps-deploy@v2
    with:
    app-name: '<app-name>'
    slot-name: 'production'
    images: '<registry-server>/${{ secrets.AzureAppService_ContainerUsername_... }}/<image>:${{ github.sha }}'
    - name: Sign out of Azure
    run: |
    az logout

Automate with CLI

To configure the container registry and the Docker image, run az webapp config container set.

az webapp config container set --name <app-name> --resource-group <group-name> --docker-custom-image-name '<image>:<tag>' --docker-registry-server-url 'https://<registry-name>.azurecr.io' --docker-registry-server-user '<username>' --docker-registry-server-password '<password>'

To configure a multi-container (Docker Compose) app, prepare a Docker Compose file locally, and then run az webapp config container set with the --multicontainer-config-file parameter. If your Docker Compose file contains private images, add --docker-registry-server-* parameters as shown in the previous example.

az webapp config container set --resource-group <group-name> --name <app-name> --multicontainer-config-file <docker-compose-file>

To configure CI/CD from the container registry to your app, run az webapp deployment container config with the --enable-cd parameter. The command outputs the webhook URL, but you must manually create the webhook in your registry in a separate step. The following example enables CI/CD on your app, and then uses the webhook URL in the output to create the webhook in Azure Container Registry.

ci_cd_url=$(az webapp deployment container config --name <app-name> --resource-group <group-name> --enable-cd true --query CI_CD_URL --output tsv)

az acr webhook create --name <webhook-name> --registry <registry-name> --resource-group <group-name> --actions push --uri $ci_cd_url --scope '<image>:<tag>'