SQL Server not initating a DB on docker deployment - sql-server

I know this has been covered multiple times, but I still cannot execute an SQL script on docker deployment.
docker-compose
version: '3.9'
services:
mssql:
build: ./docker/mssql
container_name: db
ports:
- 1433:1433
environment:
- ACCEPT_EULA=Y
- SA_PASSWORD=Welcome#toSQL2022
- MSSQL_PID=Developer
volumes:
- ./docker/mssql/db-data:/var/opt/mssql/data
- ./docker/mssql/scripts:/var/opt/mssql/scripts
networks:
- supernet
networks:
supernet: {}
Dockerfile
FROM mcr.microsoft.com/mssql/server:2019-CU15-ubuntu-20.04
COPY ./create-from-mdf.sql .
EXPOSE 1433
#tried this: CMD ["/opt/mssql-tools/bin/sqlcmd", "-i", "create-from-mdf.sql", "-S", "localhost", "-U", "SA", "-P" "Welcome#toSQL2022"]
#tried this: CMD sleep 30 && /opt/mssql-tools/bin/sqlcmd -S localhost,1433 -U sa -P Welcome#toSQL2022 -i create-from-mdf.sql#
CMD /opt/mssql-tools/bin/sqlcmd -S localhost,1433 -U sa -P Welcome#toSQL2022 -i create-from-mdf.sql
I get this error:
db | Sqlcmd: Error: Microsoft ODBC Driver 17 for SQL Server : Login timeout expired.
db | Sqlcmd: Error: Microsoft ODBC Driver 17 for SQL Server : TCP Provider: Error code 0x2749.
db | Sqlcmd: Error: Microsoft ODBC Driver 17 for SQL Server : A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correct and if SQL Server is configured to allow remote connections. For more information see SQL Server Books Online..
db exited with code 1
However, if I connect to container via CLI the same command gets executed succefully:
/opt/mssql-tools/bin/sqlcmd -S localhost,1433 -U sa -P Welcome#toSQL2022 -i create-from-mdf.sql

Related

Issues connecting to Docker MSSQL using pyodbc

I have pulled a docker image that runs an MS SQL from docker hub:
docker pull mcr.microsoft.com/mssql/server:2017-latest
docker run --name some-db -e ACCEPT_EULA=Y -e MSSQL_SA_PASSWORD=Aamerge1234 -e MSSQL_PID=Developer -d -p 1433:1433 mcr.microsoft.com/mssql/server:2017-latest
The container runs fine, I added a strong password as required.
This is the python code I am using to connect with the database using pyodbc:
import pyodbc
server = 'localhost:1433'
# database = ''
username = 'sa'
password = 'Aamerge1234'
conn = pyodbc.connect('DRIVER={SQL Server Native Client 11.0};SERVER='+server+';UID='+username+';PWD='+ password)
I have omitted the variable database because mssql creates several.
I tried using the following ODBC drivers:
ODBC Driver 17 for SQL Server
SQL Server
However, it always returns error:
OperationalError: ('08001', '[08001] [Microsoft][ODBC Driver 17 for SQL Server]Named Pipes Provider: Could not open a connection to SQL Server [53]. (53) (SQLDriverConnect); [08001] [Microsoft][ODBC Driver 17 for SQL Server]Login timeout expired (0); [08001] [Microsoft][ODBC Driver 17 for SQL Server]A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correct and if SQL Server is configured to allow remote connections. For more information see SQL Server Books Online. (53)')

I can't connect to SQL Server inside container

This is my docker-compose.yml file:
version: "3.9"
services:
api:
# configuration of API here
db:
image: mcr.microsoft.com/mssql/server
restart: always
container_name: Database
volumes:
- ./Data:/var/opt/mssql
environment:
- ACCEPT_EULA=Y
- SA_PASSWORD=lksU2o412f7tBj58t07B
- MSSQL_PID=Express
ports:
- 1433:1433
command: >
sh -c
"
tail -f /dev/null
"
As you can see, I'm using the official docker image for MS SQL Server, mcr.microsoft.com/mssql/server.
My laptop is Ubuntu 20.04 LTS.
I run docker-compose up -d and then docker exec -it db sh to get interactive shell.
Then I write this command:
/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P 'lksU2o412f7tBj58t07B'
And I get this response:
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 0x2749.
Sqlcmd: Error: Microsoft ODBC Driver 17 for SQL Server : A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correct and if SQL Server is configured to allow remote connections. For more information see SQL Server Books Online..
This is the official image and I have not changed anything.
Also in my api container, I can ping db or Database. But I can't telnet port 1433.
Also from my host machine I can telnet localhost 1433, but I get this response:
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Connection closed by foreign host.
This is a terrible experience in working with containers from Microsoft. Aren't containers supposed to work out of the box? Isn't container technology there only to solve these stupid problems?
What should I do?

Cannot access to dockerized SQL Server instance

I have simple docker-compose.yml which contains two services only, my-api and sql-server.
version: '3.0'
services:
sql-server:
image: mcr.microsoft.com/mssql/server:2019-latest
hostname: sql-server
container_name: sql-server
ports:
- "1433:1433"
environment:
- ACCEPT_EULA=Y
- SA_PASSWORD=MyPassword01*
- MSSQL_PID=Express
my-api:
ports:
- "8080:5000"
depends_on:
- sql-server
... ommited for clarity
When I docker-compose up --build the containers are ready (I can verify with docker ps)
a7a47b89a17a mcr.microsoft.com/mssql/server:2019-latest "/opt/mssql/bin/perm…" 12 minutes ago Up 11 minutes 0.0.0.0:1433->1433/tcp sql-server
but I cannot access my SQL Server using SSMS.
SSMS login window:
Server Name: localhost,1433
Authentication: SQL Server Authentication
Username: sa
Password: MyPassword01*
Error:
Cannot connect to localhost,1433.
Login failed for user 'sa'. (.Net SqlClient Data Provider)
PS: I also tried with
Server Name: sql-server,1433
but still cannot access
Execute the below code which will display the public ipaddress.
Instead of localhost use this ipaddress
docker inspect -f "{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" mssqltrek-con1.
I followed the below link to achieve the same.
https://www.sqlshack.com/sql-server-with-a-docker-container-on-windows-server-2016/
I guess you have to debug further. The first thing I guess you can do is to open the bash inside the container and try to connect to your SQL database from the container.
docker exec -it sql-server "bash"
Once inside the container bash, then connect with sqlcmd,
/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "<YourNewStrong#Passw0rd>"
If you fail to connect inside the container, then I have to assume your SA password is somehow different when you set up the SQL server. But if this is not an issue, that means, you can connect to SQL server inside the container, then you can be rest assured it is something wrong with SSMS on port 1433 in your computer. Make sure the server name is correct.

Debezium Connector for SQL Server - connection refused

I want to use Kafka to publish MSSQL CDC events.
I am using Docker containers for:
debezium/zookeeper
debezium/kafka
debezium/connect
Microsoft SQL Server
Containers started as follows:
docker run -it --name zookeeper -p 2181:2181 -p 2888:2888 -p 3888:3888 debezium/zookeeper
docker run -it --name kafka -p 9092:9092 --link zookeeper:zookeeper debezium/kafka
docker run -it --name connect -p 8083:8083 -e GROUP_ID=1 -e CONFIG_STORAGE_TOPIC=my-connect-configs -e OFFSET_STORAGE_TOPIC=my-connect-offsets -e ADVERTISED_HOST_NAME="localhost" --link zookeeper:zookeeper --link kafka:kafka debezium/connect
docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=xxxxxxxxxxxxx" -p 1433:1433 --name sql1 -d mcr.microsoft.com/mssql/server:2017-CU8-ubuntu
All containers start running successfully.
Then I created new MSSQL db in SQL Server container. Created 1 table in new db and turned on CDC for that table. CDC is working fine.
Then I send connector configuration below to Kafka Connect REST API as follows:
curl -X POST -H "Content-Type: application/json" -d #test-mssql-connector.json http://localhost:8083/connectors
using test-mssql-connector.json
{
"name": "test-mssql-connector5",
"config": {
"connector.class": "io.debezium.connector.sqlserver.SqlServerConnector",
"database.hostname": "localhost",
"database.port": "1433",
"database.user": "SA",
"database.password": "xxxxxxxxxxxxx",
"database.dbname": "test",
"database.server.name": "sql1",
"table.whitelist": "dbo.Persons",
"database.history.kafka.bootstrap.servers": "kafka:9092",
"database.history.kafka.topic": "dbhistory.sql1"
}
}
However, Kafka connector cannot connect to the MSSQL db giving error message below:
com.microsoft.sqlserver.jdbc.SQLServerException: The TCP/IP connection
to the host localhost, port 1433 has failed. Error: \"Connection
refused. Verify the connection properties. Make sure that an instance
of SQL Server is running on the host and accepting TCP/IP connections
at the port. Make sure that TCP connections to the port are not
blocked by a firewall.
Most troubleshooting are if database actually running, or port is blocked, but there is no problem with new MSSQL db. It's container is active, and the db is successfully running. The port is not blocked. I can successfully connect to it from host machine using DbVisualizer or other query tools with following configuration:
database server = localhost
database port = 1433
user = SA
pw = xxxxxxxxxxxxx
database name = test
I can successfully use telnet localhost 1433 to connect to server.
Is there something missing in the connector configuration above?
IMHO the localhost is not correct as localhost is something else in Connect container and in SQL Server container. You should link the database container into Connect container and use the appropriate hostname.
You need to first set up your sql container and THEN only start the connect service specifying the sql server as an additional link:
docker run -it --name connect -p 8083:8083 -e GROUP_ID=1 -e CONFIG_STORAGE_TOPIC=my-connect-configs -e OFFSET_STORAGE_TOPIC=my-connect-offsets -e ADVERTISED_HOST_NAME="localhost" --link zookeeper:zookeeper --link kafka:kafka --link kafka:kafka debezium/connect

Run command after docker container is started

I've prepared a docker-compose file to deploy container with database:
services:
tmp-db:
image: microsoft/mssql-server-linux:latest
environment:
ACCEPT_EULA: Y
SA_PASSWORD: yourStrong(!)Password
ports:
- 1433:1433
It is okay. But now I need to create a database and build its structure. I need to execute some sql commands.
To check if i am able to do this I added command to the service:
services:
tmp-db:
image: microsoft/mssql-server-linux:latest
environment:
ACCEPT_EULA: Y
SA_PASSWORD: yourStrong(!)Password
command: /opt/mssql-tools/bin/sqlcmd -U sa -P yourStrong(!)Password -Q "SELECT [name] FROM sys.databases"
ports:
- 1433:1433
However I got the following errors:
tmp-db_1 | Sqlcmd: Error: Microsoft ODBC Driver 13 for SQL Server : Login timeout expired.
tmp-db_1 | Sqlcmd: Error: Microsoft ODBC Driver 13 for SQL Server : TCP Provider: Error code 0x2749.
tmp-db_1 | Sqlcmd: Error: Microsoft ODBC Driver 13 for SQL Server : A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correct and if SQL Server is configured to allow remote connections. For more information see SQL Server Books Online..
I feel the command is executed before Sql Server instance is started. How can I fix it? How can I execute some sql after Sql Server is started?
The issue is that only one command is executed in a container. When you specify the command in docker-compose.yml it overrides the default command, which was supposed to start the container. So you have two options
Run the command manually
services:
tmp-db:
image: microsoft/mssql-server-linux:latest
environment:
ACCEPT_EULA: Y
SA_PASSWORD: yourStrong(!)Password
ports:
- 1433:1433
Then you can execute
docker-compose exec tmp-db /opt/mssql-tools/bin/sqlcmd -U sa -P yourStrong(!)Password -Q "SELECT [name] FROM sys.databases"
Have two services - one for server & one for data loading
services:
load-db:
image: microsoft/mssql-server-linux:latest
command: sh -c 'sleep 10 && /opt/mssql-tools/bin/sqlcmd -U sa -P yourStrong(!)Password -Q "SELECT [name] FROM sys.databases"'
network_mode: service:tmp-db
tmp-db:
image: microsoft/mssql-server-linux:latest
environment:
ACCEPT_EULA: Y
SA_PASSWORD: yourStrong(!)Password
ports:
- 1433:1433
In this approach we launch another container with the command to load our data, we run it on the network of our DB server container. This is done just to avoid the host name of the DB, if you prefer you can pass the host name also as tmp-db and remove the network_mode: service:tmp-db.

Resources