Create SQL Server database from a script in docker - sql-server

Simple question I hope. I cannot find anything anywhere.
How do you create a database in a Microsoft SQL Server Docker container?
Dockerfile:
I am looking at the following Dockerfile:
FROM microsoft/mssql-server-windows-developer:latest
ENV sa_password ab873jouehxaAGR
WORKDIR /
COPY /db-scripts/create-db.sql .
# here be the existing run commnd in the image microsoft/mssql-server-windows-developer:latest
#CMD ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';", ".\\start -sa_password $env:sa_password -ACCEPT_EULA $env:ACCEPT_EULA -attach_dbs \\\"$env:attach_dbs\\\" -Verbose" ]
RUN (sqlcmd -S localhost -U SA -P ab873jouehxaAGR -i create-db.sql)
docker-compose.yml:
I have put together the following docker compose file:
version: '3.4'
services:
sql.data:
image: ${DOCKER_REGISTRY}myfirst-mssql:latest
container_name: myfirst-mssql_container
build:
context: .
dockerfile: ./Dockerfile
environment:
SA_PASSWORD: ab873jouehxaAGR
ACCEPT_EULA: Y
Bringing it together
I am running the command docker-compose up against the above. And assuming create-db.sql file will simply create a database which is not relevant here to keep things minimal.
Errors
The error I get above is that the login for SA is invalid when it runs the .sql script:
Step 7/7 : RUN (sqlcmd -S localhost -U SA -P ab873jouehxaAGR -i create-db.sql)
---> Running in 2ac5644d0bd9
Sqlcmd: Error: Microsoft ODBC Driver 13 for SQL Server : Login failed for user 'SA'..
It looks like this runs before the password has been changed to ab873jouehxaAGR which typically looks like the command from mssql-server-windows-developer:latest.json from inspecting the image in vscode - \start -sa_password $env:sa_password -ACCEPT_EULA $env:ACCEPT_EULA -attach_dbs actually does.
Environment
I am running docker Docker version 18.06.1-ce, build e68fc7a on Windows 10.
Attach or script
I am not specifying attaching a database using the environment variable attach_dbs of which I see in many examples.
I am trying to find a best practice for managing a sql container from a point of view of end to end testing and a lot of articles seem to not cover the data aspect part - ie Development Workflow
I would be interested to hear in comments thoughts on these two approaches in the Docker world.

using following commands can solve your problem
docker-compose up --build -d
version: '3.4'
services:
sql.data:
image: ${DOCKER_REGISTRY}myfirst-mssql:latest
container_name: myfirst-mssql_container
environment:
SA_PASSWORD: ab873jouehxaAGR
ACCEPT_EULA: Y
and after that:
docker exec myfirst-mssql_container sqlcmd
-d master
-S localhost
-U "sa"
-P "ab873jouehxaAGR"
-Q 'select 1'

Related

Can't run mssql docker image: permissions_check.sh: exec format error

I've trying to run a mssql docker container with Linux 20.04 installed in a Raspberry pi, and I got the following error:
mssql | exec /opt/mssql/bin/permissions_check.sh: exec format error
mssql exited with code 1
My docker compose file is the following:
version: "3.7"
services:
sql-server-db:
container_name: mssql
image: mcr.microsoft.com/mssql/server:2022-latest
#image: mcr.microsoft.com/mssql/server:2019-CU18-ubuntu-20.04
ports:
- "1433:1433"
environment:
MSSQL_SA_PASSWORD: ******
ACCEPT_EULA: Y
volumes:
- ./Data/mssql:/var/opt/mssql/data
Also, I've tried to run the container like this:
docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=******" -p 1433:1433 --name mssql -d mcr.microsoft.com/mssql/server:2019-CU18-ubuntu-20.04
Additionally, I've tried more than one image with no success.
I've tried everything I have in my hands, I'm starting to losing my mind with this right now....
Things I've tried:
I read an article in stackoverflow about defining a volume inside docker-compose.yml file to the mssql image.
I've put and take single and double quotation marks from the docker-compose.yml file.
As I mentioned before, I tried to run docker run (...) command to check another way around.
I expected these to work since I thought I had a spelling mistake or a comma, quatation mark wrong, etc. All with no success.

Initialize SQL Server database in docker container without sqlcmd

I am working on a MacBook Pro with M1 CPU so I can't use the "normal" mssql docker image. I am using azure-sql-edge that doesn't have sqlcmd to initialize the database (create schema, database, login).
I have created a sql script that I would like to run once the container starts but I can't find any alternative to sqlcmd.
Is there any other way to do it?
I had same issue, I used mssql-tools docker image from Microsoft registry.
Sample docker-compose:
---
version: '3.8'
services:
mssql:
image: mcr.microsoft.com/azure-sql-edge:latest
command: /opt/mssql/bin/sqlservr
environment:
ACCEPT_EULA: "Y"
SA_PASSWORD: "SA_Passw0rd"
stdin_open: true
ports:
- 1433:1433
networks:
- db_net
sqlcmd:
image: mcr.microsoft.com/mssql-tools:latest
command: /opt/mssql_scripts/run-initialization.sh
stdin_open: true
volumes:
- ./mssql_scripts:/opt/mssql_scripts
networks:
- db_net
networks:
db_net:
name: db_net
To use this docker-compose you need to have a shell script named run-initialization.sh with execute rights inside mssql_scripts folder.
The run-initialization.sh script waits for database to start up and then execute sql commands:
/opt/mssql-tools/bin/sqlcmd -S mssql -U SA -P SA_Passw0rd -d master -Q "SELECT version()"
or if you want to execute from test.sql file:
/opt/mssql-tools/bin/sqlcmd -S mssql -U SA -P SA_Passw0rd -d master -i /opt/mssql_scripts/test.sql
The solution above worked for me using Mac M1 chip, don't need to create a shell script can run the commands direct.
sqlcmd:
image: mcr.microsoft.com/mssql-tools:latest
stdin_open: true
environment:
- MSSQL_SA_PASSWORD=Xxx
- MSSQL_DATABASE=test
- MSSQL_BACKUP="/opt/mssql/test.bak"
volumes:
- ./test_data.bak:/opt/mssql/test.bak
command: /bin/bash -c '/opt/mssql-tools/bin/sqlcmd -S mssql -U sa -P $$MSSQL_SA_PASSWORD -d tempdb -q "EXIT(RESTORE DATABASE $$MSSQL_DATABASE FROM DISK = $$MSSQL_BACKUP)"; wait;'
mssql:
image: mcr.microsoft.com/azure-sql-edge:latest
environment:
- ACCEPT_EULA=Y
- MSSQL_SA_PASSWORD=Xxxx
- MSSQL_DATABASE=test
- MSSQL_SLEEP=7
ports:
- 1433:1433
Since I am starting a new project I looked into this issue again and found a good solution for me.
I found go-sqlcmd, a new implementation of sqlcmd using golang and it's compatible with M1 chips.
So I am running azure-sql-edge as before using docker compose:
version: "3.9"
services:
mssql:
image: mcr.microsoft.com/azure-sql-edge:latest
command: /opt/mssql/bin/sqlservr
environment:
ACCEPT_EULA: "Y"
SA_PASSWORD: ${DATABASE_SA_PASSWORD}
stdin_open: true
ports:
- 1433:1433
When the database container is up and in idle I run this bash script (in my case I am reading the environmnet variables from a .NET appsettings.json file):
cat <appsetting.json> | jq -r 'to_entries|map("\(.key)=\(.value|tostring)")|.[]' > temp
# Show env vars
grep -v '^#' temp
# Export env vars
export $(grep -v '^#' temp | xargs)
export SQLCMDPASSWORD=$DATABASE_SA_PASSWORD
sqlcmd -U sa \
-v DATABASE_SCHEMA=$DATABASE_SCHEMA \
-v DATABASE_DB_NAME=$DATABASE_DB_NAME \
-v DATABASE_LOGIN_NAME=$DATABASE_LOGIN_NAME \
-v DATABASE_LOGIN_PASSWORD=$DATABASE_LOGIN_PASSWORD \
-i sql/init-db.sql,sql/init-user.sql
I had to split the database and schema creation in a script, then I create the user and assign it to the database.
The sql scripts, init-db.sql:
USE master
IF NOT EXISTS (SELECT name FROM sys.schemas WHERE name = N'$(DATABASE_SCHEMA)')
BEGIN
EXEC sys.sp_executesql N'CREATE SCHEMA [$(DATABASE_SCHEMA)] AUTHORIZATION [dbo]'
END
IF NOT EXISTS (SELECT name FROM sys.databases WHERE name = N'$(DATABASE_DB_NAME)')
BEGIN
CREATE DATABASE $(DATABASE_DB_NAME)
END
init-user.sql:
USE $(DATABASE_DB_NAME)
IF NOT EXISTS(SELECT principal_id FROM sys.server_principals WHERE name = '$(DATABASE_LOGIN_NAME)') BEGIN
CREATE LOGIN $(DATABASE_LOGIN_NAME)
WITH PASSWORD = '$(DATABASE_LOGIN_PASSWORD)'
END
IF NOT EXISTS(SELECT principal_id FROM sys.database_principals WHERE name = '$(DATABASE_LOGIN_NAME)') BEGIN
CREATE USER $(DATABASE_LOGIN_NAME) FOR LOGIN $(DATABASE_LOGIN_NAME)
END

Bitbucket pipeline sql server database set port

I have a bitbucket pipeline that must execute django unittests. Therefore, I need a test database which should be a SQL SERVER datbase.
The pipeline looks like this:
# This is a sample build configuration for Python.
# Check our guides at https://confluence.atlassian.com/x/x4UWN for more examples.
# Only use spaces to indent your .yml configuration.
# -----
# You can specify a custom docker image from Docker Hub as your build environment.
image: python:3.7.3
pipelines:
branches:
master:
- step:
name: Setup sql
image: fabiang/sqlcmd
script:
- sqlcmd -S localhost -U sa -P $DB_PASSWORD
services:
- sqlserver
- step:
name: Run tests
caches:
- pip
script: # Modify the commands below to build your repository.
- python3 -m venv my_env
- source my_env/bin/activate
- apt-get update && apt-get install
- pip3 install -r req-dev.txt
- python3 manage.py test
- step:
name: Linter
script: # Modify the commands below to build your repository.
- pip3 install flake8
- flake8 --exclude=__init__.py migrations/
definitions:
services:
sqlserver:
image: mcr.microsoft.com/mssql/server:2017-latest
variables:
ACCEPT_EULA: Y
SA_PASSWORD: $DB_PASSWORD
And everytime when I run the pipeline I get:
Sqlcmd: Error: Microsoft ODBC Driver 17 for SQL Server : Login timeout expired.
Sqlcmd: Error: Microsoft ODBC Driver 17 for SQL Server : TCP Provider: Error code 0x2726.
I tried to do it locally but then it only work when I defined a port with the -p tag:
docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=yourStrong!' -p 1433:1433 -d mcr.microsoft.com/mssql/server:2017-latest
How can I make the pipeline work? (probably defining a port but how?)
UPDATE:
On the sqlserver tab in the result section is the following error shown:
I think the problem is when you call the script - sqlcmd -S localhost -U sa -P $DB_PASSWORD because your sqlserver is not yet completly initialized.
Try to put a sleep 10 before the command and the best is to add an error case if command fail sleep 5 and retry again.

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"]
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 are a link to a GitHub Repository where show 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

Login fails for SA sql server linux docker

I try to use sql server on docker, linux. I start the container like this:
docker run -d -p 1433:1433 -e sa_password="12345qwerASDF" -e ACCEPT_EULA=Y --name sql-server --hostname sql-server microsoft/mssql-server-linux:2017-latest
When I try to connect, all I get is "Login failed for user 'sa'"
Tried with different password, with and without double and single quotes...
Finally I got it to work:
docker run --name sqlserver --hostname sqlserver -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=1StrongPwd!!" -p 1433:1433 -d microsoft/mssql-server-linux:2017-latest
I guess it should be MSSQL_SA_PASSWORD and not SA_PASSWORD
The documentation isn't clear in that part...
Your password 12345qwerASDF doesn't meet complexity requirements. Try adding a non-alphanumeric characters such as exclamation point (!).
To check for errors, run: docker logs ID (where ID is container ID from docker ps).
For docker-compose file
i was facing problem with sa user login failed i fix it by adding
depends_on:
- db
here's my full version of docker-compose file
version: '3.1'
services:
colour-api:
build: .
environment:
DBServer: "ms-sql-server"
ports:
- "8080:80"
depends_on:
- ms-sql-server
ms-sql-server:
image: mcr.microsoft.com/mssql/server
environment:
ACCEPT_EULA: "Y"
MSSQL_SA_PASSWORD: "Pa55w0rd2019"
ports:
- "1444:1433"
Follow this link for more details
https://docs.docker.com/compose/aspnet-mssql-compose/
I got the same error. Stop the sql server services running in your local. Then You can login to sql server(linux) via docker(dbeaver)
1-) I got the error
2-) Stop the sql server services running in your local
3-) Then You can login to sql server(linux) via docker(dbeaver)
I hope it was helpful
Try this :
docker run -e "ACCEPT_EULA=Y" -e "sa_password=12345qwerASDF" -p 1433:1433 --name sql-server --hostname sql-server -d microsoft/mssql-server-linux:2017-latest
IMPORTANT NOTE: If you are using PowerShell on Windows to run these
commands use double quotes instead of single quotes.
Source : https://hub.docker.com/r/microsoft/mssql-server-linux/
I solved my problem with this notes
In formal doc used SA_PASSWORD !!!, but MSSQL_SA_PASSWORD is true (Microsoft team, what are doing?!!!!)
As a docker "[Configuration/Requirements for Microsoft SQL Server][1]" said: " A strong system administrator (SA) password: At least 8 characters including uppercase, lowercase letters, base-10 digits and/or non-alphanumeric symbols."
In Linux, use single quote for define password .
Be sure, before you run "docker run .." , the volume of "data" which you mount from host to container must be clean (if you have it!).
Here is a sample of “docker run” for creation Microsoft SQL Server container.
docker run
-e ACCEPT_EULA=Y
-e MSSQL_SA_PASSWORD='Mssql!Passw0rd'
-e MSSQL_DATA_DIR=/var/opt/mssql/data
-e MSSQL_PID='Developer'
-e MSSQL_TCP_PORT=1433
-p 1433:1433
-v /var/opt/mssql/data:/var/opt/mssql/data
-v /var/opt/mssql/log:/var/opt/mssql/log
-v /var/opt/mssql/secrets:/var/opt/mssql/secrets
--name mssql_2017
-d mcr.microsoft.com/mssql/server:2017-latest
for checking an instance of SQL Server ...
docker exec -it mssql_2017 /bin/bash
cd /opt/mssql-tools/bin/
./sqlcmd -S localhost -U SA -P 'Mssql!Passw0rd'
select ##version
go
I hope this hints can help you.
The docker volume used for the mssql service could be corrupted.
In a docker setup using mcr.microsoft.com/mssql/server:2019-latest
I have encountered a similar problem. Although I had no problem
connecting to the server from a container built from the command line the issue persisted for the docker container.
Removing the volume and recreating the container did the trick.
docker run --name SQLServer -e ACCEPT_EULA=Y -e MSSQL_SA_PASSWORD=“Yourpassword” -e MSSQL_PID="Express" -p 1433:1433 -d mcr.microsoft.com/mssql/server:2019-latest
Same thing happened to me but the problem was I had a windows desktop version of MSSQL and I forgot to stop the service before connecting to the docker version.

Resources