Tutorial: Create a multi-container app with Docker Compose

In this tutorial, you'll learn how to manage more than one container and communicate between them when using Container Tools in Visual Studio. Managing multiple containers requires container orchestration and requires an orchestrator such as Docker Compose, Kubernetes, or Service Fabric. Here, we'll use Docker Compose. Docker Compose is great for local debugging and testing in the course of the development cycle.

Prerequisites

Create a Web Application project

In Visual Studio, create an ASP.NET Core Web Application project, named WebFrontEnd. Select Web Application to create a web application with Razor pages.

Do not select Enable Docker Support. You'll add Docker support later.

Screenshot of creating the web project

Screenshot of creating the web project

Do not select Enable Docker Support. You'll add Docker support later.

Screenshot of creating the web project

Create a Web API project

Add a project to the same solution and call it MyWebAPI. Select API as the project type, and clear the checkbox for Configure for HTTPS. In this design, we're only using SSL for communication with the client, not for communication from between containers in the same web application. Only WebFrontEnd needs HTTPS.

Screenshot of creating the Web API project

Screenshot of creating the Web API project

Add code to call the Web API

  1. In the WebFrontEnd project, open the Index.cshtml.cs file, and replace the OnGet method with the following code.

     public async Task OnGet()
     {
        ViewData["Message"] = "Hello from webfrontend";
    
        using (var client = new System.Net.Http.HttpClient())
        {
           // Call *mywebapi*, and display its response in the page
           var request = new System.Net.Http.HttpRequestMessage();
           request.RequestUri = new Uri("http://mywebapi/api/values/1");
           var response = await client.SendAsync(request);
           ViewData["Message"] += " and " + await response.Content.ReadAsStringAsync();
        }
     }
    
  2. In the Index.cshtml file, add a line to display ViewData["Message"] so that the file looks like the following code:

    @page
    @model IndexModel
    @{
        ViewData["Title"] = "Home page";
    }
    
    <div class="text-center">
        <h1 class="display-4">Welcome</h1>
        <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
        <p>@ViewData["Message"]</p>
    </div>
    
  3. Now in the Web API project, add code to the Values controller to customize the message returned by the API for the call you added from webfrontend.

      // GET api/values/5
      [HttpGet("{id}")]
      public ActionResult<string> Get(int id)
      {
          return "webapi (with value " + id + ")";
      }
    
  4. In the WebFrontEnd project, choose Add > Container Orchestrator Support. The Docker Support Options dialog appears.

  5. Choose Docker Compose.

  6. Choose your Target OS, for example, Linux.

    Screenshot of choosing the Target OS

    Visual Studio creates a docker-compose.yml file and a .dockerignore file in the docker-compose node in the solution, and that project shows in boldface font, which shows that it's the startup project.

    Screenshot of Solution Explorer with docker-compose project added

    The docker-compose.yml appears as follows:

    version: '3.4'
    
     services:
       webfrontend:
         image: ${DOCKER_REGISTRY-}webfrontend
         build:
           context: .
           dockerfile: WebFrontEnd/Dockerfile
    

    The .dockerignore file contains file types and extensions that you don't want Docker to include in the container. These files are generally associated with the development environment and source control, not part of the app or service you're developing.

    Look at the Container Tools section of the output pane for details of the commands being run. You can see the command-line tool docker-compose is used to configure and create the runtime containers.

  7. In the Web API project, again right-click on the project node, and choose Add > Container Orchestrator Support. Choose Docker Compose, and then select the same target OS.

    Note

    In this step, Visual Studio will offer to create a Dockerfile. If you do this on a project that already has Docker support, you are prompted whether you want to overwrite the existing Dockerfile. If you've made changes in your Dockerfile that you want to keep, choose no.

    Visual Studio makes some changes to your docker compose YML file. Now both services are included.

    version: '3.4'
    
    services:
      webfrontend:
        image: ${DOCKER_REGISTRY-}webfrontend
        build:
          context: .
          dockerfile: WebFrontEnd/Dockerfile
    
      mywebapi:
        image: ${DOCKER_REGISTRY-}mywebapi
        build:
          context: .
          dockerfile: MyWebAPI/Dockerfile
    
  8. Run the site locally now (F5 or Ctrl+F5) to verify that it works as expected. If everything is configured correctly, you see the message "Hello from webfrontend and webapi (with value 1)."

    The first project that you use when you add container orchestration is set up to be launched when you run or debug. You can configure the launch action in the Project Properties for the docker-compose project. On the docker-compose project node, right-click to open the context menu, and then choose Properties, or use Alt+Enter. The following screenshot shows the properties you would want for the solution used here. For example, you can change the page that is loaded by customizing the Service URL property.

    Screenshot of docker-compose project properties

    Here's what you see when launched:

    Screenshot of running web app

Next steps

Look at the options for deploying your containers to Azure.

See also

Docker Compose
Container Tools