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?
Related
I am working with a MacBook M1 that runs a SQL Server database using microsoft-azure-sql-edge image. On the same laptop is running a Win 11 VM using Parallels where SQL Server Management Studio is installed.
The issue is that I can't connect to the database from the Windows VM. I tried to give a hostname to the database container and connect it to the host network using this docker compose config:
version: "3.9"
services:
mssql:
image: mcr.microsoft.com/azure-sql-edge:latest
command: /opt/mssql/bin/sqlservr
environment:
ACCEPT_EULA: "Y"
SA_PASSWORD: ${SAPassword}
stdin_open: true
container_name: sqlserver
hostname: sqlserver
network_mode: host
ports:
- 1433:1433
I tried to set sqlserver as server name and enter the login for sa but I get an error:
A network-related or instance-specific error occurred while establishing a connection to SQL Server
Trying to spin up an mssql server with a docker-compose file:
version: "3.7"
services:
sqlserver:
image: mcr.microsoft.com/mssql/server:2017-latest
container_name: sqlserver
user: root
ports:
- "1433:1433"
environment:
SA_USERNAME: sa
SA_PASSWORD: Dev1234!
ACCEPT_EULA: Y
MSSQL_AGENT_ENABLED: 'true'
volumes:
- ./volumes/data2:/var/opt/mssql/data
- ./volumes/backup:/var/opt/mssql/Backup
The server is up and running successfully, But when tried to connect with powershell script code:
$connectionString = "Data Source=localhost,1433;User ID=sa;Password=Dev1234!;"
$connection = New-Object System.Data.SqlClient.SqlConnection($connectionString)
$connection.Open();
It throws error like:
"A network-related or instance-specific error occurred while
establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name
is correct and that SQL Server is configured to allow remote connections. (provider: TCP Provider, error: 0 - The
remote computer refused the network connection.)"
That is, it fails when trying to connect with 'localhost' as host, it is successfully connecting when "127.0.0.1" is specified as host.
The same happens when I tried to connect with SQL server management studio.
My docker engine is running in wsl, an ubuntu distro specifically. There is MySQL and different other servers already spun up which I can access with localhost.
Is there anything I need to specify in docker-compose to make this work? When checking documentation, there are no params aligned to it as I see.
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
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.
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.