| 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 |
|
|||
| ms.topic | tutorial | |||
| ms.date | 02/03/2025 | |||
| ms.author | cshoe | |||
| zone_pivot_groups | container-apps-image-build-type |
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 by following the instructions in the Quickstart: Build and deploy an app to Azure Container Apps from a repository 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.":::
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. 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. See Assign Azure roles using the Azure portal and Azure roles, Microsoft Entra roles, and classic subscription administrator rolesfor details. |
| GitHub Account | Sign up for free. |
| git | Install git |
| Azure CLI | Install the Azure CLI. |
::: zone-end
::: zone pivot="docker-local"
| Requirement | Instructions |
|---|---|
| Azure account | If you don't have one, create an account for free. You need the Contributor or Owner permission on the Azure subscription to proceed. Refer to Assign Azure roles using the Azure portal for details. |
| GitHub Account | Sign up for free. |
| git | Install git |
| Azure CLI | Install the Azure CLI. |
| Docker Desktop | Docker provides installers that configure the Docker environment on macOS, Windows, and Linux. From your command prompt, type docker to ensure Docker is running. |
::: zone-end
[!INCLUDE container-apps-create-cli-steps.md]
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]
Navigate to the repository for your preferred language and fork the repository.
Select the Fork button at the top of the album API repo 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 clone https://github.com/$GITHUB_USERNAME/containerapps-albumapi-csharp.git code-to-cloud
Select the Fork button at the top of the album API repo 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 clone https://github.com/$GITHUB_USERNAME/containerapps-albumapi-go.git code-to-cloud
Select the Fork button at the top of the album API repo 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 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.
Select the Fork button at the top of the album API repo 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 clone https://github.com/$GITHUB_USERNAME/containerapps-albumapi-javascript.git code-to-cloud
Select the Fork button at the top of the album API repo 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 clone https://github.com/$GITHUB_USERNAME/containerapps-albumapi-python.git code-to-cloud
Next, change the directory into the root of the cloned repo.
cd code-to-cloud/src[!INCLUDE container-apps-create-resource-group.md]
-
After the album API container image is built, create an Azure Container Registry (ACR) instance in your resource group to store it.
az acr create \ --resource-group $RESOURCE_GROUP \ --location $LOCATION \ --name $ACR_NAME \ --sku Basic$acr = New-AzContainerRegistry ` -ResourceGroupName $ResourceGroup ` -Location $Location ` -Name $ACRName ` -Sku Basic
-
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).
az acr config authentication-as-arm show --registry "$ACR_NAME"If ARM tokens are allowed, the command outputs the following.
{ "status": "enabled" }If the
statusisdisabled, allow ARM tokens with the following command.az acr config authentication-as-arm update --registry "$ACR_NAME" --status enabled$acr.AzureAdAuthenticationAsArmPolicyStatusIf the command returns
disabled, allow ARM tokens with the following command.Update-AzContainerRegistry ` -ResourceGroupName $acr.ResourceGroupName ` -Name $acr.Name ` -AzureAdAuthenticationAsArmPolicyStatus enabled
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.
-
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.IDENTITY="<YOUR_IDENTITY_NAME>"az identity create \ --name $IDENTITY \ --resource-group $RESOURCE_GROUP -
Get the identity's resource ID.
IDENTITY_ID=$(az identity show \ --name $IDENTITY \ --resource-group $RESOURCE_GROUP \ --query id \ --output tsv)
-
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.$IdentityName="<YOUR_IDENTITY_NAME>" $Identity = New-AzUserAssignedIdentity -ResourceGroupName $ResourceGroup -Name $IdentityName -
Get the identity's resource and principal ID.
$IdentityId = $Identity.Id $PrincipalId = (Get-AzUserAssignedIdentity -Name $IdentityName -ResourceGroupName $ResourceGroup).PrincipalId -
Get the registry's resource ID. Before you run the following command, replace the <placeholders> with the resource group name for your registry.
$RegistryId = (Get-AzContainerRegistry -ResourceGroupName $ResourceGroup -Name $ACRName).Id -
Create the
acrpullrole assignment for the identity.New-AzRoleAssignment -ObjectId $PrincipalId -Scope $RegistryId -RoleDefinitionName acrpull
::: zone pivot="acr-remote"
With ACR tasks, you can build and push the docker image for the album API without installing Docker locally.
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.
az acr build --registry $ACR_NAME --image $API_NAME .
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.
az loginThen build the container.
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"
The following steps show how to build your container image locally using Docker and push the image to the new container registry.
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.
docker build --tag $ACR_NAME.azurecr.io/$API_NAME .
docker build --tag "$ACRName.azurecr.io/$APIName" .First, sign in to your Azure Container Registry.
az acr login --name $ACR_NAME
Connect-AzContainerRegistry -Name $ACRName
Now, push the image to your registry.
docker push $ACR_NAME.azurecr.io/$API_NAMEdocker push "$ACRName.azurecr.io/$APIName"::: zone-end
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.
az containerapp env create \
--name $ENVIRONMENT \
--resource-group $RESOURCE_GROUP \
--location "$LOCATION"
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.
$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:
$EnvArgs = @{
EnvName = $Environment
ResourceGroupName = $ResourceGroup
Location = $Location
AppLogConfigurationDestination = 'log-analytics'
LogAnalyticConfigurationCustomerId = $WorkspaceId
LogAnalyticConfigurationSharedKey = $WorkspaceSharedKey
}
New-AzContainerAppManagedEnv @EnvArgs
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.
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
--ingresstoexternal, your container app is accessible from the public internet. -
The
target-portis set to8080to match the port that the container is listening to for requests. -
Without a
queryproperty, the call toaz containerapp createreturns 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
acrPullrole to your user-assigned managed identity, so it can pull images from your container registry.
To create the container app, create template objects that you pass in as arguments to the New-AzContainerApp command.
-
Create a template object to define your container image parameters.
$ImageParams = @{ Name = $APIName Image = $ACRName + '.azurecr.io/' + $APIName + ':latest' } $TemplateObj = New-AzContainerAppTemplateObject @ImageParams -
Create a registry credential object to define your registry information.
$RegistryArgs = @{ Server = $ACRName + '.azurecr.io' Identity = $IdentityId } $RegistryObj = New-AzContainerAppRegistryCredentialObject @RegistryArgs -
Get your environment ID.
$EnvId = (Get-AzContainerAppManagedEnv -EnvName $Environment -ResourceGroup $ResourceGroup).Id -
Create the container app.
$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
IngressExternalto$true, your container app is accessible from the public internet. - The
IngressTargetPortparameter is set to8080to match the port that the container is listening to for requests.
- By setting
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.":::
If you're not going to continue on to the Communication between microservices 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.
az group delete --name $RESOURCE_GROUP
Remove-AzResourceGroup -Name $ResourceGroup -Force
Tip
Having issues? Let us know on GitHub by opening an issue in the Azure Container Apps repo.
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