Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Learn how to configure continuous integration and continuous delivery (CI/CD) for a custom container image from managed Azure Container Registry repositories or Docker Hub.
1. Go to the Deployment Center
In the Azure portal, go to the management pane for your Azure App Service app.
From the left menu, select Deployment Center > Settings.
2. Choose deployment source
Choose the deployment source based on the following criteria:
- Container registry sets up CI/CD between your container registry and App Service.
- Choose 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
anddocker 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. - To set up CI/CD with Azure Pipelines, see Deploy an Azure Web App Container from Azure Pipelines.
- For a Docker Compose app, select Container Registry.
If you choose 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.
2. Configure registry settings
3. Configure registry settings
Note
Sidecar containers (preview) 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 (preview).
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 where your container registry is. 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:
- How to use system-assigned managed identities with App Service and Azure Container Registry
- How to use user-assigned managed identities with App Service and Azure Container Registry
Select the Image and Tag to deploy. You can choose to type the startup command in Startup File.
Follow the next step, depending on the Container Type value:
- For 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.
- For Single Container, select the Image and Tag to deploy. You can choose to 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 starting your container.
3. Enable CI/CD
4. 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 by GitHub Actions directly. 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 your selected image is updated with docker push
. The webhook causes your App Service app to restart and run docker pull
to get the updated image.
To ensure the proper functioning of the webhook, it's essential to 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 Basic Auth Publishing Credentials is enabled, go to your web app's Configuration > General Settings. Look for the Platform Setting section, and then select the Basic Auth Publishing Credentials option.
For other private registries, you can post to the webhook manually or as a step in a CI/CD pipeline. In Webhook URL, select the Copy button to get the webhook URL.
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 add the webhooks manually to the images specified in your Docker Compose file.
4. Save your settings
5. Save your settings
Select Save.
How CI/CD works with GitHub Actions
If you choose GitHub Actions in Source (see Choose deployment source), 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, and then runsdocker 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, and 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 in 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. For more information, see Workflow syntax for GitHub Actions. The workflow must end with the
Azure/webapps-deploy
action to trigger an app restart. - 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 create the webhook in your registry manually 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>'