¿Cómo conectar al servicio de SQL Server desde Docker en Docker?
Estoy intentando construir y ejecutar una aplicación ASP.NET Core y probarla con Newman. Aquí está la tubería que tengo:
services:
- mcr.microsoft.com/mssql/server:2019-CU14-ubuntu-20.04
- docker:19.03.12-dind
variables:
VERSION: "0.0.0"
ACCEPT_EULA: Y
MSSQL_SA_PASSWORD: "***"
DOCKER_TLS_CERTDIR: "/certs"
stages:
- test
postman_tests:
stage: test
tags:
- docker
script:
- docker run -p 5555:80 -v $(pwd)/CatalogService/:/app/ -w /app -e ASPNETCORE_URLS=http://+:80 -e ASPNETCORE_ENVIRONMENT=Development -t mcr.microsoft.com/dotnet/sdk:6.0.100-alpine3.14-amd64 dotnet run --project ./CatalogService.csproj
- sleep 120s
- docker run -v $(pwd)/test:/etc/newman -t postman/newman:alpine run "CatalogService.postman_collection.json" --reporters="cli"
Acabo de empezar hoy a aprender sobre Docker y cómo usarlo con la tubería de Gitlab, por favor háganme saber si tienen una mejor manera de hacerlo.
¿Por qué la aplicación no puede acceder al servicio de mssql? Este es el error que obtengo:
[...]
Status: Downloaded newer image for mcr.microsoft.com/dotnet/sdk:6.0.100-alpine3.14-amd64
Building...
info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
Entity Framework Core 6.0.0 initialized 'CatalogDb' using provider 'Microsoft.EntityFrameworkCore.SqlServer:6.0.0' with options: None
Unhandled exception. Microsoft.Data.SqlClient.SqlException (0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: TCP Provider, error: 35 - An internal exception was caught)
[...]
Y esta es la cadena de conexión que estoy utilizando en el archivo appsettings.json
:
"ConnectionStrings": {
"CatalogDb": "Password=****;Persist Security Info=True;User ID=SA;Database=CatalogDb;Server=mcr.microsoft.com__mssql__server"
},
Si ejecuto la siguiente tubería con la imagen .net sdk
, entonces la aplicación comienza y puede conectarse a la base de datos. Pero de esta manera, ¿no puedo usar newman para probarla? ¿O sí?
build:
stage: build
tags:
- docker
image:
name: mcr.microsoft.com/dotnet/sdk:6.0
entrypoint: [""]
script:
- dotnet build ./CatalogService.csproj --configuration Release --no-self-contained
- dotnet run --project ./CatalogService.csproj
variables:
ErrorActionPreference: stop
Actualización:
Agregué un alias y actualicé la cadena de conexión al servicio, pero aún no se conecta.
services:
- name: mcr.microsoft.com/mssql/server:2019-CU14-ubuntu-20.04
alias: mssql
- docker:19.03.12-dind
Password=*****;Persist Security Info=True;User ID=SA;Database=CatalogDb;Server=mssql
También agregué la variable FF_NETWORK_PER_BUILD
según lo especificado aquí, pero la aplicación aún no se conecta a la base de datos.
postman_tests:
stage: test
tags:
- docker
variables:
FF_NETWORK_PER_BUILD: "true"
script:
- docker run -p 5555:80 -v $(pwd)/CatalogService/:/app/ -w /app -e ASPNETCORE_URLS=http://+:80 -e ASPNETCORE_ENVIRONMENT=Development -t mcr.microsoft.com/dotnet/sdk:6.0.100-alpine3.14-amd64 dotnet run --project ./CatalogService.csproj
- sleep 120s
- docker run -v $(pwd)/test:/etc/newman -t postman/newman:alpine run "CatalogService.postman_collection.json" --reporters="cli"
Actualización con archivo completo .yml:
Esta tubería tiene 3 etapas:
- construir/publicar el origen
- construir la imagen de Docker para probar la aplicación
- probar la aplicación con una base de datos y postman
variables:
DOCKER_TLS_CERTDIR: "/certs"
REGISTRY_TENANT: TTT
REGISTRY_URL: UUU
REGISTRY_NAME: NNN
IMAGE_NAME: image
stages:
- build
- docker
- test
buld_source:
stage: build
tags:
- docker
image: mcr.microsoft.com/dotnet/sdk:6.0
script:
- dotnet clean
- dotnet build /builds/xxx.sln --configuration Release
- dotnet publish /builds/xxx1.csproj --output ./publish/xxx1
- dotnet publish /builds/xxx2.csproj --output ./publish/xxx2
artifacts:
paths:
- ./publish/*
expire_in: 1 hour
variables:
ErrorActionPreference: stop
docker_test_image:
stage: docker
needs: ["buld_source"]
tags:
- docker
variables:
RUNTIME_IMAGE: mcr.microsoft.com/dotnet/aspnet:6.0
DOCKER_DRIVER: overlay2
services:
- docker:20.10.12-dind
script:
# Preparar Dockerfile
- sed -i "s~\$DOCKERIMAGE~$RUNTIME_IMAGE~g" Dockerfile
- sed -i 's/\$ENVIRONMENT/Testing/g' Dockerfile
- sed -i "s/\$ENTRYPOINT/xxx1.dll/g" Dockerfile
- cat Dockerfile
# Procesar Dockerfile
- docker login $REGISTRY_URL -u $REGISTRY_NAME -p $REGISTRY_PASS
- docker build --tag "$REGISTRY_URL/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA" .
- docker push "$REGISTRY_URL/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA"
postman_tests:
stage: test
needs: ["docker_test_image"]
tags:
- docker
services:
- docker:20.10.12-dind
dependencies: []
variables:
DOCKER_DRIVER: overlay2
before_script:
- docker login $REGISTRY_URL -u $REGISTRY_NAME -p $REGISTRY_PASS
script:
- docker network create -d bridge network
- docker run --name mcr.microsoft.commssqlserver --network network -p 1433:1433 -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=ppp" -d mcr.microsoft.com/mssql/server:2019-Latest
- sleep 30s
- docker logs mcr.microsoft.commssqlserver
- docker run --network network --name xxx1 -p 5535:5535 -d $REGISTRY_URL/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA
- sleep 30s
- docker logs xxx1
- docker run --network network -v $(pwd)/test:/etc/newman -t postman/newman:alpine run "xxx1.postman_collection.json" --reporters="cli"
- sleep 5s
- docker rmi -f $REGISTRY_URL/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA
davy.ai
Construyendo y ejecutando una aplicación ASP.NET Core con Docker y pruebas de Newman
Este es un pipeline de GitLab que construye y ejecuta una aplicación ASP.NET Core y la prueba con Newman. El pipeline tiene tres etapas:
Aquí está el código del pipeline:
El pipeline utiliza Docker para construir, ejecutar y probar la aplicación. La etapa
build_source
utiliza la imagen .NET SDK para construir y publicar el código fuente. La etapadocker_test_image
construye una imagen de Docker a partir del código fuente y la ejecuta. La etapapostman_tests
crea una red, inicia un contenedor SQL Server, inicia el contenedor de la aplicación y ejecuta la prueba de Postman contra la aplicación.En la etapa
build_source
, definimos la imagen y el script utilizados para construir y publicar el código fuente. Ejecutamos los comandosdotnet
para limpiar, construir y publicar el código. Configuramos las rutas de artefactos para la salida publicada y establecemos un tiempo de caducidad.En la etapa
docker_test_image
, preparamos el archivo Dockerfile y construimos la imagen utilizando el comandodocker
. Empujamos la imagen a un registro y establecemos el nombre de la imagen en el SHA corto de confirmación.En la etapa
postman_tests
, definimos una red e iniciamos los contenedores SQL Server y de la aplicación. Ejecutamos las pruebas de Postman contra el contenedor de la aplicación y limpiamos la imagen después de la prueba. Utilizamos el comando$(pwd)
para obtener el directorio de trabajo actual para la ruta de la prueba de Postman.El contenedor de la aplicación se está ejecutando en el puerto
5535
en la etapadocker_test_image
. Podemos actualizar la etapapostman_tests
para probar la aplicación utilizando la URL `http://xxx1:5535`.Para solucionar los problemas de que el contenedor de la aplicación no accede a SQL Server, agregamos un alias al contenedor SQL Server y actualizamos la cadena de conexión para usar el nombre de
alias
. También agregamos la variableFF_NETWORK_PER_BUILD
a la etapapostman_tests
. Sin embargo, descubrimos que el problema se debía a un error tipográfico en el archivoappsettings.json
. El valorserver
debería sermssql
en lugar demcr.microsoft.com__mssql__server
.