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.
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
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?
I'm migrating a local SQL Server development database to run in a Linux docker container (on the same dev machine). When running my integration tests in Visual Studio 2019 on Windows, I receive MSDTC errors:
Exception thrown:
'System.Transactions.TransactionManagerCommunicationException' in
System.Data.dll An exception of type
'System.Transactions.TransactionManagerCommunicationException'
occurred in System.Data.dll but was not handled in user code
Communication with the underlying transaction manager has failed.
Here's my latest iteration of SQL Server in my docker-compose:
services:
sqlserver:
image: mcr.microsoft.com/mssql/server:2019-latest
container_name: SqlServer
restart: always
environment:
- ACCEPT_EULA=Y
- SA_PASSWORD=verySecretPassword
- MSSQL_RPC_PORT=13500
- MSSQL_DTC_TCP_PORT=51000
ports:
- "1401:1433"
- "135:13500"
- "51000:51000"
volumes:
- sqldata:/var/opt/mssql
I've tried all sorts of ways to adjust the RPC port to get this working. This is the main MS article. I've tried port 135:135 but it gives the same error. The note in the article at the bottom appears to be related to my issue.
For SQL Server outside of a container or for non-root containers, a
different ephemeral port, such as 13500, must be used in the container
and traffic to port 135 must then be routed to that port. You would
also need to configure port routing rules within the container from
the container port 135 to the ephemeral port.
Also, if you decide to map the container's port 135 to a different
port on the host, such as 13500, then you have to configure port
routing on the host. This enables the docker container to participate
in distributed transactions with the host and with other external
servers.
SQL Server 2019 containers run as a non-root user. I've tried port routing using netsh in windows... and also the MS article links to how to perform port forwarding in Ubuntu... which I'm unable to do even when logged in as root in the SQL Server container... iptables is not installed, and it doesn't let me apt-get install it?? I also updated the DTC options in windows to make it as open as possible, but it had no effect. Not sure what the secret sauce is. Hoping someone else has a similar setup that works.
Thanks for the tip on msdtc config, I got mine working with this compose:
version: '3.4'
services:
sqlserver:
image: mcr.microsoft.com/mssql/server:2019-GA-ubuntu-16.04
container_name: sqlserver
user: root
environment:
- ACCEPT_EULA=Y
- SA_PASSWORD=[yourPwd]
- MSSQL_RPC_PORT=135
- MSSQL_DTC_TCP_PORT=51000
ports:
- "1433:1433"
- "135:135"
- "51000:51000"
volumes:
- D:\DockerVolumes\sqlserver:/var/opt/mssql/data
My Docker-Compose.yml:
version: "3"
services:
db:
image: microsoft/mssql-server-linux:2017-CU8
ports:
- 1433:1433
deploy:
mode: replicated
replicas: 1
environment:
- ACCEPT_EULA=Y
- MSSQL_SA_PASSWORD=SuperStrongSqlAdminPassword)(*£)($£)
volumes:
- /home/mssql/:/var/opt/mssql/
- /var/opt/mssql/data
As you can see I have a volume mapped to a directory on the host machine: /home/msqql:/var/opt/mssql/
If I do: docker stack deploy -c docker-compose.yml [stack name].
The server starts and I can see data is written to the hosts directory: /home/mssql/*.
I then connect to the server and create a database, tables and add some data.
If I then kill the stack using docker stack rm [stack name], or restart the host for maintenance reasons etc.
When SQL Server starts up again, although the /home/mssql/* still contains the files created by the server initially, if I connect to the server the database/tables/data is gone.
Do I have to re-attach the database when the server restarts somehow, or something else I'm missing maybe?
Thanks
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.