How to wait for MSSQL in Docker Compose? How to wait for MSSQL in Docker Compose? docker docker

How to wait for MSSQL in Docker Compose?


When you use depends_on, docker-compose will just launch your base service with more priority and never wait for start services.

There are some useful external program that help you to wait for specific service (port), then run another service.

vishnubob/wait-for-it is one of them which blocks execution flow until your specific port(s) get ready.
Another good choice is eficode/wait-for which already prepared for docker-compose.

Example usage (according to 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

-- UPDATE --

Consider you have a Python application that depend on a database like PostgreSQL, and also your application will run with this command: python app.py
As Official Docker Document said, Put vishnubob/wait-for-it in your image (inside of your other project files like app.py)

Now just put this lines in your 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

Note: Don't forget to put this commands in your Dockerfile inside your image files:

# Copy wait-for-it.sh into our imageCOPY wait-for-it.sh wait-for-it.sh# Make it executable, in LinuxRUN chmod +x wait-for-it.sh


After searching and trying many different scenarios, I was able to add waiting using the following composer file. This is for asp.net core solution. The key is that you have to overwrite entrypoint if it is specified in dockerfile. Also, you need to make sure to save "wait-for-it.sh" LF as line ending instead of CRLF, otherwise you'll get the error of file not found.

The dockerfile should have the following (download it from here: https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh, make sure to save the file):

COPY ./wait-for-it.sh /wait-for-it.shRUN 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


Create two separate dockerfiles (e.g):

  1. Mssql.Dockerfile
  2. App.Dockerfile

Set up the sequence within docker-compose.yml

Mssql.Dockerfile

FROM mcr.microsoft.com/mssql/server AS baseENV ACCEPT_EULA=YENV SA_PASSWORD=Password123COPY . .COPY ["Db/Scripts/*", "Db/Scripts/"]VOLUME ./Db:/var/opt/mssql/dataHEALTHCHECK --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

App.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

Note:The connection string will look like: "Server=sqlserver;Database=Northwind;Trusted_Connection=False;User Id=sa;Password=Password123;MultipleActiveResultSets=true"