Search code examples
sql-serverdockerdocker-composedockerfile

SQL Server Docker Compose SQLCMD does not execute


I'm currently trying to set up a SQL Server in docker compose and I want to create the database on build with the RUN instruction. This doesn't work, however when I execute the same command on the running container with sh, it works

my compose file looks like this:

version: "3.7"

services:
  mssql:
    build: ./mssql
    environment: 
      SA_PASSWORD: "Password12345!"
      ACCEPT_EULA: "Y"
    container_name: mssqlDB
    ports:
      - "1433:1433"
    restart: always

And here my Dockerfile:

FROM mcr.microsoft.com/mssql/server:2019-GA-ubuntu-16.04
COPY ./prod.sql /
RUN ./opt/mssql-bin/sqlcmd -S localhost -U SA -P "Password12345!" -Q "Create Database HelloWorld"
CMD ["/opt/mssql/bin/sqlservr"]

Solution

  • This is because the SQL Server instance is not started and you must wait for it.

    From the Docker Hub official page of SQL Server there is a link to a GitHub Repository that shows how to run a sql script on Docker container.

    Below I have re-adapted the GitHub code for you case

    initialize.sh

    # Typically SQL Server takes about 5-10 seconds to start up 
    # Wait for the SQL Server to come up (90 sec) You can reduce to 20sec and see
    sleep 90s
    
    #run the setup script to create the DB and the schema in the DB
    /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P password -d master -i prod.sql
    

    entrypoint.sh

    #start SQL Server, start the script to create the DB and import the data
    /opt/mssql/bin/sqlservr & initialize.sh 
    

    Dockerfile

    FROM mcr.microsoft.com/mssql/server:2019-GA-ubuntu-16.04
    COPY ./prod.sql /
    
    # Grant permissions for the import-data script to be executable
    RUN chmod +x ./initialize.sh
    
    CMD /bin/bash ./entrypoint.sh
    

    Another solution that I personally made is to run the SQL Server service and wait until the service came up.

    create.sh

    /opt/mssql-tools/bin/sqlcmd -U sa -P $1 -Q 'CREATE DATABASE [MyNewDatabase]'
    /opt/mssql-tools/bin/sqlcmd -U sa -P $1 -d 'MyNewDatabase' -i /src/script.sql
    

    script.sql

    CREATE TABLE MyTable (..)
    

    DockerFile

    
    FROM mcr.microsoft.com/mssql/server:2017-latest-ubuntu
    EXPOSE 1433
    
    WORKDIR /
    COPY ./create.sh /src/
    COPY ./script.sql /src/
    
    ENV ACCEPT_EULA Y
    ENV SA_PASSWORD P@ssw0rd
    
    RUN echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bash_profile
    RUN echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
    
    RUN ( /opt/mssql/bin/sqlservr --accept-eula & ) | grep -q "Service Broker manager has started" \
        && /src/create.sh P@ssw0rd \
        && pkill sqlservr