PhpStorm: Local, Docker, or Remote Interpreter — Choosing How to Run and Debug PHP
A decision guide for PhpStorm's three PHP execution models — local interpreter, Docker-based remote interpreter, and JetBrains Gateway remote development — with configuration, Xdebug path-mapping fixes, and validation steps.
27 Aug 2025, 18:27 UTC

The decision and its constraints
PhpStorm can execute PHP three ways: a local interpreter installed on your machine, a remote interpreter inside Docker/Docker Compose (or SSH/WSL), or full remote development where the IDE backend itself runs on a server via JetBrains Gateway. The choice determines whether your tests, debugging sessions, and code-quality tools run against the same PHP version and extensions as production — or against whatever happens to be on your laptop.
The constraints that matter: how closely your environment must match production, how big the codebase is, how fast your machine is, and how much configuration drift your team tolerates. Pick the simplest model that satisfies the production-parity requirement.
Comparing the three execution models
| Model | Setup cost | Production parity | Performance | Main risk |
|---|---|---|---|---|
| Local interpreter | Lowest | Poor — host PHP version and extensions usually diverge from deployment | Fastest file access and indexing | Tests pass locally but fail in CI/production |
| Docker / Docker Compose interpreter | Moderate — needs a Docker server connection and image | High — runs the same image as production | Good; container startup adds small overhead | Path-mapping errors silently break debugging |
| Remote development (Gateway) | Highest — licensed backend, server resources, network dependency | High — code lives and runs on the server | Best for huge codebases or weak laptops | Network outages stall all work; not a free fix |
Trade-offs in practice
Local interpreter. Fine for scratch scripts and quick syntax checks. The problem is drift: your host may run PHP 8.3 with a different set of extensions than the production container, so PHPUnit results and even language behavior can differ. Treat it as a convenience, not a source of truth.
Docker-based interpreter. PhpStorm runs CLI scripts, PHPUnit, and Xdebug sessions inside a container from your chosen image. This is the pragmatic default for most teams: tests and debugging execute against the production image while editing and indexing stay local and fast. The cost is configuration — a Docker server connection, an interpreter entry, and path mappings.
Gateway remote development. Indexing and language analysis move to the server, which helps when the codebase is too large for a laptop or the local machine is slow. It requires a licensed backend, adequate server CPU/RAM, and a reliable network. Adopt it when local indexing is demonstrably the bottleneck, not preemptively.
One subtlety: Composer, PHP CS Fixer, PHPStan/Psalm, and test runners can each be pointed at a different interpreter. Mixing is possible but invites drift — a fixer running on local PHP 8.3 reformatting code for a PHP 8.1 container is a real failure mode. Keep all tools on one interpreter unless you have a specific reason.
Configuring a Docker Compose interpreter
These steps apply to recent PhpStorm versions; the exact UI labels vary between releases, so verify against your installed version.
- Ensure Docker is running and your
docker-compose.ymldefines the PHP service (for example, a service namedappbuilt from your production image). - In PhpStorm, open Settings > PHP. Next to CLI Interpreter, click the ... button, then + > From Docker, Vagrant, VM, WSL, Remote....
- Choose Docker Compose, select your compose file, and pick the service (
app). PhpStorm detects the PHP binary inside the container. - Confirm the detected PHP version and extensions in the interpreter dialog match what the image provides.
- Under Settings > PHP > Test Frameworks, point PHPUnit at this interpreter and set the path to
vendor/autoload.phpas seen inside the container (for example/var/www/html/vendor/autoload.php).
Making Xdebug actually stop at breakpoints
The most common failure is breakpoints being ignored with no error. The cause is almost always a missing or wrong path mapping between host project files and container paths.
- Check the Xdebug major version in your image (
php -vinside the container shows it). Xdebug 3 changed default ports (9003 instead of 9000) and usesmodeinstead of Xdebug 2's boolean flags — yourphp.inisettings must match the installed major version. - A typical Xdebug 3 container config:
xdebug.mode=debug,xdebug.client_host=host.docker.internal,xdebug.start_with_request=yes. - In Settings > PHP > Servers, create a server entry for the debug connection and enable Use path mappings, mapping your local project root to the container path (for example
/home/me/project→/var/www/html). Without this, PhpStorm cannot correlate incoming debug frames with your files.
Validating the setup
- Version check: create a scratch file with
<?php phpinfo();(or runphp -vvia the interpreter) and use Run. Confirm the reported PHP version matches the production image, not your host. - Debug check: set a breakpoint in a trivial script, click the Start Listening for PHP Debug Connections icon, and run the script. Execution should pause. If it does not, check the Servers path mapping first, then the Xdebug port and mode.
- Parity check: run the project's PHPUnit suite through the configured interpreter, then run
vendor/bin/phpunitmanually inside the container (docker compose exec app vendor/bin/phpunit). Pass/fail results should be identical; divergence means the interpreter is not actually the container you think it is.
Limitations
Interpreter configuration dialogs differ across PhpStorm releases, so treat menu paths above as approximate and confirm in your version. Gateway remote development needs a licensed backend and a well-provisioned server; it is not a performance fix you get for free. And a Docker interpreter only delivers parity if the image genuinely matches production — an outdated local image recreates the drift problem inside a container.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.