Skip to content
Joey Wang
Menu

Search

DevOps and Reliability

localhost vs 127.0.0.1 vs 0.0.0.0: Network Binding Explained

Why localhost, 127.0.0.1, 0.0.0.0, and * behave differently for MySQL clients and services, and how to find and fix a local port conflict between Docker and SSH.

· 2 min read

database #mysql#networking#docker#ssh

Audio summary

Running a Dockerized database alongside an SSH tunnel to a remote one, both on the same local port, produces confusing failures: the wrong service answers, or one client works while another times out. That comes down to what address each service actually binds to and which one your client resolves to.

Localhost vs. 127.0.0.1

TermTypeIP AddressMySQL Client Behavior
localhostHostnameUsually 127.0.0.1Often tries a Unix socket connection (not TCP/IP), which can fail for Docker or SSH tunnels.
127.0.0.1IPv4 Loopback127.0.0.1Always forces a TCP/IP connection (recommended for local testing).

Step 2: Understanding 0.0.0.0 and * Bindings

These addresses specify which network interfaces a service should listen on.

TermMeaningInterfaces Covered
0.0.0.0IPv4 WildcardListens on all available IPv4 interfaces, including 127.0.0.1 and your external network IP.
*Shorthand WildcardActs the same as 0.0.0.0 or :: (IPv6 wildcard) in most contexts: listens on all interfaces.

Step 3: The Port Conflict Scenario & Identifying the Full Command

A port conflict is often avoided because two services listen on different interfaces, such as one on the universal 0.0.0.0:3306 and one on the specific 127.0.0.1:3306.

To confirm exactly which process is which, you must inspect the full command.

Identifying the Full Process Command

The lsof tool shows the PID, but the ps tool shows the full command associated with that PID.

  1. Run lsof to find the PIDs listening on the port (e.g., 3306):

    sudo lsof -i :3306 -t
  2. Run ps to see the full command for those PIDs:

    ps -fp $(sudo lsof -i :3306 -t)
Command Snippet in ps OutputService Confirmed
docker-proxy -host-ip 0.0.0.0 -container-port 3306 ...Docker Container
ssh -L 3307:localhost:3306 user@...SSH Tunnel
/usr/sbin/mysqld --daemonize --pid-file=...Local/Host MySQL Server

Step 4: Connecting to the Correct MySQL Instance

Use the -h (host) and -P (port) flags on the mysql client to connect explicitly to the correct service.

  • To Docker (using the global binding): Connect using your machine’s actual network IP address (e.g., 192.168.1.10) to ensure you hit the Docker proxy.

    mysql -h 192.168.1.10 -P 3306 -u docker_user -p
  • To SSH Tunnel (using the loopback binding): Connect using the loopback IP address.

    mysql -h 127.0.0.1 -P 3306 -u remote_user -p

Step 5: Avoid the Conflict Entirely

To maintain a stable development environment, always configure a unique host port for each service.

ServiceHost PortSSH Command / Docker ConfigMySQL Connection Command
Docker DB3306-p 3306:3306mysql -h 127.0.0.1 -P 3306 -u user -p
SSH Tunnel3307ssh -L 3307:remote_db:3306 user@hostmysql -h 127.0.0.1 -P 3307 -u user -p