Поделиться через


Руководство по созданию многоконтейнерного приложения с помощью Docker Compose

В этом руководстве вы узнаете, как управлять несколькими контейнерами и взаимодействовать между ними при использовании средств контейнеров в Visual Studio. Для управления несколькими контейнерами требуется оркестрация контейнеров и оркестратор, например Docker Compose или Service Fabric. Для этих процедур используется Docker Compose. Docker Compose отлично подходит для локальной отладки и тестирования в течение цикла разработки.

Полный пример, который вы создали в этом руководстве, можно найти на сайте GitHub https://github.com/MicrosoftDocs/vs-tutorial-samples в папке docker/ComposeSample.

Необходимые компоненты

  • Docker Desktop
  • Visual Studio 2019 с установленной рабочей нагрузкой Веб-разработка, Средства Azure и (или) Кроссплатформенная разработка .NET.
  • Docker Desktop
  • Visual Studio 2022 с установленной рабочей нагрузкой Веб-разработка, Azure Tools и (или) Кроссплатформенная разработка .NET. Эта установка включает средства разработки .NET 8.

Создание проекта веб-приложения

В Visual Studio создайте проект Веб-приложение ASP.NET Core с именем WebFrontEnd для создания веб-приложения с Razor Pages.

Screenshot showing Create ASP.NET Core Web App project.

Не нажимайте кнопку "Включить поддержку Docker". Вы добавите поддержку Docker позже в процессе.

Screenshot of the Additional information screen when creating a web project. The option to Enable Docker Support is not selected.

Примечание.

В Visual Studio 2022 17.2 и более поздних версий для этого проекта можно использовать Функции Azure.

Screenshot showing Create ASP.NET Core Web App project.

Не нажимайте кнопку "Включить поддержку Docker". Вы добавите поддержку Docker позже в процессе.

Screenshot of the Additional information screen when creating a web project. The option to Enable Docker Support is not selected.

Создание проекта веб-API

Добавьте еще один проект в то же решение и назовите его MyWebAPI. Выберите тип проекта API и снимите флажок Настроить для HTTPS. В данном случае протокол SSL используется только для обмена данными с клиентом, но не для обмена данными между контейнерами в пределах веб-приложения. Только для WebFrontEnd необходим протокол HTTPS, а в коде в примерах предполагается, что флажок снят. Используемые Visual Studio сертификаты разработчика .NET обычно позволяют выполнять запросы к контейнеру извне, а не запросы между контейнерами.

Screenshot of creating the Web API project.

  1. Добавьте еще один проект в то же решение и назовите его WebAPI. Выберите тип проекта API и снимите флажок Настроить для HTTPS. В данном случае протокол SSL используется только для обмена данными с клиентом, но не для обмена данными между контейнерами в пределах веб-приложения. Только для WebFrontEnd необходим протокол HTTPS, а в коде в примерах предполагается, что флажок снят. Используемые Visual Studio сертификаты разработчика .NET обычно позволяют выполнять запросы к контейнеру извне, а не запросы между контейнерами.

    Screenshot of creating the Web API project.

  2. Добавьте поддержку Redis Cache. Добавьте пакет NuGet Microsoft.Extensions.Caching.StackExchangeRedis (не StackExchange.Redis). В файле Program.cs добавьте следующие строки сразу перед var app = builder.Build():

    builder.Services.AddStackExchangeRedisCache(options =>
       {
          options.Configuration = "redis:6379"; // redis is the container name of the redis service. 6379 is the default port
          options.InstanceName = "SampleInstance";
       });
    
  3. Добавьте директивы using в файл Program.cs для Microsoft.Extensions.Caching.Distributed и Microsoft.Extensions.Caching.StackExchangeRedis.

    using Microsoft.Extensions.Caching.Distributed;
    using Microsoft.Extensions.Caching.StackExchangeRedis;
    
  4. В проекте веб-API удалите существующие файлы WeatherForecast.cs и Controllers/WeatherForecastController.cs, а затем в папке Controllers добавьте файл CounterController.cs со следующим содержимым:

    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Caching.Distributed;
    using StackExchange.Redis;
    
    namespace WebApi.Controllers
    {
        [ApiController]
        [Route("[controller]")]
        public class CounterController : ControllerBase
        {
            private readonly ILogger<CounterController> _logger;
            private readonly IDistributedCache _cache;
    
            public CounterController(ILogger<CounterController> logger, IDistributedCache cache)
            {
                _logger = logger;
                _cache = cache;
            }
    
            [HttpGet(Name = "GetCounter")]
            public string Get()
            {
                string key = "Counter";
                string? result = null;
                try
                {
                    var counterStr = _cache.GetString(key);
                    if (int.TryParse(counterStr, out int counter))
                    {
                        counter++;
                    }
                    else
                    {
                        counter = 0;
                    }
                    result = counter.ToString();
                    _cache.SetString(key, result);
                }
                catch(RedisConnectionException)
                {
                    result = "Redis cache is not found.";
                }
                return result;
            }
        }
    }
    

    Служба увеличивает значение счетчика при каждом доступе к странице и сохраняет счетчик в Redis Cache.

Добавление кода для вызова веб-API

  1. В проекте WebFrontEnd откройте файл Index.cshtml.cs и замените текст метода OnGet следующим кодом.

     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/WeatherForecast");
           // request.RequestUri = new Uri("http://mywebapi/api/values/1"); // For ASP.NET 2.x, comment out previous line and uncomment this line.
           var response = await client.SendAsync(request);
           ViewData["Message"] += " and " + await response.Content.ReadAsStringAsync();
        }
     }
    

    Примечание.

    В реальном коде не следует удалять HttpClient после каждого запроса. Рекомендации см. в разделе Использование HttpClientFactory для реализации устойчивых HTTP-запросов.

  2. В файл Index.cshtml добавьте строку для отображения ViewData["Message"], чтобы файл выглядел примерно так:

    @page
    @model IndexModel
    @{
       ViewData["Title"] = "Home page";
    }
    
    <div class="text-center">
       <h1 class="display-4">Welcome</h1>
       <p>Learn about <a href="/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
       <p>@ViewData["Message"]</p>
    </div>
    
  3. (Только для ASP.NET 2.x) Теперь перейдите в проект веб-API и добавьте в контроллер Values код с пользовательским сообщением API для вызова, который вы добавили из webfrontend.

    // GET api/values/5
    [HttpGet("{id}")]
    public ActionResult<string> Get(int id)
    {
       return "webapi (with value " + id + ")";
    }
    

    Примечание.

    В .NET Core 3.1 и более поздних версий можно использовать предоставленный API WeatherForecast, а не этот дополнительный код. Однако необходимо закомментировать вызов UseHttpsRedirection в проекте веб-API, так как код использует HTTP для вызова, а не HTTPS.

          //app.UseHttpsRedirection();
    

Добавление поддержки Docker Compose

  1. В проекте WebFrontEnd выберите Добавить > Container Orchestrator Support (Поддержка оркестратора контейнеров). Появится диалоговое окно Варианты поддержки Docker.

  2. Выберите Docker Compose.

  3. Выберите целевую ОС, например Linux.

    Screenshot of choosing the Target OS.

    Visual Studio создаст файлы docker-compose.yml и DOCKERIGNORE в узле docker-compose решения. Этот проект выделен полужирным шрифтом, что значит, что это запускаемый проект.

    Screenshot of Solution Explorer with docker-compose project added.

    Файл docker-compose.yml выглядит так:

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

    В version первой строке указана версия файла Docker Compose. Обычно не следует изменять его, так как он используется средствами для понимания того, как интерпретировать файл.

    Файл DOCKERIGNORE содержит типы и расширения имен файлов, которые средству Docker не нужно включать в контейнер. Обычно эти файлы связаны со средой разработки и системой управления версиями, а не с самим разрабатываемым приложением или службой.

    Сведения о выполняемых командах приводятся в разделе Инструменты для контейнера области выходных данных. Как вы можете видеть, программа командной строки docker-compose используется для настройки и создания контейнеров среды выполнения.

  4. В проекте веб-API еще раз щелкните узел проекта правой кнопкой мыши и выберите пункт Добавить>Container Orchestrator Support (Поддержка оркестратора контейнеров). Выберите Docker Compose, а затем выберите ту же целевую ОС.

    Примечание.

    На этом этапе Visual Studio предложит создать Dockerfile. Если сделать это для проекта, который уже поддерживает Docker, появится запрос на перезапись существующего файла Dockerfile. Если вы внесли изменения в Dockerfile, которые хотите сохранить, выберите "Нет".

    Visual Studio вносит ряд изменений в YML-файл docker-compose. Теперь включены обе службы.

    version: '3.4'
    
    services:
      webfrontend:
        image: ${DOCKER_REGISTRY-}webfrontend
        build:
          context: .
          dockerfile: WebFrontEnd/Dockerfile
    
      mywebapi:
        image: ${DOCKER_REGISTRY-}mywebapi
        build:
          context: .
          dockerfile: MyWebAPI/Dockerfile
    
  5. Первый проект, в котором вы добавляете оркестрацию контейнеров, настраивается запускаемым при выполнении или отладке. Настроить действие запуска для проекта docker-compose можно в свойствах проекта. Щелкните правой кнопкой мыши узел проекта docker-compose и выберите в контекстном меню пункт Свойства или нажмите клавиши ALT+ВВОД. На снимке экрана ниже показаны свойства, которые требуются для решения в этом руководстве. Например, можно изменить загружаемую страницу, настроив свойство URL-адрес службы.

    Screenshot of docker-compose project properties.

    Вот что вы видите при запуске (версия .NET Core 2.x):

    Screenshot of running web app.

    В веб-приложении для .NET 3.1 отображаются данные о погоде в формате JSON.

  6. Теперь предположим, что вам нужно только подключить отладчик к WebFrontEnd, а не проект веб-API. В строке меню вы можете выбрать раскрывающийся список рядом с кнопкой "Пуск", чтобы открыть меню параметров отладки. Выберите в нем Управление параметрами запуска Docker Compose.

    Screenshot of Debug Manage Compose Settings menu item.

    Откроется диалоговое окно Управление параметрами запуска Docker Compose. В этом диалоговом окне можно контролировать, какое подмножество служб запускается во время сеанса отладки, которое запускается с присоединенным отладчиком или без нее, а также службу запуска и URL-адрес. См. Запуск подмножества служб Compose.

    Screenshot of Manage Docker Compose Launch Settings dialog box.

    Выберите Создать, чтобы создать профиль, и назовите его Debug WebFrontEnd only. Затем задайте для проекта веб-API параметр Запускать без отладки, оставьте для проекта WebFrontEnd параметр запуска с отладкой и нажмите Сохранить.

    Новая конфигурация будет выбрана как конфигурацию по умолчанию при следующем нажатии клавиши F5.

  7. Нажмите клавишу F5, чтобы подтвердить правильную работу.

Поздравляем! Вы запустили приложение Docker Compose с пользовательским профилем Docker Compose.

  1. В проекте WebFrontEnd откройте файл Index.cshtml.cs и замените текст метода OnGet следующим кодом.

    public async Task OnGet()
    {
       using (var client = new System.Net.Http.HttpClient())
       {
          // Call *mywebapi*, and display its response in the page
          var request = new System.Net.Http.HttpRequestMessage();
          // webapi is the container name
          request.RequestUri = new Uri("http://webapi/Counter");
          var response = await client.SendAsync(request);
          string counter = await response.Content.ReadAsStringAsync();
          ViewData["Message"] = $"Counter value from cache :{counter}";
       }
    }
    

    Примечание.

    В реальном коде не следует удалять HttpClient после каждого запроса. Рекомендации см. в разделе Использование HttpClientFactory для реализации устойчивых HTTP-запросов.

  2. В файл Index.cshtml добавьте строку для отображения ViewData["Message"], чтобы файл выглядел примерно так:

    @page
    @model IndexModel
    @{
        ViewData["Title"] = "Home page";
    }
    
    <div class="text-center">
        <h1 class="display-4">Welcome</h1>
        <p>Learn about <a href="/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
        <p>@ViewData["Message"]</p>
    </div>
    

    Этот код отображает значение счетчика, возвращаемого из проекта веб-API.

Добавление поддержки Docker Compose

  1. В проекте WebFrontEnd выберите Добавить > Container Orchestrator Support (Поддержка оркестратора контейнеров). Появится диалоговое окно Варианты поддержки Docker.

  2. Выберите Docker Compose.

  3. Выберите целевую ОС, например Linux.

    Screenshot of choosing the Target OS.

    Visual Studio создаст файлы docker-compose.yml и DOCKERIGNORE в узле docker-compose решения. Этот проект выделен полужирным шрифтом, что значит, что это запускаемый проект.

    Screenshot of Solution Explorer with docker-compose project added.

    Файл docker-compose.yml выглядит так:

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

    В version первой строке указана версия файла Docker Compose. Обычно не следует изменять его, так как он используется средствами для понимания того, как интерпретировать файл.

    Файл DOCKERIGNORE содержит типы и расширения имен файлов, которые средству Docker не нужно включать в контейнер. Обычно эти файлы связаны со средой разработки и системой управления версиями, а не с самим разрабатываемым приложением или службой.

    Сведения о выполняемых командах приводятся в разделе Инструменты для контейнера области выходных данных. Как вы можете видеть, программа командной строки docker-compose используется для настройки и создания контейнеров среды выполнения.

  4. В проекте веб-API еще раз щелкните узел проекта правой кнопкой мыши и выберите пункт Добавить>Container Orchestrator Support (Поддержка оркестратора контейнеров). Выберите Docker Compose, а затем выберите ту же целевую ОС.

    Примечание.

    На этом этапе Visual Studio предложит создать Dockerfile. Если сделать это для проекта, который уже поддерживает Docker, появится запрос на перезапись существующего файла Dockerfile. Если вы внесли изменения в Dockerfile, которые хотите сохранить, выберите "Нет".

    Visual Studio вносит ряд изменений в YML-файл docker-compose. Теперь включены обе службы.

    version: '3.4'
    
    services:
      webfrontend:
        image: ${DOCKER_REGISTRY-}webfrontend
        build:
          context: .
          dockerfile: WebFrontEnd/Dockerfile
    
      mywebapi:
        image: ${DOCKER_REGISTRY-}mywebapi
        build:
          context: .
          dockerfile: MyWebAPI/Dockerfile
    
  5. Добавьте кэш Redis Сache в файл docker.compose.yml:

    redis:
       image: redis
    

    Убедитесь, что отступ находится на том же уровне, что и у двух других служб.

  6. Первый проект, в котором вы добавляете оркестрацию контейнеров, настраивается запускаемым при выполнении или отладке. Настроить действие запуска для проекта docker-compose можно в свойствах проекта. Щелкните правой кнопкой мыши узел проекта docker-compose и выберите в контекстном меню пункт Свойства или нажмите клавиши ALT+ВВОД. Например, можно изменить загружаемую страницу, настроив свойство URL-адрес службы.

    Screenshot of docker-compose project properties.

  7. Нажмите клавишу F5. Вот что вы увидите при запуске:

    Screenshot of running web app.

  8. Контейнеры можно отслеживать с помощью окна "Контейнеры ". Если окно не отображается, используйте поле поиска, нажмите клавиши CTRL K, CTRL++O или нажмите клавиши CTRL+Q. В разделе "Поиск компонентов" найдите containersи выберите "Просмотреть>другие контейнеры Windows>" в списке.

  9. Разверните узел "Контейнеры решений" и выберите узел для проекта Docker Compose, чтобы просмотреть объединенные журналы на вкладке "Журналы" этого окна.

    Screenshot showing viewing the Logs tab in the Containers window.

    Вы также можете выбрать узел для отдельного контейнера для просмотра журналов, переменных среды, файловой системы и других сведений.

Настройка профилей запуска

  1. Это решение использует Redis Cache, но не эффективно перестраивать контейнер Redis Cache при каждом запуске сеанса отладки. Чтобы избежать этой ситуации, можно настроить несколько профилей запуска. Создайте один профиль для запуска кэша Redis. Создайте второй профиль, чтобы запустить другие службы. Второй профиль может использовать контейнер кэша Redis, который уже запущен. В строке меню можно использовать раскрывающийся список рядом с кнопкой "Пуск", чтобы открыть меню с параметрами отладки. Выберите "Управление Docker Compose Launch Параметры".

    Screenshot of Debug Manage Compose Settings menu item.

    Откроется диалоговое окно Управление параметрами запуска Docker Compose. В этом диалоговом окне можно контролировать, какое подмножество служб запускается во время сеанса отладки, которое запускается с присоединенным отладчиком или без нее, а также службу запуска и URL-адрес. См. Запуск подмножества служб Compose.

    Screenshot of Manage Docker Compose Launch Settings dialog box.

    Выберите Создать, чтобы создать профиль, и назовите его Start Redis. Затем установите для контейнера Redis значение Запуск без отладки, для других оставьте значение Не запускать и нажмите кнопку Сохранить.

    Screenshot showing creating the Redis profile that starts the Redis service only.

    Затем создайте еще один профиль Start My Services, который не запускает Redis, но запускает две другие службы.

    Screenshot showing creating the Services profile that starts the other services.

    (Необязательно.) Создайте третий профиль Start All, чтобы запускать все. Можно также выбрать пункт Запуск без отладки для Redis.

  2. В раскрывающемся списке на главной панели инструментов Visual Studio выберите команду Start Redis (Запустить Redis) и нажмите клавишу F5. Произойдут сборка и запуск контейнера Redis. В окне Контейнеры можно убедиться, что он запущен. Затем выберите Start My Services (Запустить мои службы) в раскрывающемся списке и нажмите клавишу F5, чтобы запустить службы. Теперь можно поддерживать работу контейнера Redis Сache во многих последующих сеансах отладки. При каждом запуске служб эти службы используют один и тот же контейнер кэша Redis.

Поздравляем! Вы запустили приложение Docker Compose с пользовательским профилем Docker Compose.

Следующие шаги

Ознакомьтесь с вариантами развертывания контейнеров в Azure.

См. также

Docker Compose
Инструменты для работы с контейнерами