Tutorial: Build and deploy from source code to Azure Container Apps

This article shows you how to build and deploy an application to Azure Container Apps from source code on your machine in your preferred programming language.

In this tutorial you:

  • Create a simple web application.
  • Create an associated Dockerfile for your app.
  • Create an image from the compiled code and push it to a container registry.
  • Use managed identity to securely access your container registry.
  • Deploy your container to Azure Container Apps.
  • View your app in a browser to verify deployment.

Prerequisites

To complete this project, you need the following items:

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.
Azure CLI Install the Azure CLI or upgrade to the latest version. The Azure Developer CLI (azd commands) is available through the Azure CLI.

Depending on your choice of language, you also might need to install the appropriate runtime, SDK, and other dependencies.

Install the .NET SDK.

Create the local application

The following steps show the code and dependencies required to build a sample application to deploy on Azure Container Apps.

Note

If you would like to use another language other than the ones listed, enter the following prompt into your preferred AI model.

Before you submit the prompt, replace <LANGUAGE> with your language of choice.

Generate the simplest possible "hello world" web server in idiomatic <LANGUAGE>.

Make sure to include any dependencies required for the application to run locally and in production. 
  1. Create and run your source code.

    Create a new C# project.

    dotnet new webapp --name MyAcaDemo --language C#
    

    Change into the MyAcaDemo folder.

    cd MyAcaDemo
    

    Open Program.cs in a code editor and replace the contents with the following code.

    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }
    
        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                    webBuilder.UseUrls("http://*:8080");
                });
    }
    

    Implementing the Program class with this code creates the basis of a web application. Next, create a class responsible for returning a web page as a response.

    In the same folder, create a new file named Startup.cs and enter the following code.

    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
        }
    
        public void Configure(IApplicationBuilder app)
        {   
            app.UseRouting();
    
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGet("/", async context =>
                {
                    await context.Response.WriteAsync("Hello World!");
                });
            });
        }
    }
    

    Now when a request is made to your web application, the text "Hello World!" is returned. To verify your code is running correctly on your local machine, build your project in release configuration.

    dotnet build -c Release
    

    Next, run your application to verify your code is implemented correctly.

    dotnet run --configuration Release
    

    Once you verify the application works as expected, you can stop the local server and move on to creating a Dockerfile so you can deploy the app to Container Apps.

  2. In the MyAcaDemo folder, create a file named Dockerfile and add the following contents.

    FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
    WORKDIR /src
    COPY . .
    RUN dotnet publish -c Release -o /app/publish
    
    FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final
    WORKDIR /app
    COPY --from=build /app/publish .
    EXPOSE 8080
    ENTRYPOINT ["dotnet", "MyAcaDemo.dll"]
    

    Now that you have your code and a Dockerfile ready, you can deploy your app to Azure Container Apps.

Create Azure resources

  1. Sign in to Azure from the CLI with the following command. To complete the authentication process, make sure to follow all the prompts.

    az login
    
  2. Install or update the Azure Container Apps extension for the Azure CLI.

    az extension add --name containerapp --upgrade
    

    Note

    If you receive errors about missing parameters when you run az containerapp commands, be sure you have the latest version of the Azure Container Apps extension installed.

  3. Now that your Azure CLI setup is complete, you can define a set of environment variables.

    Before you run the following command, review the provided values.

    The location is configured as Central US, but you can change to a location nearest you if you prefer.

    LOCATION="CentralUS"
    RESOURCE_GROUP="my-demo-group"
    IDENTITY_NAME="my-demo-identity"
    ENVIRONMENT="my-demo-environment"
    REGISTRY_NAME="mydemoregistry$(openssl rand -hex 4)"
    CONTAINER_APP_NAME="my-demo-app"
    

    The mydemoregistry$(openssl rand -hex 4) command generates a random string to use as your container registry name. Registry names must be globally unique, so this string helps ensure your commands run successfully.

  4. Create a resource group to organize the services related to your container app deployment.

    az group create \
      --name $RESOURCE_GROUP \
      --location $LOCATION \
      --output none
    
  5. Create a user-assigned managed identity and get its ID with the following commands.

    First, create the managed identity.

    az identity create \
        --name $IDENTITY_NAME \
        --resource-group $RESOURCE_GROUP \
        --output none
    

    Now set the identity identifier into a variable for later use.

    IDENTITY_ID=$(az identity show \
      --name $IDENTITY_NAME \
      --resource-group $RESOURCE_GROUP \
      --query id \
      --output tsv)
    
  6. Create a Container Apps environment to host your app using the following command.

    az containerapp env create \
        --name $ENVIRONMENT \
        --resource-group $RESOURCE_GROUP \
        --location $LOCATION \
        --mi-user-assigned $IDENTITY_ID \
        --output none
    
  7. Create an Azure Container Registry (ACR) instance in your resource group. The registry stores your container image.

    az acr create \
      --resource-group $RESOURCE_GROUP \
      --name $REGISTRY_NAME \
      --sku Basic \
      --output none
    
  8. Assign your user-assigned managed identity to your container registry instance with the following command.

    az acr identity assign \
      --identities $IDENTITY_ID \
      --name $REGISTRY_NAME \
      --resource-group $RESOURCE_GROUP \
      --output none
    

Build and push the image to a registry

Build and push your container image to your container registry instance with the following command.

az acr build \
    -t $REGISTRY_NAME".azurecr.io/"$CONTAINER_APP_NAME":helloworld" \
    -r $REGISTRY_NAME .

This command applies the tag helloworld to your container image.

Create your container app

Create your container app with the following command.

az containerapp create \
  --name $CONTAINER_APP_NAME \
  --resource-group $RESOURCE_GROUP \
  --environment $ENVIRONMENT \
  --image $REGISTRY_NAME".azurecr.io/"$CONTAINER_APP_NAME":helloworld" \
  --target-port 8080 \
  --ingress external \
  --user-assigned $IDENTITY_ID \
  --registry-identity $IDENTITY_ID \
  --registry-server $REGISTRY_NAME.azurecr.io \
  --query properties.configuration.ingress.fqdn

This command adds the acrPull role to your user-assigned managed identity, so it can pull images from your container registry.

The following table describes the parameters used by this command.

Parameter Value Description
name $CONTAINER_APP_NAME The name of your container app.
resource-group $RESOURCE_GROUP The resource group in which your container app is deployed.
environment $ENVIRONMENT The environment in which your container app runs.
image $REGISTRY_NAME".azurecr.io/"$CONTAINER_APP_NAME":helloworld" The container image to deploy, including the registry name and tag.
target-port 80 Matches the port that your app is listening to for requests.
ingress external Makes your container app accessible from the public internet.
user-assigned $IDENTITY_ID The user-assigned managed identity for your container app.
registry-identity registry-identity The identity used to access the container registry.
registry-server $REGISTRY_NAME.azurecr.io The server address of your container registry.
query properties.configuration.ingress.fqdn Filters the output to just the app's fully qualified domain name (FQDN).

Once this command completes, it returns URL for your new web app.

Verify deployment

Copy the app's URL into a web browser. Once the container app is started, it returns Hello World!.

Since this is the first time the application is accessed, it may take a few moments for the app to return a response.

Clean up resources

If you're not going to use the Azure resources created in this tutorial, you can remove them with a single command. Before you run the command, there's a next step in this tutorial series that shows you how to make changes to your code and update your app in Azure.

If you're done and want to remove all Azure resources created in this tutorial, delete the resource group with the following command.

az group delete --name aca-demo

Tip

Having issues? Let us know on GitHub by opening an issue in the Azure Container Apps repo.

Next steps

Next, continue on to learn how to update the container app you created.