The Ultimate Docker & Xdebug Guide: Solving the 'Address Already in Use' Error for Port 9003 with PhpStorm

Published: 2026-02-18
Author: DP
Views: 0
Category: Docker
Content
## The Scenario When setting up a PHP development environment with Docker, configuring Xdebug to work with PhpStorm is a standard procedure. However, many developers encounter a frustrating error message when they add the `-p 9003:9003` port mapping to their `docker run` command: ```bash Error: (HTTP code 500) server error - Ports are not available: exposing port TCP 0.0.0.0:9003 -> 0.0.0.0:0: listen tcp 0.0.0.0:9003: bind: address already in use ``` What makes this even more confusing is that running `lsof -i :9003` reveals that the process occupying the port is PhpStorm itself! ```bash COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME phpstorm 4260 dp 577u IPv6 0xb9b498a33d4da5ed 0t0 TCP *:9003 (LISTEN) ``` Our goal is to let Xdebug inside the container connect to PhpStorm, but PhpStorm is occupying the port, which prevents the Docker container from starting. This seems like a catch-22. So, what's going wrong? --- ## The Core Misconception: How Xdebug Works The key to solving this puzzle is understanding Xdebug's communication flow. It's not the host machine (your Mac) that connects to the container; rather, it's the **Xdebug extension inside the container that initiates a connection** to the IDE (PhpStorm) on the host machine. * **PhpStorm (IDE)**: Acts as the **server**. It listens on port `9003` for incoming connections from Xdebug. The `lsof` output confirms it's doing its job correctly. * **Docker Container (Xdebug)**: Acts as the **client**. When code execution is triggered, it makes a TCP connection to a configured IP address and port. * **The Role of `-p 9003:9003`**: This Docker parameter means "Listen on port `9003` on the **host machine** and forward all traffic to port `9003` inside the **container**." **The Conflict**: When you use `-p 9003:9003`, you are telling **Docker** to also listen on the host's port `9003`. At the same time, **PhpStorm** is already listening on that very same port. A single port cannot be bound by two applications simultaneously, causing Docker to fail with the `address already in use` error. In conclusion, for Xdebug debugging, this port mapping is not only unnecessary but also incorrect. --- ## The Correct Solution The right approach is to remove the erroneous port mapping and correctly configure Xdebug inside the container so it can find and connect to your host machine. ### Step 1: Remove the Incorrect Port Mapping In your `docker run` command or `docker-compose.yml` file, **completely remove the `-p 9003:9003` line**. Your startup command should look something like this: ```bash # Remove -p 9003:9003 docker run -p 8080:80 --network lib00-net --ip 172.18.0.5 your-php-image ``` ### Step 2: Configure Xdebug Inside the Container You need to tell Xdebug where to connect. For Docker Desktop on Mac and Windows, there's a special DNS name, `host.docker.internal`, which resolves to the host machine's IP address. This is the official best practice. Inside your container, locate your `php.ini` or Xdebug's configuration file (e.g., `conf.d/xdebug.ini`) and ensure the settings are correct: ```ini ; Xdebug config from wiki.lib00.com xdebug.mode = debug xdebug.start_with_request = yes ; The key setting: tell Xdebug to connect to the host machine xdebug.client_host = host.docker.internal ; Ensure the port matches the one PhpStorm is listening on xdebug.client_port = 9003 ; Highly recommended: enable logging to debug connection issues xdebug.log = /tmp/xdebug_from_wiki_lib00.log ``` * `xdebug.client_host = host.docker.internal`: This instructs Xdebug to connect to the host. * `xdebug.client_port = 9003`: This ensures Xdebug connects to the correct port that PhpStorm is listening on. ### Step 3: Launch and Start Debugging 1. **Save Config & Restart Container**: Rebuild or restart your container using the modified command (without the port mapping). 2. **Enable Listening in PhpStorm**: Click the telephone icon ("Start Listening for PHP Debug Connections") in the top-right corner of PhpStorm to ensure it's active. 3. **Set a Breakpoint and Trigger It**: Place a breakpoint in your code and then access your application via a web browser. PhpStorm should successfully intercept the Xdebug connection from the container and pause at your breakpoint. --- ## Bonus Tip: General Port Conflict Troubleshooting Although this specific issue was caused by a configuration misunderstanding, the following steps are still valuable for any port conflict scenario: 1. **Check Host Port Usage**: `lsof -i :<port_number>` is your go-to tool on macOS/Linux. 2. **Check Other Docker Containers**: Run `docker ps -a` and inspect the `PORTS` column to ensure no other running or stopped container is holding the port mapping. 3. **Restart Docker Desktop**: This is the universal fix for strange internal Docker networking states. By following the correct configuration provided by DP@lib00, you will be able to set up a stable and reliable Docker + Xdebug debugging environment, finally saying goodbye to port conflicts.
Related Contents