Proposed Pull Request Change

title description services author ms.service ms.custom ms.topic ms.date ms.author zone_pivot_groups
Tutorial: Build and deploy your app to Azure Container Apps Build and deploy your app to Azure Container Apps with az containerapp create command. container-apps craigshoemaker azure-container-apps ['devx-track-azurecli', 'devx-track-azurepowershell', 'ignite-2023'] tutorial 02/03/2025 cshoe container-apps-image-build-type
📄 Document Links
GitHub View on GitHub Microsoft Learn View on Microsoft Learn
Content Truncation Detected
The generated rewrite appears to be incomplete.
Original lines: -
Output lines: -
Ratio: -
Raw New Markdown
Generating updated version of doc...
Rendered New Markdown
Generating updated version of doc...
+0 -0
+0 -0
--- title: "Tutorial: Build and deploy your app to Azure Container Apps" description: Build and deploy your app to Azure Container Apps with az containerapp create command. services: container-apps author: craigshoemaker ms.service: azure-container-apps ms.custom: - devx-track-azurecli - devx-track-azurepowershell - ignite-2023 ms.topic: tutorial ms.date: 02/03/2025 ms.author: cshoe zone_pivot_groups: container-apps-image-build-type --- # Tutorial: Build and deploy your app to Azure Container Apps This article demonstrates how to build and deploy a microservice to Azure Container Apps from a source repository using your preferred programming language. This is the first tutorial in the series of articles that walk you through how to use core capabilities within Azure Container Apps. The first step is to create a back end web API service that returns a static collection of music albums. > [!NOTE] > You can also build and deploy this app using the [az containerapp up](/cli/azure/containerapp#az_containerapp_up) by following the instructions in the [Quickstart: Build and deploy an app to Azure Container Apps from a repository](quickstart-code-to-cloud.md) article. The `az containerapp up` command is a fast and convenient way to build and deploy your app to Azure Container Apps using a single command. However, it doesn't provide the same level of customization for your container app. The next tutorial in the series will build and deploy the front end web application to Azure Container Apps. The following screenshot shows the output from the album API deployed in this tutorial. :::image type="content" source="media/quickstart-code-to-cloud/azure-container-apps-album-api.png" alt-text="Screenshot of response from albums API endpoint."::: ## Prerequisites To complete this project, you need the following items: ::: zone pivot="acr-remote" | Requirement | Instructions | |--|--| | Azure account | If you don't have one, [create an account for free](https://azure.microsoft.com/pricing/purchase-options/azure-account?cid=msft_learn). You need the *User Access Administrator* or *Owner* permission on the Azure subscription to proceed. Make sure to use the most restrictive role for your context. <br><br>See [Assign Azure roles using the Azure portal](/azure/role-based-access-control/role-assignments-portal?tabs=current) and [Azure roles, Microsoft Entra roles, and classic subscription administrator roles](/azure/role-based-access-control/rbac-and-directory-admin-roles)for details. | | GitHub Account | Sign up for [free](https://github.com/join). | | git | [Install git](https://git-scm.com/downloads) | | Azure CLI | Install the [Azure CLI](/cli/azure/install-azure-cli).| ::: zone-end ::: zone pivot="docker-local" | Requirement | Instructions | |--|--| | Azure account | If you don't have one, [create an account for free](https://azure.microsoft.com/pricing/purchase-options/azure-account?cid=msft_learn). You need the *Contributor* or *Owner* permission on the Azure subscription to proceed. Refer to [Assign Azure roles using the Azure portal](/azure/role-based-access-control/role-assignments-portal?tabs=current) for details. | | GitHub Account | Sign up for [free](https://github.com/join). | | git | [Install git](https://git-scm.com/downloads) | | Azure CLI | Install the [Azure CLI](/cli/azure/install-azure-cli).| | Docker Desktop | Docker provides installers that configure the Docker environment on [macOS](https://docs.docker.com/docker-for-mac/), [Windows](https://docs.docker.com/docker-for-windows/), and [Linux](https://docs.docker.com/engine/installation/#supported-platforms). <br><br>From your command prompt, type `docker` to ensure Docker is running. | ::: zone-end [!INCLUDE [container-apps-create-cli-steps.md](../../includes/container-apps-create-cli-steps.md)] ## Create environment variables Now that your Azure CLI setup is complete, you can define the environment variables that are used throughout this article. [!INCLUDE [container-apps-code-to-cloud-setup.md](../../includes/container-apps-code-to-cloud-setup.md)] ## Prepare the GitHub repository Navigate to the repository for your preferred language and fork the repository. # [C#](#tab/csharp) Select the **Fork** button at the top of the [album API repo](https://github.com/azure-samples/containerapps-albumapi-csharp) to fork the repo to your account. Now you can clone your fork of the sample repository. Use the following git command to clone your forked repo into the *code-to-cloud* folder: ```git git clone https://github.com/$GITHUB_USERNAME/containerapps-albumapi-csharp.git code-to-cloud ``` # [Go](#tab/go) Select the **Fork** button at the top of the [album API repo](https://github.com/azure-samples/containerapps-albumapi-go) to fork the repo to your account. Now you can clone your fork of the sample repository. Use the following git command to clone your forked repo into the *code-to-cloud* folder: ```git git clone https://github.com/$GITHUB_USERNAME/containerapps-albumapi-go.git code-to-cloud ``` # [Java](#tab/java) Select the **Fork** button at the top of the [album API repo](https://github.com/azure-samples/containerapps-albumapi-java) to fork the repo to your account. Now you can clone your fork of the sample repository. Use the following git command to clone your forked repo into the *code-to-cloud* folder: ```git git clone https://github.com/$GITHUB_USERNAME/containerapps-albumapi-java.git code-to-cloud ``` > [!NOTE] > The Java sample only supports a Maven build, which results in an executable JAR file. The build uses the default settings, as passing in environment variables is not supported. # [JavaScript](#tab/javascript) Select the **Fork** button at the top of the [album API repo](https://github.com/azure-samples/containerapps-albumapi-javascript) to fork the repo to your account. Now you can clone your fork of the sample repository. Use the following git command to clone your forked repo into the *code-to-cloud* folder: ```git git clone https://github.com/$GITHUB_USERNAME/containerapps-albumapi-javascript.git code-to-cloud ``` # [Python](#tab/python) Select the **Fork** button at the top of the [album API repo](https://github.com/azure-samples/containerapps-albumapi-python) to fork the repo to your account. Now you can clone your fork of the sample repository. Use the following git command to clone your forked repo into the *code-to-cloud* folder: ```git git clone https://github.com/$GITHUB_USERNAME/containerapps-albumapi-python.git code-to-cloud ``` --- Next, change the directory into the root of the cloned repo. ```console cd code-to-cloud/src ``` [!INCLUDE [container-apps-create-resource-group.md](../../includes/container-apps-create-resource-group.md)] ## Create an Azure Container Registry 1. After the album API container image is built, create an Azure Container Registry (ACR) instance in your resource group to store it. # [Bash](#tab/bash) ```azurecli az acr create \ --resource-group $RESOURCE_GROUP \ --location $LOCATION \ --name $ACR_NAME \ --sku Basic ``` # [PowerShell](#tab/powershell) ```azurepowershell $acr = New-AzContainerRegistry ` -ResourceGroupName $ResourceGroup ` -Location $Location ` -Name $ACRName ` -Sku Basic ``` --- 1. Your container registry must allow Azure Resource Manager (ARM) audience tokens for authentication in order to use managed identity to pull images. Use the following command to check if ARM tokens are allowed to access your Azure Container Registry (ACR). # [Bash](#tab/bash) ```azurecli az acr config authentication-as-arm show --registry "$ACR_NAME" ``` If ARM tokens are allowed, the command outputs the following. ``` { "status": "enabled" } ``` If the `status` is `disabled`, allow ARM tokens with the following command. ```azurecli az acr config authentication-as-arm update --registry "$ACR_NAME" --status enabled ``` # [PowerShell](#tab/powershell) ```azurepowershell $acr.AzureAdAuthenticationAsArmPolicyStatus ``` If the command returns `disabled`, allow ARM tokens with the following command. ```azurepowershell Update-AzContainerRegistry ` -ResourceGroupName $acr.ResourceGroupName ` -Name $acr.Name ` -AzureAdAuthenticationAsArmPolicyStatus enabled ``` --- ## Create a user-assigned managed identity To avoid using administrative credentials, pull images from private repositories in Microsoft Azure Container Registry using managed identities for authentication. When possible, use a user-assigned managed identity to pull images. # [Bash](#tab/bash) 1. Create a user-assigned managed identity. Before you run the following commands, choose a name for your managed identity and replace the `\<PLACEHOLDER\>` with the name. ```bash IDENTITY="<YOUR_IDENTITY_NAME>" ``` ```azurecli az identity create \ --name $IDENTITY \ --resource-group $RESOURCE_GROUP ``` 1. Get the identity's resource ID. ```azurecli IDENTITY_ID=$(az identity show \ --name $IDENTITY \ --resource-group $RESOURCE_GROUP \ --query id \ --output tsv) ``` # [PowerShell](#tab/powershell) 1. Create a user-assigned managed identity. Before you run the following commands, choose a name for your managed identity and replace the `\<PLACEHOLDER\>` with the name. ```azurepowershell $IdentityName="<YOUR_IDENTITY_NAME>" $Identity = New-AzUserAssignedIdentity -ResourceGroupName $ResourceGroup -Name $IdentityName ``` 1. Get the identity's resource and principal ID. ```azurepowershell $IdentityId = $Identity.Id $PrincipalId = (Get-AzUserAssignedIdentity -Name $IdentityName -ResourceGroupName $ResourceGroup).PrincipalId ``` 1. Get the registry's resource ID. Before you run the following command, replace the *\<placeholders\>* with the resource group name for your registry. ```azurepowershell $RegistryId = (Get-AzContainerRegistry -ResourceGroupName $ResourceGroup -Name $ACRName).Id ``` 1. Create the `acrpull` role assignment for the identity. ```azurepowershell New-AzRoleAssignment -ObjectId $PrincipalId -Scope $RegistryId -RoleDefinitionName acrpull ``` --- ::: zone pivot="acr-remote" ## Build your application With [ACR tasks](/azure/container-registry/container-registry-tasks-overview), you can build and push the docker image for the album API without installing Docker locally. ### Build the container with ACR Run the following command to initiate the image build and push process using ACR. The `.` at the end of the command represents the docker build context, meaning this command should be run within the *src* folder where the Dockerfile is located. # [Bash](#tab/bash) ```azurecli az acr build --registry $ACR_NAME --image $API_NAME . ``` # [PowerShell](#tab/powershell) The `az acr build` command does not have a PowerShell equivalent, but can be run in PowerShell. To sign into Azure with the Azure CLI, run the following command and follow the prompts to complete the authentication process. ```powershell az login ``` Then build the container. ```powershell az acr build --registry $AcrName --image $APIName . ``` --- Output from the `az acr build` command shows the upload progress of the source code to Azure and the details of the `docker build` and `docker push` operations. ::: zone-end ::: zone pivot="docker-local" ## Build your application The following steps show how to build your container image locally using Docker and push the image to the new container registry. ### Build the container with Docker The following command builds a container image for the album API and tags it with the fully qualified name of the ACR login server. The `.` at the end of the command represents the docker build context, meaning this command should be run within the *src* folder where the Dockerfile is located. # [Bash](#tab/bash) ```azurecli docker build --tag $ACR_NAME.azurecr.io/$API_NAME . ``` # [PowerShell](#tab/powershell) ```powershell docker build --tag "$ACRName.azurecr.io/$APIName" . ``` --- ### Push the image to your container registry First, sign in to your Azure Container Registry. # [Bash](#tab/bash) ```azurecli az acr login --name $ACR_NAME ``` # [PowerShell](#tab/powershell) ```azurepowershell Connect-AzContainerRegistry -Name $ACRName ``` --- Now, push the image to your registry. # [Bash](#tab/bash) ```bash docker push $ACR_NAME.azurecr.io/$API_NAME ``` # [PowerShell](#tab/powershell) ```bash docker push "$ACRName.azurecr.io/$APIName" ``` --- ::: zone-end ## Create a Container Apps environment The Azure Container Apps environment acts as a secure boundary around a group of container apps. Create the Container Apps environment using the following command. # [Bash](#tab/bash) ```azurecli az containerapp env create \ --name $ENVIRONMENT \ --resource-group $RESOURCE_GROUP \ --location "$LOCATION" ``` # [PowerShell](#tab/powershell) A Log Analytics workspace is required for the Container Apps environment. The following commands create a Log Analytics workspace and save the workspace ID and primary shared key to variables. ```azurepowershell $WorkspaceArgs = @{ Name = 'my-album-workspace' ResourceGroupName = $ResourceGroup Location = $Location PublicNetworkAccessForIngestion = 'Enabled' PublicNetworkAccessForQuery = 'Enabled' } New-AzOperationalInsightsWorkspace @WorkspaceArgs $WorkspaceId = (Get-AzOperationalInsightsWorkspace -ResourceGroupName $ResourceGroup -Name $WorkspaceArgs.Name).CustomerId $WorkspaceSharedKey = (Get-AzOperationalInsightsWorkspaceSharedKey -ResourceGroupName $ResourceGroup -Name $WorkspaceArgs.Name).PrimarySharedKey ``` To create the environment, run the following command: ```azurepowershell $EnvArgs = @{ EnvName = $Environment ResourceGroupName = $ResourceGroup Location = $Location AppLogConfigurationDestination = 'log-analytics' LogAnalyticConfigurationCustomerId = $WorkspaceId LogAnalyticConfigurationSharedKey = $WorkspaceSharedKey } New-AzContainerAppManagedEnv @EnvArgs ``` --- ## Deploy your image to a container app Now that you have an environment created, you can create and deploy your container app with the `az containerapp create` command. Create and deploy your container app with the following command. # [Bash](#tab/bash) ```azurecli az containerapp create \ --name $API_NAME \ --resource-group $RESOURCE_GROUP \ --environment $ENVIRONMENT \ --image $ACR_NAME.azurecr.io/$API_NAME \ --target-port 8080 \ --ingress external \ --registry-server $ACR_NAME.azurecr.io \ --user-assigned "$IDENTITY_ID" \ --registry-identity "$IDENTITY_ID" \ --query properties.configuration.ingress.fqdn ``` * By setting `--ingress` to `external`, your container app is accessible from the public internet. * The `target-port` is set to `8080` to match the port that the container is listening to for requests. * Without a `query` property, the call to `az containerapp create` returns a JSON response that includes a rich set of details about the application. Adding a query parameter filters the output to just the app's fully qualified domain name (FQDN). * This command adds the `acrPull` role to your user-assigned managed identity, so it can pull images from your container registry. # [PowerShell](#tab/powershell) To create the container app, create template objects that you pass in as arguments to the `New-AzContainerApp` command. 1. Create a template object to define your container image parameters. ```azurepowershell $ImageParams = @{ Name = $APIName Image = $ACRName + '.azurecr.io/' + $APIName + ':latest' } $TemplateObj = New-AzContainerAppTemplateObject @ImageParams ``` 1. Create a registry credential object to define your registry information. ```azurepowershell $RegistryArgs = @{ Server = $ACRName + '.azurecr.io' Identity = $IdentityId } $RegistryObj = New-AzContainerAppRegistryCredentialObject @RegistryArgs ``` 1. Get your environment ID. ```azurepowershell $EnvId = (Get-AzContainerAppManagedEnv -EnvName $Environment -ResourceGroup $ResourceGroup).Id ``` 1. Create the container app. ```azurepowershell $AppConfig = @{ IngressTargetPort = 8080 IngressExternal = $true Registry = $RegistryObj } $AppConfigObj = New-AzContainerAppConfigurationObject @AppConfig $AppArgs = @{ Name = $APIName Location = $Location ResourceGroupName = $ResourceGroup ManagedEnvironmentId = $EnvId TemplateContainer = $TemplateObj Configuration = $AppConfigObj UserAssignedIdentity = @($IdentityId) } $MyApp = New-AzContainerApp @AppArgs # Show the app's fully qualified domain name (FQDN). $MyApp.LatestRevisionFqdn ``` * By setting `IngressExternal` to `$true`, your container app is accessible from the public internet. * The `IngressTargetPort` parameter is set to `8080` to match the port that the container is listening to for requests. --- ## Verify deployment Copy the FQDN to a web browser. From your web browser, navigate to the `/albums` endpoint of the FQDN. :::image type="content" source="media/quickstart-code-to-cloud/azure-container-apps-album-api.png" alt-text="Screenshot of response from albums API endpoint."::: ## Clean up resources If you're not going to continue on to the [Communication between microservices](communicate-between-microservices.md) tutorial, you can remove the Azure resources created during this quickstart. Run the following command to delete the resource group along with all the resources created in this quickstart. # [Bash](#tab/bash) ```azurecli az group delete --name $RESOURCE_GROUP ``` # [PowerShell](#tab/powershell) ```azurepowershell Remove-AzResourceGroup -Name $ResourceGroup -Force ``` --- > [!TIP] > Having issues? Let us know on GitHub by opening an issue in the [Azure Container Apps repo](https://github.com/microsoft/azure-container-apps). ## Next steps This quickstart is the entrypoint for a set of progressive tutorials that showcase the various features within Azure Container Apps. Continue on to learn how to enable communication from a web front end that calls the API you deployed in this article. > [!div class="nextstepaction"] > [Tutorial: Communication between microservices](communicate-between-microservices.md)
Success! Branch created successfully. Create Pull Request on GitHub
Error: