Compartir a través de


Definir su aplicación de varios contenedores con docker-compose.yml

Sugerencia

Este contenido es un extracto del libro electrónico, ".NET Microservices Architecture for Containerized .NET Applications" (Arquitectura de microservicios de .NET para aplicaciones de .NET contenedorizadas), disponible en Documentación de .NET o como un PDF descargable y gratuito que se puede leer sin conexión.

Miniatura de la portada del libro electrónico 'Arquitectura de microservicios de .NET para aplicaciones .NET contenedorizadas'.

En esta guía, el archivo docker-compose.yml se introdujo en la sección Paso 4. Defina los servicios en docker-compose.yml al compilar una aplicación de Docker de varios contenedores. Sin embargo, hay maneras adicionales de usar los archivos docker-compose que merecen la pena explorar con más detalle.

Por ejemplo, puede describir explícitamente cómo desea implementar la aplicación de varios contenedores en el archivo docker-compose.yml. Opcionalmente, también puede describir cómo va a compilar las imágenes personalizadas de Docker. (Las imágenes personalizadas de Docker también se pueden compilar con la CLI de Docker).

Básicamente, se define cada uno de los contenedores que desea implementar más determinadas características para cada implementación de contenedor. Una vez que tenga un archivo de descripción de implementación de varios contenedores, puede implementar toda la solución en una sola acción orquestada por el comando de la CLI docker-compose up , o bien puede implementarla de forma transparente desde Visual Studio. De lo contrario, tendría que usar la CLI de Docker para implementar contenedor por contenedor en varios pasos mediante el comando docker run desde la línea de comandos. Por lo tanto, cada servicio definido en docker-compose.yml debe especificar exactamente una imagen o compilación. Otras claves son opcionales y son análogas a sus docker run homólogos de línea de comandos.

El siguiente código YAML es la definición de un archivo global pero único docker-compose.yml posible para el ejemplo eShopOnContainers. Este código no es el archivo docker-compose real de eShopOnContainers. En su lugar, es una versión simplificada y consolidada en un solo archivo, que no es la mejor manera de trabajar con archivos docker-compose, como se explicará más adelante.

version: '3.4'

services:
  webmvc:
    image: eshop/webmvc
    environment:
      - CatalogUrl=http://catalog-api
      - OrderingUrl=http://ordering-api
      - BasketUrl=http://basket-api
    ports:
      - "5100:80"
    depends_on:
      - catalog-api
      - ordering-api
      - basket-api

  catalog-api:
    image: eshop/catalog-api
    environment:
      - ConnectionString=Server=sqldata;Initial Catalog=CatalogData;User Id=sa;Password=[PLACEHOLDER]
    expose:
      - "80"
    ports:
      - "5101:80"
    #extra hosts can be used for standalone SQL Server or services at the dev PC
    extra_hosts:
      - "CESARDLSURFBOOK:10.0.75.1"
    depends_on:
      - sqldata

  ordering-api:
    image: eshop/ordering-api
    environment:
      - ConnectionString=Server=sqldata;Database=Services.OrderingDb;User Id=sa;Password=[PLACEHOLDER]
    ports:
      - "5102:80"
    #extra hosts can be used for standalone SQL Server or services at the dev PC
    extra_hosts:
      - "CESARDLSURFBOOK:10.0.75.1"
    depends_on:
      - sqldata

  basket-api:
    image: eshop/basket-api
    environment:
      - ConnectionString=sqldata
    ports:
      - "5103:80"
    depends_on:
      - sqldata

  sqldata:
    environment:
      - SA_PASSWORD=[PLACEHOLDER]
      - ACCEPT_EULA=Y
    ports:
      - "5434:1433"

  basketdata:
    image: redis

La clave raíz de este archivo es services. En esa clave, se definen los servicios que desea implementar y ejecutar al ejecutar el docker-compose up comando o al implementar desde Visual Studio mediante este archivo docker-compose.yml. En este caso, el archivo docker-compose.yml tiene varios servicios definidos, como se describe en la tabla siguiente.

Nombre del servicio Descripción
webmvc Contenedor que incluye la aplicación ASP.NET Core MVC que consume los microservicios del lado servidor de C#
catalog-api Contenedor que incluye el microservicio Catalog ASP.NET Core Web API
ordering-api Contenedor que incluye el microservicio Ordering ASP.NET Core Web API
sqldata Contenedor que ejecuta SQL Server para Linux, que contiene las bases de datos de microservicios
basket-api Contenedor con el microservicio Basket ASP.NET Core Web API
basketdata Contenedor que ejecuta el servicio de caché de REDIS, con la base de datos de cesta como caché de REDIS

Un contenedor de API de servicio web simple

Si nos centramos en un único contenedor, el microservicio de contenedor catalog-api tiene una definición sencilla:

  catalog-api:
    image: eshop/catalog-api
    environment:
      - ConnectionString=Server=sqldata;Initial Catalog=CatalogData;User Id=sa;Password=[PLACEHOLDER]
    expose:
      - "80"
    ports:
      - "5101:80"
    #extra hosts can be used for standalone SQL Server or services at the dev PC
    extra_hosts:
      - "CESARDLSURFBOOK:10.0.75.1"
    depends_on:
      - sqldata

Este servicio en contenedor tiene la siguiente configuración básica:

  • Se basa en la imagen personalizada de eshop/catalog-api . Por simplicidad, no hay ninguna compilación: configuración de clave en el archivo. Esto significa que la imagen debe haberse compilado previamente (con la compilación de Docker) o se ha descargado (con el comando docker pull) desde cualquier registro de Docker.

  • Define una variable de entorno denominada ConnectionString con la cadena de conexión que Entity Framework usará para acceder a la instancia de SQL Server que contiene el modelo de datos de catálogo. En este caso, el mismo contenedor de SQL Server contiene varias bases de datos. Por lo tanto, necesita menos memoria en la máquina de desarrollo para Docker. Sin embargo, también puede implementar un contenedor de SQL Server para cada base de datos de microservicios.

  • El nombre de SQL Server es sqldata, que es el mismo nombre que se usa para el contenedor que ejecuta la instancia de SQL Server para Linux. Esto es conveniente; poder usar esta resolución de nombres (interna para el host de Docker) resolverá la dirección de red, por lo que no es necesario conocer la dirección IP interna de los contenedores a los que accede desde otros contenedores.

Dado que la cadena de conexión se define mediante una variable de entorno, puede establecer esa variable a través de un mecanismo diferente y en otro momento. Por ejemplo, puede establecer una cadena de conexión diferente al implementar en producción en los hosts finales o establecerla desde las canalizaciones de CI/CD en Azure DevOps Services o en su sistema de DevOps de su preferencia.

  • Expone el puerto 80 para el acceso interno al servicio catalog-api dentro del host de Docker. El host es actualmente una máquina virtual Linux porque se basa en una imagen de Docker para Linux, pero puede configurar el contenedor para que se ejecute en una imagen de Windows en su lugar.

  • Reenvía el puerto expuesto 80 en el contenedor al puerto 5101 en la máquina host de Docker (la máquina virtual Linux).

  • Vincula el servicio web al servicio sqldata (la instancia de SQL Server para la base de datos linux que se ejecuta en un contenedor). Al especificar esta dependencia, el contenedor catalog-api no se iniciará hasta que el contenedor sqldata ya se haya iniciado; Este aspecto es importante porque catalog-api debe tener primero en funcionamiento la base de datos de SQL Server. Sin embargo, este tipo de dependencia de contenedor no es suficiente en muchos casos, ya que Docker solo comprueba en el nivel de contenedor. A veces, es posible que el servicio (en este caso, SQL Server) todavía no esté listo, por lo que es aconsejable implementar la lógica de reintento con retroceso exponencial en los microservicios de cliente. De este modo, si un contenedor de dependencias no está listo durante un breve tiempo, la aplicación seguirá siendo resistente.

  • Está configurado para permitir el acceso a servidores externos: la configuración de extra_hosts permite acceder a servidores externos o máquinas fuera del host de Docker (es decir, fuera de la máquina virtual Linux predeterminada, que es un host de Docker de desarrollo), como una instancia local de SQL Server en el equipo de desarrollo.

También hay otras configuraciones más avanzadas docker-compose.yml que analizaremos en las secciones siguientes.

Uso de archivos docker-compose para tener como destino varios entornos

Los docker-compose.*.yml archivos son archivos de definición y se pueden usar en varias infraestructuras que entienden ese formato. La herramienta más sencilla es el comando docker-compose.

Por lo tanto, mediante el comando docker-compose puede tener como destino los siguientes escenarios principales.

Entornos de desarrollo

Al desarrollar aplicaciones, es importante poder ejecutar una aplicación en un entorno de desarrollo aislado. Puede usar el comando de la CLI de docker-compose para crear ese entorno o Visual Studio, que usa docker-compose en segundo plano.

El archivo docker-compose.yml permite configurar y documentar todas las dependencias de servicio de la aplicación (otros servicios, caché, bases de datos, colas, etc.). Con el comando de la CLI docker-compose, puede crear e iniciar uno o varios contenedores para cada dependencia con un solo comando (docker-compose up).

Los archivos docker-compose.yml son archivos de configuración interpretados por el motor de Docker, pero también sirven como archivos de documentación convenientes sobre la composición de la aplicación de varios contenedores.

Entornos de prueba

Una parte importante de cualquier proceso de implementación continua (CD) o integración continua (CI) son las pruebas unitarias y las pruebas de integración. Estas pruebas automatizadas requieren un entorno aislado para que no se vean afectados por los usuarios ni por ningún otro cambio en los datos de la aplicación.

Con Docker Compose puede crear y destruir ese entorno aislado de un modo muy sencillo ejecutando unos scripts o comandos en el símbolo del sistema, como los comandos siguientes:

docker-compose -f docker-compose.yml -f docker-compose-test.override.yml up -d
./run_unit_tests
docker-compose -f docker-compose.yml -f docker-compose-test.override.yml down

Implementaciones de producción

También puede usar Compose para implementar en un motor remoto de Docker. Un caso típico es implementar en una única instancia de host de Docker.

Si usa cualquier otro orquestador (por ejemplo, Azure Service Fabric o Kubernetes), es posible que tenga que agregar opciones de configuración de configuración y metadatos como las de docker-compose.yml, pero en el formato requerido por el otro orquestador.

En cualquier caso, docker-compose es un formato práctico de herramientas y metadatos para los flujos de trabajo de desarrollo, pruebas y producción, aunque el flujo de trabajo de producción puede variar en el orquestador que está usando.

Uso de varios archivos docker-compose para controlar varios entornos

Al fijar como objetivo entornos diferentes, debe usar varios archivos compose. Este enfoque le permite crear varias variantes de configuración en función del entorno.

Invalidar el archivo base docker-compose

Puede usar un solo archivo docker-compose.yml como en los ejemplos simplificados que se muestran en las secciones anteriores. Sin embargo, no se recomienda para la mayoría de las aplicaciones.

De forma predeterminada, Compose lee dos archivos, un docker-compose.yml y un archivo de docker-compose.override.yml opcional. Como se muestra en la figura 6-11, al usar Visual Studio y habilitar la compatibilidad con Docker, Visual Studio también crea un archivo docker-compose.vs.debug.g.yml adicional para depurar la aplicación, puede echar un vistazo a este archivo en la carpeta obj\Docker\ en la carpeta de la solución principal.

Archivos de un proyecto de Docker Compose.

Figura 6-11. archivos "docker-compose" en Visual Studio 2019

Estructura del archivo de proyecto docker-compose:

  • .dockerignore : se usa para pasar por alto los archivos
  • docker-compose.yml : se usa para componer microservicios
  • docker-compose.override.yml : se usa para configurar el entorno de microservicios

Puede editar los archivos docker-compose con cualquier editor, como Visual Studio Code o Sublime, y ejecutar la aplicación con el comando docker-compose up.

Por convención, el archivo docker-compose.yml contiene la configuración base y otras opciones estáticas. Esto significa que la configuración del servicio no debe cambiar en función del entorno de implementación que tenga como destino.

El archivo docker-compose.override.yml, como sugiere su nombre, contiene opciones de configuración que invalidan la configuración base, como la configuración que depende del entorno de implementación. También puede tener varios archivos de invalidación con nombres diferentes. Los archivos de sobrescritura suelen contener información adicional necesaria para la aplicación, pero que es específica de un entorno o de una implementación.

Fijar como objetivo varios entornos

Un caso de uso típico es cuando se definen varios archivos de composición para que pueda apuntar a varios entornos, como producción, preproducción, integración continua o desarrollo. Para respaldar estas diferencias, puede dividir la configuración de Compose en varios archivos, como se muestra en la figura 6-12.

Diagrama de tres archivos docker-compose establecidos para invalidar el archivo base.

Figura 6-12. Varios archivos docker-compose reemplazan valores en el archivo base docker-compose.yml

Puede combinar varios archivos docker-compose*.yml para controlar distintos entornos. Comienza con el archivo docker-compose.yml base. Este archivo base contiene las opciones de configuración base o estática que no cambian en función del entorno. Por ejemplo, la aplicación eShopOnContainers tiene el siguiente archivo docker-compose.yml (simplificado con menos servicios) como archivo base.

#docker-compose.yml (Base)
version: '3.4'
services:
  basket-api:
    image: eshop/basket-api:${TAG:-latest}
    build:
      context: .
      dockerfile: src/Services/Basket/Basket.API/Dockerfile
    depends_on:
      - basketdata
      - identity-api
      - rabbitmq

  catalog-api:
    image: eshop/catalog-api:${TAG:-latest}
    build:
      context: .
      dockerfile: src/Services/Catalog/Catalog.API/Dockerfile
    depends_on:
      - sqldata
      - rabbitmq

  marketing-api:
    image: eshop/marketing-api:${TAG:-latest}
    build:
      context: .
      dockerfile: src/Services/Marketing/Marketing.API/Dockerfile
    depends_on:
      - sqldata
      - nosqldata
      - identity-api
      - rabbitmq

  webmvc:
    image: eshop/webmvc:${TAG:-latest}
    build:
      context: .
      dockerfile: src/Web/WebMVC/Dockerfile
    depends_on:
      - catalog-api
      - ordering-api
      - identity-api
      - basket-api
      - marketing-api

  sqldata:
    image: mcr.microsoft.com/mssql/server:2019-latest

  nosqldata:
    image: mongo

  basketdata:
    image: redis

  rabbitmq:
    image: rabbitmq:3-management

Los valores del archivo docker-compose.yml base no deben cambiar debido a distintos entornos de implementación de destino.

Si se centra en la definición del servicio webmvc, por ejemplo, puede ver cómo esa información es mucho igual independientemente del entorno al que se dirija. Tiene la siguiente información:

  • Nombre del servicio: webmvc.

  • Imagen personalizada del contenedor: eshop/webmvc.

  • Comando para compilar la imagen personalizada de Docker, que indica qué Dockerfile se va a usar.

  • Dependencias de otros servicios, por lo que este contenedor no se inicia hasta que se hayan iniciado los otros contenedores de servicios dependientes.

Puede tener configuración adicional, pero el punto importante es que en el archivo base docker-compose.yml, solo quiere establecer la información que es común entre entornos. A continuación, en el archivo docker-compose.override.yml o archivos similares para producción o preproducción, debe colocar la configuración específica para cada entorno.

Normalmente, el docker-compose.override.yml se usa para el entorno de desarrollo, como en el ejemplo siguiente de eShopOnContainers:

#docker-compose.override.yml (Extended config for DEVELOPMENT env.)
version: '3.4'

services:
# Simplified number of services here:

  basket-api:
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://0.0.0.0:80
      - ConnectionString=${ESHOP_AZURE_REDIS_BASKET_DB:-basketdata}
      - identityUrl=http://identity-api
      - IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105
      - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
      - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME}
      - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD}
      - AzureServiceBusEnabled=False
      - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
      - OrchestratorType=${ORCHESTRATOR_TYPE}
      - UseLoadTest=${USE_LOADTEST:-False}

    ports:
      - "5103:80"

  catalog-api:
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://0.0.0.0:80
      - ConnectionString=${ESHOP_AZURE_CATALOG_DB:-Server=sqldata;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=[PLACEHOLDER]}
      - PicBaseUrl=${ESHOP_AZURE_STORAGE_CATALOG_URL:-http://host.docker.internal:5202/api/v1/catalog/items/[0]/pic/}
      - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
      - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME}
      - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD}
      - AzureStorageAccountName=${ESHOP_AZURE_STORAGE_CATALOG_NAME}
      - AzureStorageAccountKey=${ESHOP_AZURE_STORAGE_CATALOG_KEY}
      - UseCustomizationData=True
      - AzureServiceBusEnabled=False
      - AzureStorageEnabled=False
      - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
      - OrchestratorType=${ORCHESTRATOR_TYPE}
    ports:
      - "5101:80"

  marketing-api:
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://0.0.0.0:80
      - ConnectionString=${ESHOP_AZURE_MARKETING_DB:-Server=sqldata;Database=Microsoft.eShopOnContainers.Services.MarketingDb;User Id=sa;Password=[PLACEHOLDER]}
      - MongoConnectionString=${ESHOP_AZURE_COSMOSDB:-mongodb://nosqldata}
      - MongoDatabase=MarketingDb
      - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
      - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME}
      - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD}
      - identityUrl=http://identity-api
      - IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105
      - CampaignDetailFunctionUri=${ESHOP_AZUREFUNC_CAMPAIGN_DETAILS_URI}
      - PicBaseUrl=${ESHOP_AZURE_STORAGE_MARKETING_URL:-http://host.docker.internal:5110/api/v1/campaigns/[0]/pic/}
      - AzureStorageAccountName=${ESHOP_AZURE_STORAGE_MARKETING_NAME}
      - AzureStorageAccountKey=${ESHOP_AZURE_STORAGE_MARKETING_KEY}
      - AzureServiceBusEnabled=False
      - AzureStorageEnabled=False
      - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
      - OrchestratorType=${ORCHESTRATOR_TYPE}
      - UseLoadTest=${USE_LOADTEST:-False}
    ports:
      - "5110:80"

  webmvc:
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://0.0.0.0:80
      - PurchaseUrl=http://webshoppingapigw
      - IdentityUrl=http://10.0.75.1:5105
      - MarketingUrl=http://webmarketingapigw
      - CatalogUrlHC=http://catalog-api/hc
      - OrderingUrlHC=http://ordering-api/hc
      - IdentityUrlHC=http://identity-api/hc
      - BasketUrlHC=http://basket-api/hc
      - MarketingUrlHC=http://marketing-api/hc
      - PaymentUrlHC=http://payment-api/hc
      - SignalrHubUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5202
      - UseCustomizationData=True
      - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
      - OrchestratorType=${ORCHESTRATOR_TYPE}
      - UseLoadTest=${USE_LOADTEST:-False}
    ports:
      - "5100:80"
  sqldata:
    environment:
      - SA_PASSWORD=[PLACEHOLDER]
      - ACCEPT_EULA=Y
    ports:
      - "5433:1433"
  nosqldata:
    ports:
      - "27017:27017"
  basketdata:
    ports:
      - "6379:6379"
  rabbitmq:
    ports:
      - "15672:15672"
      - "5672:5672"

En este ejemplo, la configuración de invalidación de desarrollo expone algunos puertos al host, define variables de entorno con direcciones URL de redireccionamiento y especifica cadenas de conexión para el entorno de desarrollo. Esta configuración es solo para el entorno de desarrollo.

Cuando se ejecuta docker-compose up (o se inicia desde Visual Studio), el comando lee automáticamente las sobreescrituras como si ambos archivos se combinaran.

Supongamos que desea otro archivo compose para el entorno de producción, con valores de configuración, puertos o cadenas de conexión diferentes. Puede crear otro archivo de anulación, como el archivo llamado docker-compose.prod.yml con diferentes configuraciones y variables de entorno. Ese archivo puede almacenarse en un repositorio de Git diferente o administrado y protegido por un equipo diferente.

Cómo efectuar una implementación con un archivo de invalidación específico

Para usar varios archivos de invalidación o un archivo de invalidación con un nombre diferente, puede usar la opción -f con el comando docker-compose y especificar los archivos. Compose combina archivos en el orden en que se especifican en la línea de comandos. En el ejemplo siguiente se muestra cómo efectuar la implementación con archivos de invalidación.

docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d

Uso de variables de entorno en archivos docker-compose

Es conveniente, especialmente en entornos de producción, poder obtener información de configuración de variables de entorno, como se ha mostrado en los ejemplos anteriores. Puede hacer referencia a una variable de entorno en los archivos docker-compose mediante la sintaxis ${MY_VAR}. La siguiente línea de un archivo docker-compose.prod.yml muestra cómo hacer referencia al valor de una variable de entorno.

IdentityUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105

Las variables de entorno se crean e inicializan de diferentes maneras, en función del entorno host (Linux, Windows, clúster en la nube, etc.). Sin embargo, un enfoque práctico es usar un archivo .env. Los archivos docker-compose admiten la declaración de variables de entorno predeterminadas en el archivo .env. Estos valores para las variables de entorno son los valores predeterminados. Sin embargo, los valores que podría haber definido en cada uno de los entornos, en el sistema operativo host o en las variables de entorno del clúster, pueden invalidar los valores predeterminados. Este archivo .env se coloca en la carpeta desde la que se ejecuta el comando docker-compose.

En el ejemplo siguiente se muestra un archivo .env como el archivo .env para la aplicación eShopOnContainers.

# .env file

ESHOP_EXTERNAL_DNS_NAME_OR_IP=host.docker.internal

ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP=10.121.122.92

Docker-compose espera que cada línea de un archivo .env esté en el formato <variable>=<value>.

Los valores establecidos en el entorno en tiempo de ejecución siempre invalidan los valores definidos dentro del archivo .env. De forma similar, los valores pasados a través de argumentos de línea de comandos también invalidan los valores predeterminados establecidos en el archivo .env.

Recursos adicionales

Creación de imágenes de Docker de ASP.NET Core optimizadas

Si está explorando Docker y .NET en fuentes en Internet, encontrará Dockerfiles que muestran la simplicidad de crear una imagen de Docker copiando tu código fuente en un contenedor. Estos ejemplos sugieren que, mediante una configuración sencilla, puede tener una imagen de Docker con el entorno empaquetado con la aplicación. En el ejemplo siguiente se muestra un Dockerfile simple de este tipo.

FROM mcr.microsoft.com/dotnet/sdk:8.0
WORKDIR /app
ENV ASPNETCORE_URLS http://+:80
EXPOSE 80
COPY . .
RUN dotnet restore
ENTRYPOINT ["dotnet", "run"]

Un Dockerfile como este funcionará. Sin embargo, puede optimizar sustancialmente las imágenes, especialmente las imágenes de producción.

En el modelo de microservicios y contenedores están iniciando contenedores constantemente. La forma típica de usar contenedores no reinicia un contenedor en reposo, ya que el contenedor es desechable. Los orquestadores (como Kubernetes y Azure Service Fabric) crean nuevas instancias de imágenes. Esto significa que necesitarás optimizar al precompilar la aplicación en su construcción, así que el proceso de creación de instancias será más rápido. Cuando se inicia el contenedor, tendría que estar preparado para ejecutarse. No restaure ni compile durante la ejecución mediante los comandos dotnet restore y dotnet build de la CLI, como en las entradas de blog sobre .NET y Docker.

El equipo de .NET ha estado realizando un trabajo importante para que .NET y ASP.NET Core sea un marco optimizado para contenedores. No solo es .NET un marco ligero con una superficie de memoria pequeña; el equipo se ha centrado en las imágenes de Docker optimizadas para tres escenarios principales y los ha publicado en el registro de Docker Hub en dotnet/, a partir de la versión 2.1:

  • Desarrollo: la prioridad es la capacidad de iterar y depurar rápidamente los cambios, y donde el tamaño es secundario.
  • Compilación: la prioridad es compilar la aplicación y la imagen incluye archivos binarios y otras dependencias para optimizar los archivos binarios.
  • Producción: el enfoque es la implementación rápida y el inicio de contenedores, por lo que estas imágenes se limitan a los archivos binarios y el contenido necesario para ejecutar la aplicación.

El equipo de .NET proporciona algunas variantes básicas en dotnet/, por ejemplo:

  • sdk: para escenarios de desarrollo y compilación
  • aspnet: para escenarios de producción de ASP.NET
  • runtime: para escenarios de producción de .NET
  • runtime-deps: para escenarios de producción de aplicaciones independientes

Para un inicio más rápido, las imágenes en tiempo de ejecución también configuran automáticamente las direcciones aspnetcore_url en el puerto 80 y usan Ngen para crear una caché de imágenes nativa de ensamblados.

Recursos adicionales