Docker Compose桥接网络下容器TCP连接失败问题求助
Let's break down why your connection attempts are failing and walk through practical fixes step by step:
1. The Most Common Culprit: Service Listening on localhost (127.0.0.1)
If your autoserver pymodbus service is configured to listen only on 127.0.0.1 (the container's loopback interface), it will only accept connections from inside its own container—even if other containers are on the same bridge network.
To fix this, you need to configure your server to listen on 0.0.0.0 (all available network interfaces) so it can accept connections from other containers in the network.
For example, in your autoserver's Python code:
from pymodbus.server.sync import StartTcpServer # Replace 127.0.0.1 with 0.0.0.0 to accept external connections StartTcpServer(your_context, address=("0.0.0.0", 5020))
2. Verify Network Connectivity Between Containers
First, confirm both containers are attached to the same monitor-net network:
- Run
docker inspect autoserver | grep Networksanddocker inspect clientperf | grep Networks—both should listmonitor-netas their active network.
Next, test DNS resolution and basic connectivity from the clientperf container:
# Exec into the clientperf container docker exec -it clientperf bash # Ping the autoserver by name (Docker's internal DNS should resolve this to its IP) ping autoserver # Test if port 5020 is open using netcat nc -zv autoserver 5020
If ping works but nc fails, the issue is definitely with the autoserver's service not listening correctly (see step 1). If ping fails, double-check your Docker Compose config to ensure both services are explicitly attached to monitor-net.
3. Fix the Race Condition with depends_on
The depends_on directive only ensures the autoserver container starts before clientperf—it doesn't wait for the pymodbus service inside autoserver to be fully ready. This means your client script might be trying to connect before the server finishes initializing.
Add a wait-for-ready logic to your clientperf service:
- Option 1: Use a tool like
wait-for-it(install it in your clientperf Dockerfile):
Then update your Docker Compose command for# In clientperf's Dockerfile RUN apt-get update && apt-get install -y wait-for-itclientperf:clientperf: # ... other config ... command: wait-for-it autoserver:5020 -- python your_script.py - Option 2: Add a retry loop directly in your Python client code:
from pymodbus.client.sync import ModbusTcpClient import time host = 'autoserver' client = ModbusTcpClient(host, port=5020) # Retry connection 5 times with 2-second delays connected = False for _ in range(5): if client.connect(): connected = True break time.sleep(2) if not connected: raise Exception("Failed to connect to autoserver after retries")
4. Double-Check Port Listening Status
Ensure your autoserver is actually listening on port 5020:
- Exec into the autoserver container and run:
You should see output showingnetstat -tulpn | grep 50200.0.0.0:5020(not127.0.0.1:5020). If nothing appears, your server isn't starting correctly—check the container logs withdocker logs autoserverfor startup errors.
Final Notes
- You don't need
portsmapping in your Compose config for inter-container communication—exposeis sufficient (it declares the port is in use, and containers on the same network can access it directly). - Using the service name
autoserveris the correct approach (Docker's internal DNS resolves service names to container IPs in bridge networks)—avoid hardcoding IPs since they can change on container restart.
内容的提问来源于stack exchange,提问作者19mike95

