Saltar al contenido

¿Cómo esperar MSSQL en Docker Compose?

Nuestros desarrolladores estrellas han agotado sus reservas de café, investigando día y noche por la respuesta, hasta que Mateo halló el resultado en Gitea así que hoy la comparte contigo.

Solución:

Después de buscar y probar muchos escenarios diferentes, pude agregar la espera usando el siguiente archivo de composición. Esto es para asp.net solución central. El key es que tienes que sobrescribir entrypoint si se especifica en dockerfile. Además, debe asegurarse de guardar “wait-for-it.sh” LF como final de línea en lugar de CRLF; de lo contrario, obtendrá el error de file not found.

El dockerfile debe tener lo siguiente (descárguelo desde aquí: https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh, asegúrese de guardar el archivo):

COPY ./wait-for-it.sh /wait-for-it.sh
RUN chmod +x wait-for-it.sh

docker-compose.yml

version: '3.7'

services:

  vc-db:
    image: mcr.microsoft.com/mssql/server:latest
    ports:
      - "$DOCKER_SQL_PORT:-1433:1433"
    expose:  
      - 1433  
    environment: 
      - ACCEPT_EULA=Y
      - MSSQL_PID=Express
      - SA_PASSWORD=v!rto_Labs!
    networks:
      - virto

  vc-platform-web:
    image: virtocommerce/platform:$DOCKER_TAG:-latest
    ports:
      - "$DOCKER_PLATFORM_PORT:-8090:80"
    environment:
      - ASPNETCORE_URLS=http://+
    depends_on:
      - vc-db
    entrypoint: ["/wait-for-it.sh", "vc-db:1433", "-t", "120", "--", "dotnet", "VirtoCommerce.Platform.Web.dll"]
    networks:
      - virto

Cuando usas depends_on, docker-compose simplemente lanzará su servicio base con más prioridad y nunca esperará a que comiencen los servicios.

Hay algunos programas externos útiles que lo ayudan a esperar un servicio específico (puerto) y luego ejecutar otro servicio.

vishnubob / wait-for-it es uno de ellos que bloquea el flujo de ejecución hasta que sus puertos específicos estén listos.
Otra buena opción es eficode / wait-for, que ya está preparado para docker-compose.

Ejemplo de uso (según eficode / wait-for docs)

version: '2'

services:
  db:
    image: postgres:9.4

  backend:
    build: backend
    # Blocks execution flow util db:5432 is ready (Or you can use localhost instead)
    command: sh -c './wait-for db:5432 -- npm start'
    depends_on:
      - db

— ACTUALIZAR —

Considere que tiene una aplicación Python que depende de una base de datos como PostgreSQL, y también su aplicación se ejecutará con este comando: python app.py

Como decía el documento oficial de Docker, Put vishnubob/wait-for-it en su imagen (dentro de sus otros archivos de proyecto como app.py)

Ahora solo ponga estas líneas en su docker-compose.yml:

version: "3"
services:
  web:
    build: .
    ports:
      - "80:8000"
    depends_on:
      - "db"
    # This command waits until `db:5432` respond (5432 is default PostgreSQL port)
    # then runs our application by this command: `python app.py`
    command: ["./wait-for-it.sh", "db:5432", "--", "python", "app.py"]
  db:
    image: postgres

Nota: No olvide poner estos comandos en su Dockerfile dentro de sus archivos de imagen:

# Copy wait-for-it.sh into our image
COPY wait-for-it.sh wait-for-it.sh
# Make it executable, in Linux
RUN chmod +x wait-for-it.sh

Cree dos dockerfiles separados (por ejemplo):

  1. Mssql.Dockerfile
  2. Aplicación.Dockerfile

Configure la secuencia dentro de docker-compose.yml

Mssql.Dockerfile

FROM mcr.microsoft.com/mssql/server AS base

ENV ACCEPT_EULA=Y
ENV SA_PASSWORD=Password123

COPY . .
COPY ["Db/Scripts/*", "Db/Scripts/"]
VOLUME ./Db:/var/opt/mssql/data

HEALTHCHECK --interval=10s --timeout=5s --start-period=10s --retries=10 
    CMD /opt/mssql-tools/bin/sqlcmd -S . -U sa -P Password123 -i Db/Scripts/SetupDb.sql || exit 1

Aplicación.Dockerfile:

    FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
    WORKDIR /app
    EXPOSE 80
    EXPOSE 443

    FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
    WORKDIR /src
    COPY ["AspNetCoreWebApplication/AspNetCoreWebApplication.csproj", "AspNetCoreWebApplication/"]
    COPY ["WebApp.Data.EF/WebApp.Data.EF.csproj", "WebApp.Data.EF/"]
    COPY ["WebApp.Service/WebApp.Service.csproj", "WebApp.Service/"]

    RUN dotnet restore "AspNetCoreWebApplication/AspNetCoreWebApplication.csproj"
    COPY . .
    WORKDIR "/src/AspNetCoreWebApplication"
    RUN dotnet build "AspNetCoreWebApplication.csproj" -c Release -o /app/build
    FROM build AS publish
    RUN dotnet publish "AspNetCoreWebApplication.csproj" -c Release -o /app/publish

    FROM base AS final
    WORKDIR /app
    COPY --from=publish /app/publish .
    ENTRYPOINT ["dotnet", "AspNetCoreWebApplication.dll"]

Docker-compose.yml:

version: '3.7'

services:
    api:
        image: aspnetcore/mentoring_api
        container_name: mentoring_api
        build:
            context: .
            dockerfile: App.Dockerfile
        ports:
            - 8081:80
        expose: 
            - 8081
        environment:
            ASPNETCORE_ENVIRONMENT: Development
        depends_on:
            - sqlserver
    sqlserver:
        image: aspnetcore/mentoring_db
        container_name: mentoring_db
        build:
            context: .
            dockerfile: Mssql.Dockerfile
        ports:
            - "1433:1433"
        expose: 
            - 1433
        environment:
            - ACCEPT_EULA=Y
            - SA_PASSWORD=Password123
        volumes:
            - ./Db:/var/opt/mssql/data

Nota:
El conexión string se vera como: "Server=sqlserver;Database=Northwind;Trusted_Connection=False;User Id=sa;Password=Password123;MultipleActiveResultSets=true"

Aquí puedes ver las reseñas y valoraciones de los lectores

Si te ha resultado de ayuda nuestro artículo, sería de mucha ayuda si lo compartes con más programadores de esta forma contrubuyes a difundir este contenido.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *