Cannot connect to EXTERNAL MS SQL Server with named instances

I am developing a Spring Boot application which connects to two EXTERNAL MS SQL Server databases.
The databases use named instances e.g. db-name\instance name and are using dynamic ports.
I am using WSL2 on WINDOWS 11.
I can connect to the databases in my development environment and also if I build a .jar, I can run it fine on both WSL2 and from the Windows powershell.
When I try to run the built image in a Docker container, it cannot resolve the database urls.

Example of one of the connection strings in application-uat.properties:

  spring.rm-datasource.jdbcUrl=jdbc:sqlserver://mc-db1;instanceName=mc_dev;database=Manager;encrypt=true;trustServerCertificate=true;

compose.yml

services:
  api:
    image: rcp-man:0.1.0
    ports:
      - 8080:8080
      - 1433:1433 # don't think I need this
      - 1434:1434/udp # not sure about this
    environment:
      - SPRING_PROFILES_ACTIVE=uat
    #network_mode: host

Relevant log output:

 The connection to the host mc-db1, named instance mc_dev failed. Error: "java.net.SocketTimeoutException: Receive timed out". Verify the server and instance names and check that no firewall is blocking UDP traffic to port 1434. For SQL Server 2005 or later, verify that the SQL Server Browser Service is running on the host.

Tried:

  • running in host mode, but to no avail.
  • Substituting IP address instead of mc-db1 - no luck
  • pinging mc-db1 from wsl2/Windows Powershell, works fine
  • Opening inbound port 1434 in Windows firewall

Like I say, the datasource urls work fine in a .jar. Does Docker support the dynamic port resolution required for MSSQL Server named instances?

$ docker info
Client:
 Version:    28.4.0
 Context:    desktop-linux
 Debug Mode: false
 Plugins:
  ai: Docker AI Agent - Ask Gordon (Docker Inc.)
    Version:  v1.9.11
    Path:     C:\Program Files\Docker\cli-plugins\docker-ai.exe
  buildx: Docker Buildx (Docker Inc.)
    Version:  v0.28.0-desktop.1
    Path:     C:\Program Files\Docker\cli-plugins\docker-buildx.exe
  cloud: Docker Cloud (Docker Inc.)
    Version:  v0.4.27
    Path:     C:\Program Files\Docker\cli-plugins\docker-cloud.exe
  compose: Docker Compose (Docker Inc.)
    Version:  v2.39.4-desktop.1
    Path:     C:\Users\deanw\.docker\cli-plugins\docker-compose.exe
  debug: Get a shell into any image or container (Docker Inc.)
    Version:  0.0.42
    Path:     C:\Program Files\Docker\cli-plugins\docker-debug.exe
  desktop: Docker Desktop commands (Docker Inc.)
    Version:  v0.2.0
    Path:     C:\Program Files\Docker\cli-plugins\docker-desktop.exe
  extension: Manages Docker extensions (Docker Inc.)
    Version:  v0.2.31
    Path:     C:\Program Files\Docker\cli-plugins\docker-extension.exe
  init: Creates Docker-related starter files for your project (Docker Inc.)
    Version:  v1.4.0
    Path:     C:\Program Files\Docker\cli-plugins\docker-init.exe
  mcp: Docker MCP Plugin (Docker Inc.)
    Version:  v0.20.0
    Path:     C:\Users\deanw\.docker\cli-plugins\docker-mcp.exe
  model: Docker Model Runner (Docker Inc.)
    Version:  v0.1.40
    Path:     C:\Program Files\Docker\cli-plugins\docker-model.exe
  sbom: View the packaged-based Software Bill Of Materials (SBOM) for an image (Anchore Inc.)
    Version:  0.6.0
    Path:     C:\Program Files\Docker\cli-plugins\docker-sbom.exe
  scout: Docker Scout (Docker Inc.)
    Version:  v1.18.3
    Path:     C:\Program Files\Docker\cli-plugins\docker-scout.exe

Thanks in advance.

Not really important, but an image is not running in a container. A container is a running instance of an image. The image is just a temlate for a container. You may be very well aware of it, so I just shared it for clarification in case anyone finss the topic.

You are right, you don’T need that. If the API server needs to access the external database, you don’t need port forwardig from the host into the API server. It has nothing to do with external servers.

I don’t see wath support could be needed, as the container itself is a kind of isolation, but outbound requests would only need to be able to reach the target endpoint. Docker will not do anything with port detecting, although I have very little experience in configuring and using MSSQL named instances and remember almost nothing, so I just tried to search for how it works..Am I correct to assume that a UDP request would go to a service on the SQL server machine on port 1434 to get the actual port of the named instance and the client just uses that information to use that port?

Maybe I just don’t know what that connection would require, The only thing that is worth menitoning is that you are using Docker Desktop. It shouldn’t matter unless something on the server side wants to and an independent request to the client on a specific port which will never arrive unless that port is forwarded from the host into the container. As far as I know, it is not the case.

Thanks for the response. When SQL Server starts a named instance using dynamic ports it assigns it a random port number within a range. For a client to connect to that named instance, it needs to query the server to get the port. The server is running a browser service on UDP port 1434.

I captured a little bit of the back and forth traffic from the application when it starts up (this is the JAR that works fine). 172.17.1.31.1434 is the SQLServer browser service. It looks like the client application uses a different port every time (50217, 32830, 43685 … ). I cant see any UDP traffic when I run the Docker container.

$ sudo tcpdump udp -nn
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
10:18:02.338587 IP 172.23.103.176.50217 > 172.17.1.31.1434: UDP, length 10
10:18:02.341197 IP 172.17.1.31.1434 > 172.23.103.176.50217: UDP, length 91
10:18:02.729581 IP 172.23.103.176.32830 > 172.17.1.31.1434: UDP, length 10
10:18:02.730943 IP 172.17.1.31.1434 > 172.23.103.176.32830: UDP, length 91
10:18:02.784106 IP 172.23.103.176.43685 > 172.17.1.31.1434: UDP, length 10
10:18:02.785447 IP 172.17.1.31.1434 > 172.23.103.176.43685: UDP, length 91

That’s the way TCP/IP and UDP usually work.

A connection is created or a packet is sent from one IP to another, from a source port to a target port.

The source port is usually random or in sequence and varies for every connection/packet.

Docker should know about the outgoing UDP packet and therefore be able to receive a response UDP packet.

You state you can not see UDP packets. But then there is a tcpdump with UDP packets?

And how much is it external? Is it in another WSL2 distribution or somewhere on a server in your LAN network? Just because the IP is similar to what a container IP would be. If you have a Docker container in a similar network, that could be a problem. Docker Desktop has its own subnet for its VM (WSL2 distribution) and containers are using the standard ip ranges like 172.17.x.x

It could use any private ip range like these: Private network - Wikipedia

Which you could override by setting the default-address-pools.

Since you say everything works without Docker on WSL2, but not in a container, based on the IPs you shared, I would check if any IP range collision happens between the destination and the Docker networks.

I wasn’t sure first, but I realized those logs are from running a jar file without containers.