Arthur Edgarov
Arthur Edgarov

Reputation: 731

Entrypoint script is not running from docker-compose file

My goal is to create an SQL login for my apps before running other images. Since my container uses Linux - scripts are saved with LF line endings. And the Docker output console is not showing any errors related to the script, only about my apps - they can't connect to the server because no such login exists.

The problem is that the shell script is not running and no login is being created. Thanks for your help in advance.

I was looking for the examples on the web, and here is what I came up with:

docker-compose.yml

version: '3.4'

services:
    mssql:
        image: mcr.microsoft.com/mssql/server:2019-latest
        environment:
            SA_PASSWORD: "3qqimIuTQEGqVCD!"
            ACCEPT_EULA: "Y"
            LOGIN: "MyLogin"
            PASSWORD: "3qqimIuTQEGqVCD!"

        ports:
            - "1433:1433"
        volumes:
            - ./DockerScripts/SQL/CreateLogin.sql:/CreateLogin.sql
            - ./DockerScripts/Shell/Entrypoint.sh:/Entrypoint.sh
        entrypoint:
            - ./Entrypoint.sh

    webapi:
        image: ${DOCKER_REGISTRY-}webapi
        build:
            context: .
            dockerfile: Source/Code/Web/WebApi/Dockerfile
        depends_on:
            - mssql

    maintenance:
        image: ${DOCKER_REGISTRY-}maintenance
        build:
            context: .
            dockerfile: Source/Code/Web/Maintenance/Dockerfile
        depends_on:
            - mssql

DockerScripts\Shell\Entrypoint.sh

#!/bin/bash

# Start SQL server
/opt/mssql/bin/sqlservr

# Wait for MSSQL server to start
export STATUS=1
i=0
while [[ $STATUS -ne 0 ]] && [[ $i -lt 30 ]]; do
    i=$i+1
    /opt/mssql-tools/bin/sqlcmd -t 1 -U sa -P $SA_PASSWORD -Q "select 1" >> /dev/null
    STATUS=$?
done

if [ $STATUS -ne 0 ]; then
    echo "Error: MS SQL Server took more than 30 seconds to start up."
    exit 1
fi

echo "MS SQL Server started successfully."

echo "Setting up server login."

/opt/mssql-tools/bin/sqlcmd  -U sa -P $SA_PASSWORD -S localhost -i CreateLogin.sql

DockerScripts\SQL\CreateLogin.sql

USE [master];
GO
CREATE LOGIN [$(LOGIN)] WITH PASSWORD=N'$(PASSWORD)', DEFAULT_DATABASE=[master], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF;
GO
ALTER SERVER ROLE [dbcreator] ADD MEMBER [$(LOGIN)];
GO

UPDATE

I removed a lot of stuff since it doesn't relate to the issue. So for now, the main problem persists - Entrypoint.sh just not being called on compose startup.

Upvotes: 2

Views: 4217

Answers (1)

Arthur Edgarov
Arthur Edgarov

Reputation: 731

Okay, so finally I was able to solve this issue.

The problem was not that Entrypoint.sh was not called, but that all the commands after

# Start SQL server
/opt/mssql/bin/sqlservr

were just skipped.

I don't really know why, but I was searching the web more and more and in the end, I came up with this solution.

First of all, I separated the login creation logic into its own script file, this slightly improves readability:

DockerScripts/Shell/CreateLogin.sh

#!bin/bash

echo "Creating MS SQL Login."

for i in {1..50};
do

/opt/mssql-tools/bin/sqlcmd -U sa -P $SA_PASSWORD -S localhost -i CreateLogin.sql

    if [ $? -eq 0 ]
    then
        echo "MS SQL Login created."
        break
    else
        echo "..."
        sleep 1
    fi

done

Secondly - I simplified my Entrypoint.sh file to just a few rows:

#!bin/bash
/opt/mssql/bin/sqlservr | /opt/mssql/bin/permissions_check.sh | /Scripts/CreateLogin.sh

Let me explain what the commands above means:

  • /opt/mssql/bin/sqlservr - this start the server itself.
  • /opt/mssql/bin/permissions_check.sh - this is just the default entrypint file.
  • /Scripts/CreateLogin.sh - and this point us to the server login creation.

And of course, I mounted the new shell script to a volume.

That's it, literally months of struggling with this issue, and turned out it was very simple to solve.

Hope this would help somebody else. Thanks!

Upvotes: 6

Related Questions