Workspaces in PhpStorm
Reproducible development environments are not a luxury, they are a prerequisite for stable teams and reliable CI results. Dev Containers and Docker-based workspaces in PhpStorm combine containerized environments with full IDE comfort: autocompletion, navigation, debugging and refactoring run inside the container, while the editor stays local.
Table of Contents
- 1. Dev Container vs. Docker interpreter: making the right choice
- 2. Configuring devcontainer.json for PHP projects
- 3. PhpStorm Remote Development: the IDE backend inside the container
- 4. Setting up the PHP interpreter and tools inside the container
- 5. Dev Container for Magento 2 with the Mark Shust stack
- 6. Configuring XDebug inside the Dev Container
- 7. Sharing and standardizing Dev Containers across a team
- 8. Comparison: Dev Container approaches at a glance
- 9. Summary
- 10. FAQ
1. Dev Container vs. Docker interpreter: making the right choice
PhpStorm offers two fundamentally different ways to integrate Docker into the development workflow: the Docker interpreter and the Dev Container. The Docker interpreter approach means PhpStorm runs locally and uses a Docker container as an interpreter only for specific operations, such as PHP execution, Composer, and XDebug. The code lives on the host system, PhpStorm reads and analyzes it locally, and only the execution is delegated to the container.
The Dev Container approach with PhpStorm's Remote Development goes further: the IDE backend (JetBrains IDE Backend) runs directly inside the container. The PhpStorm UI stays local, but indexing, analysis, navigation and execution all happen entirely inside the container, with exactly the same packages, PHP version and configuration as in production. This eliminates "works on my machine" problems entirely, but requires a bit more configuration effort.
For teams the choice is usually clear: if all developers use the same OS and PHP versions are stable, the Docker interpreter is enough. If the team uses mixed operating systems, if different projects need different PHP versions, or if new team members should be onboarded quickly, the Dev Container approach is superior in the long run.
2. Configuring devcontainer.json for PHP projects
The devcontainer.json is the central configuration file for Dev Containers, used by both VS Code and JetBrains IDEs. PhpStorm reads this file automatically when it sits in the project's .devcontainer/ directory. The file defines the container image, ports, mounts, extensions (for VS Code), and features, which are reusable installation scripts for common tools.
For PHP projects the most important fields are: image or dockerComposeFile for the base image, postCreateCommand for setup steps after the container starts (e.g. composer install), and forwardPorts for port forwarding. PhpStorm recognizes customizations.jetbrains inside devcontainer.json for IDE-specific settings, such as which plugins should be installed automatically.
Features are predefined, composable installation blocks: ghcr.io/devcontainers/features/php:1 installs PHP with a configurable version. ghcr.io/devcontainers/features/node:1 adds Node.js. ghcr.io/devcontainers/features/docker-in-docker:2 enables Docker commands inside the container itself. These features are versioned and reproducible, a major advantage over manual installation scripts.
// .devcontainer/devcontainer.json for PHP 8.4 / Magento 2 project
{
"name": "Mironsoft PHP 8.4 Dev",
"dockerComposeFile": ["../compose.yaml", "docker-compose.devcontainer.yml"],
"service": "phpfpm",
"workspaceFolder": "/var/www/html",
"forwardPorts": [80, 443, 9003],
"postCreateCommand": "composer install --no-interaction",
"remoteUser": "app",
"customizations": {
"jetbrains": {
"backend": "PhpStorm",
"plugins": [
"com.jetbrains.php",
"org.jetbrains.plugins.phpstorm-remote-interpreter"
]
}
},
"features": {
"ghcr.io/devcontainers/features/php:1": {
"version": "8.4",
"installComposer": true
},
"ghcr.io/devcontainers/features/node:1": {
"version": "22"
}
},
"mounts": [
"source=${localWorkspaceFolder}/src,target=/var/www/html,type=bind"
]
}
3. PhpStorm Remote Development: the IDE backend inside the container
PhpStorm's Remote Development feature (since 2022.3) lets you run the IDE backend, the server part of the IDE responsible for indexing and analysis, directly inside a Docker container or on a remote server. The client part (UI) stays local. The connection happens over SSH or directly via Docker.
Getting started: "File > Remote Development > Dev Containers > Open" or via the Gateway window. PhpStorm detects devcontainer.json files in the current project and offers to start the container and install the IDE backend inside it. On the first run PhpStorm downloads the JetBrains IDE Backend package into the container, which takes a few minutes but happens automatically on subsequent updates.
Once started, the IDE behaves identically to a local installation: all shortcuts work, all tool windows are available, and static analysis runs on the container's files. The difference: Ctrl+Click on a class navigates to the container filesystem version of the file, XDebug connects directly to the container's PHP process, and Composer runs against the container PHP. For a Magento project this means PhpStorm indexes the actual Magento source files inside the container, with the exact PHP version and all installed extensions.
4. Setting up the PHP interpreter and tools inside the container
Even without full Remote Development, the PHP interpreter can point at a Docker container. Under "Settings > PHP > CLI Interpreter > Add > Docker / Docker Compose" you select the service from docker-compose.yml (e.g. phpfpm) and the PHP path inside the container. PhpStorm connects to the container when the dialog opens and reads the available interpreters automatically.
With the Docker interpreter set as the PHP interpreter, the following also work automatically: PHPUnit (tests run inside the container), PHPStan (analysis runs inside the container with the packages found there), PHP CS Fixer and PhpCS (formatting according to the container configuration), and XDebug (if configured in the container). The developer does not need to install any tools locally, everything comes from the container.
A practical note for Magento: the generated/ folder in the Magento root contains automatically generated classes (interceptors, factories). These only exist after running bin/magento setup:di:compile, i.e. after an action inside the container. When PhpStorm accesses the container files directly (Remote Development), these classes are immediately navigable. With local access via the Docker interpreter, the generated/ folder must be marked as a library root so PhpStorm indexes it.
# docker-compose.devcontainer.yml, extends compose.yaml for Dev Container
version: '3.9'
services:
phpfpm:
# Add dev-only tools not needed in production
build:
context: .
dockerfile: Dockerfile.dev
environment:
XDEBUG_MODE: "develop,debug"
XDEBUG_CONFIG: "client_host=host.docker.internal client_port=9003"
PHP_IDE_CONFIG: "serverName=mironsoft-local"
volumes:
# Persist Composer cache between container rebuilds
- composer_cache:/root/.composer/cache
# Mount SSH keys for private Composer repositories
- ${HOME}/.ssh:/root/.ssh:ro
ports:
- "9003:9003" # XDebug
volumes:
composer_cache:
# PhpStorm: Settings > PHP > CLI Interpreter > Add > Docker Compose
# Service: phpfpm
# PHP executable: /usr/local/bin/php
# Detected: PHP 8.4.x with Xdebug 3.x
5. Dev Container for Magento 2 with the Mark Shust stack
The Mark Shust stack for Magento (docker-magento) already ships with all necessary services: phpfpm, nginx, db (MySQL), redis, elasticsearch and optionally rabbitmq. A Dev Container for this setup extends the existing Compose files with a specific devcontainer.json and a docker-compose.devcontainer.yml that overrides dev-specific settings without touching the production stack.
Important adjustments for the Magento Dev Container setup: the phpfpm service needs XDebug (not included in production images), SSH keys for Composer (private Adobe Commerce packages), and an increased PHP memory limit for running the IDE backend. The workspaceFolder in devcontainer.json points to /var/www/html, the Magento root inside the container.
Once the Dev Container starts, PhpStorm automatically begins indexing. For a Magento project with 30,000+ PHP files (core, modules, vendor), the first indexing pass takes 10 to 20 minutes. After that it is cached inside the container and updated incrementally on filesystem changes. For better performance it is worth marking generated/, var/ and pub/static/ as excluded directories, since these contain no navigable source files and unnecessarily lengthen indexing time.
6. Configuring XDebug inside the Dev Container
XDebug inside a Dev Container requires a bit more configuration effort than a local setup, because PhpStorm and PHP run in different network namespaces. The XDebug client (PhpStorm) is on the host, the XDebug server (PHP) is inside the container. The connection has to go from the container to the host, which happens via host.docker.internal on macOS and Windows, or via the host gateway IP on Linux.
The critical XDebug settings inside the container: xdebug.client_host=host.docker.internal (or the gateway IP), xdebug.client_port=9003, xdebug.mode=debug and xdebug.start_with_request=yes for automatic debugging without a browser extension. In PhpStorm, port 9003 must be configured under "Settings > PHP > Debug". Under "Settings > PHP > Servers" a server is created with the name from PHP_IDE_CONFIG=serverName=..., along with path mappings between host paths and container paths.
Path mappings are the most common stumbling block: PhpStorm sees the files under the host path (e.g. /home/user/project/src), while PHP runs them under the container path (e.g. /var/www/html). Without a correct mapping, PhpStorm cannot match XDebug breakpoints to the right files. With Remote Development this problem disappears entirely, since PhpStorm works directly with the container paths.
<?php
// XDebug configuration in php.ini / conf.d/xdebug.ini (inside container)
// zend_extension=xdebug
// xdebug.mode=develop,debug
// xdebug.client_host=host.docker.internal
// xdebug.client_port=9003
// xdebug.start_with_request=yes
// xdebug.log=/tmp/xdebug.log
// xdebug.log_level=7
// PhpStorm: Settings > PHP > Servers > Add
// Name: mironsoft-local (must match PHP_IDE_CONFIG serverName)
// Host: localhost
// Port: 80
// Debugger: XDebug
// Path mappings:
// /home/mir/development/mironsoft/src -> /var/www/html
// Verify connection: Run > Start Listening for PHP Debug Connections
// Then: curl http://localhost/health
// PhpStorm should show "Incoming connection from XDebug" dialog
// Common issue: Linux host.docker.internal not available
// Solution: add to docker-compose.devcontainer.yml:
// extra_hosts:
// - "host.docker.internal:host-gateway"
7. Sharing and standardizing Dev Containers across a team
The biggest benefit of Dev Containers for teams is reproducibility: the devcontainer.json is checked into the repository and available to every developer. A new team member clones the repository, opens it in PhpStorm, confirms "Reopen in Container", and has a fully configured development environment within a few minutes. No manual PHP installation, no local Magento setup, no "works on my machine but not on yours" discussions.
For team standardization it is worth extending devcontainer.json with the following elements: postCreateCommand for composer install and initial Magento configuration, postStartCommand for services that need to be initialized on every container start, and waitFor to control the order of initialization steps. Environment variables for secrets (API keys, database passwords) come from .env files that are not checked into the repository.
A well-structured Dev Container setup for Magento contains: the devcontainer.json in the repository, a separate docker-compose.devcontainer.yml that extends the production Compose file, a Dockerfile.dev with dev-specific tools (XDebug, Composer, shell tools), and a .devcontainer/setup.sh script for the postCreateCommand. The setup script runs composer install, bin/magento setup:upgrade and other initialization steps once, right after the container build.
8. Comparison: Dev Container approaches at a glance
| Aspect | Docker interpreter | Remote Dev (Gateway) | Recommendation |
|---|---|---|---|
| IDE performance | Local, fast | Depends on container hardware | Docker interpreter for strong local machines |
| Environment consistency | Analysis local, execution in container | 100% in container | Remote Dev for consistency |
| Path mappings | Manual configuration | Automatic (container paths) | Remote Dev for XDebug |
| Onboarding effort | Interpreter configuration per developer | devcontainer.json is enough | Remote Dev for teams |
| Setup complexity | Low | devcontainer.json + Compose | Worth a one-time investment |
Mironsoft
Docker setups, Magento 2 and PhpStorm infrastructure
Set up Dev Containers for your PHP team?
We build reproducible Dev Container setups for Magento and PHP projects, from devcontainer.json all the way to full PhpStorm integration with XDebug.
Dev Container setup
devcontainer.json, Docker Compose, Dockerfile.dev for Magento and PHP projects
IDE configuration
Configuring PhpStorm Remote Development, interpreters, and XDebug path mappings
Team onboarding
Onboarding documentation and setup scripts for new team members
9. Summary
Dev Containers and Docker-based workspaces in PhpStorm solve the fundamental problem of development environment inconsistency. The devcontainer.json defines the environment declaratively and reproducibly, checked into the repository and available to every developer. PhpStorm's Remote Development brings the IDE backend directly into the container, so indexing, analysis and navigation all work with the exact container packages and the exact container PHP version.
For Magento projects using the Mark Shust stack the approach is clear: existing Compose files are extended with a docker-compose.devcontainer.yml, XDebug is configured for container-to-host connections, and devcontainer.json defines a postCreateCommand for automatic initialization. The result: new team members are productive in under 30 minutes, without manual PHP installation or a local Magento setup. Works on every machine, because the machine is the container.
Dev Containers in PhpStorm: the essentials at a glance
devcontainer.json
Check .devcontainer/devcontainer.json into the repository. Use features for PHP, Node, and Docker-in-Docker. postCreateCommand for composer install and Magento setup.
Remote Development
File > Remote Development > Dev Containers. IDE backend runs inside the container. No path mapping problems, no version conflicts between host and container.
XDebug in the container
client_host=host.docker.internal (Linux: extra_hosts: host.docker.internal:host-gateway). Server name in PHP_IDE_CONFIG must match the server name in PhpStorm settings.
Team onboarding
devcontainer.json in the repo plus Dockerfile.dev plus docker-compose.devcontainer.yml. New developers: clone the repository, confirm "Reopen in Container", wait.