from the SSH host to the Xdebug tunnel
Remote development in PhpStorm is more than SFTP upload and hoping for the best. With the right SSH setup, a configured remote interpreter, port forwarding for Xdebug, and the JetBrains Remote Development mode, you can work on distant servers with the same IDE experience as locally.
Table of Contents
- 1. Remote development: typical scenarios and requirements
- 2. Configuring an SSH connection in PhpStorm
- 3. Setting up a remote PHP interpreter via SSH
- 4. SFTP deployment and automatic synchronization
- 5. Debugging Xdebug over an SSH tunnel
- 6. Jump hosts and gateway configurations
- 7. JetBrains Remote Development (backend IDE on the server)
- 8. Remote terminal and tools in the integrated terminal
- 9. Remote development approaches compared
- 10. Summary
- 11. FAQ
1. Remote development: typical scenarios and requirements
Remote development with PhpStorm covers several fundamentally different scenarios. The most common: a Magento 2 staging server sits on a Linux host where you need to test changes or debug directly without running through the full deploy cycle. A second scenario: developing on a powerful remote server instead of a weaker local laptop. A third: the code runs inside a Docker container on a remote host and access happens exclusively over SSH.
The requirements differ considerably depending on the scenario. For staging debugging you need a remote interpreter, port forwarding for Xdebug, and possibly SFTP sync. For full remote development on a server you need either the JetBrains Remote Development backend or a well-configured SFTP mapping with a remote interpreter. For Docker on a remote host, an SSH tunnel into the Docker socket or a dedicated Docker remote host is added on top. Each of these setups has different complexity and different failure modes.
The first step is always the same: a stable SSH connection with public key authentication, ideally through the SSH agent with ForwardAgent, so that keys don't need to be stored on the remote server. PhpStorm uses the operating system's OpenSSH client or its own SSH implementation, both of which can work with ~/.ssh/config, so host aliases defined once are available everywhere.
2. Configuring an SSH connection in PhpStorm
PhpStorm reads SSH configuration from ~/.ssh/config and shows known hosts in the SSH dialog. For a new connection, navigate to Settings → Tools → SSH Configurations and set the host, port, username, and authentication method there. The recommended method is "OpenSSH config and authentication agent": it delegates key management to the SSH agent and also allows the use of FIDO2 keys and hardware security keys that PhpStorm itself doesn't support directly.
For hosts behind a jump host or bastion server, the ProxyJump configuration in ~/.ssh/config is the cleanest solution. PhpStorm also supports direct jump host configuration in the SSH settings, but the ssh_config variant is more portable and usable by all tools. Important: SSH connections in PhpStorm are reopened per function, meaning separate connections for the remote interpreter, SFTP, and the terminal. ControlMaster multiplexing in ~/.ssh/config significantly reduces latency when there are multiple simultaneous connections.
# ~/.ssh/config - Optimized for PhpStorm Remote Development
# Multiplexing: multiple PhpStorm connections through one SSH channel
Host staging-magento
HostName staging.mironsoft.de
User deploy
Port 22
IdentityFile ~/.ssh/id_ed25519_mironsoft
ForwardAgent yes
# ControlMaster: reuse the connection (reduces latency)
ControlMaster auto
ControlPath ~/.ssh/cm-%r@%h:%p
ControlPersist 10m
# Keepalive: keep the connection alive during idle periods
ServerAliveInterval 30
ServerAliveCountMax 3
# Jump host for hosts behind a bastion
Host internal-dev
HostName 10.10.1.50
User developer
ProxyJump bastion.mironsoft.de
IdentityFile ~/.ssh/id_ed25519_mironsoft
ForwardAgent yes
Host bastion.mironsoft.de
HostName bastion.mironsoft.de
User jump
Port 2222
IdentityFile ~/.ssh/id_ed25519_bastion
3. Setting up a remote PHP interpreter via SSH
With a configured SSH host, a remote interpreter can be defined under Settings → PHP → CLI Interpreter → Add → SSH Credentials. PhpStorm connects to the server, runs php --version and php -r "phpinfo();", and displays the detected PHP version, installed extensions, and php.ini paths. This interpreter can then be used for all quality tools: PHPStan, PHPUnit, PHPCS, all of them then run on the remote host with the PHP configuration found there.
For Magento 2 staging servers this means: PHPStan analyzes with the PHP version and extensions installed on the staging server. PHPUnit runs with the Magento bootstrap of the remote system. That eliminates the most common cause of discrepancies between local development and staging. The only downside: every tool invocation requires an SSH connection, which adds latency. For interactive code analysis (the PHPStan plugin) that's too slow; a local interpreter remains the better choice there. For targeted runs before a commit, the remote interpreter is ideal.
4. SFTP deployment and automatic synchronization
SFTP deployment in PhpStorm is configurable under Settings → Build, Execution, Deployment → Deployment. You create a server with an SFTP connection, define the mapping between the local project directory and the remote path, and optionally enable "Automatic Upload on Save". That means every saved file is uploaded to the remote server immediately. Combined with a remote interpreter that executes code there, this produces a workflow where changes are instantly testable.
The weakness of this approach: automatic upload on save also uploads files you wouldn't yet commit, half-finished work, debugging code, temporary changes. That's dangerous on a staging server with live data. It's better to use Upload on Explicit Command (Ctrl+Shift+X) or an upload profile that only synchronizes specific directories and is triggered explicitly. For Magento projects it's also advisable to exclude the var/, generated/, and pub/static/ directories from SFTP sync.
5. Debugging Xdebug over an SSH tunnel
Xdebug works in "debug host" mode: PHP on the remote server connects back to the developer's machine for the Xdebug connection. That assumes the remote server can reach the developer's machine, which is often not the case behind NAT or in cloud environments. The solution is a reverse SSH tunnel: local port 9003 (the Xdebug default) is forwarded over the SSH connection to the remote server, so that PHP there can connect via localhost:9003, which goes through the tunnel back to the local IDE.
The SSH command for the reverse tunnel: ssh -R 9003:localhost:9003 staging-magento. The remote server then connects via localhost:9003, the tunnel forwards that to local port 9003, where PhpStorm is waiting for incoming Xdebug connections. In the PHP configuration on the remote server: xdebug.client_host=localhost (not the external IP) and xdebug.client_port=9003. For PhpStorm: configure path mappings between remote paths and local paths so breakpoints are correctly mapped to the remote file.
# xdebug.ini on the remote staging server (PHP 8.4)
[xdebug]
zend_extension=xdebug.so
xdebug.mode=debug
; Connects back to the local IDE via a reverse SSH tunnel
xdebug.client_host=127.0.0.1
xdebug.client_port=9003
xdebug.start_with_request=trigger
; Trigger via cookie: XDEBUG_SESSION=PHPSTORM
; Or via GET parameter: ?XDEBUG_SESSION=PHPSTORM
xdebug.idekey=PHPSTORM
xdebug.log=/var/log/php/xdebug.log
xdebug.log_level=3
# SSH command for the reverse tunnel (run locally):
# ssh -R 9003:localhost:9003 -N staging-magento
# -R: remote port 9003 to local 9003
# -N: no command execution, tunneling only
# For a persistent tunnel: autossh -M 0 -R 9003:localhost:9003 -N staging-magento
6. Jump hosts and gateway configurations
In corporate environments the development server often sits behind a bastion host that is the only SSH entry point from outside. PhpStorm supports jump host configurations directly in the SSH settings: you define a "proxy" SSH host through which the actual connection is established. This corresponds to the ProxyJump parameter in ssh_config. The advantage of the ssh_config variant: it also works in the integrated terminal, for external tools, and for SFTP connections without any further configuration.
For multi-stage proxy chains (bastion to intermediate to target) ControlMaster is especially important: without it, PhpStorm opens a separate chain of SSH connections for each function (editor, remote interpreter, SFTP, terminal). With ControlMaster the first connection is established and all subsequent ones reuse the existing channel, which reduces connection setup time from several seconds to milliseconds and eases the load on the bastion server.
7. JetBrains Remote Development (backend IDE on the server)
The JetBrains Remote Development mode (since PhpStorm 2022.3) is a fundamental paradigm shift: instead of having the code locally and synchronizing it to the server via SFTP, the IDE backend runs directly on the remote server. The code lives on the server, the analysis runs on the server, the compiler runs on the server. The local JetBrains client is just a thin client interface that sends keystrokes and receives screen content, similar to RDP but optimized for code editing.
For Magento 2 projects this means: autocompletion, the PHPStan plugin, and all inspections directly use the PHP installation on the server. No path mapping needed, no SFTP sync, no discrepancy between local and remote code. Remote Development mode can be started via Remote Development in the JetBrains Toolbox App or directly in PhpStorm via File → Remote Development → SSH. The server needs to be reachable and have enough RAM (at least 4 GB for the IDE backend), but no X11 or desktop environment.
8. Remote terminal and tools in the integrated terminal
The integrated terminal in PhpStorm can be opened directly with an SSH connection as a remote shell. That replaces the separate terminal window for many tasks. Particularly useful in Magento projects: you can run bin/magento cache:flush or bin/magento setup:upgrade directly from PhpStorm without switching to another window. The terminal window is docked in the IDE and shows the output right next to the code.
For Magento deployment workflows on remote servers, you can set up remote shell scripts as External Tools that execute a sequence of commands via SSH. The script then runs entirely on the remote side, and the output appears in PhpStorm's Run panel. That way the full Magento deploy cycle (static content deploy, cache flush, setup upgrade) can be started as a run configuration with a single click, without having to type SSH commands manually.
9. Remote development approaches compared
| Approach | Code location | IDE experience | Suitable for |
|---|---|---|---|
| SFTP + Remote Interpreter | Local + remote (sync) | Medium | Staging debugging, checking CI parity |
| SSH Remote Interpreter | Local | Good (local) | Quality tools with remote PHP |
| JetBrains Remote Dev | Remote | Complete | Full remote development |
| Docker Remote Host | Container (remote) | Good | Docker-based projects on a remote host |
| Xdebug via SSH tunnel | Remote (debugging) | Full debugging | Staging bugs with a full debugger |
For most Magento 2 developers a combination is optimal: local development with Docker, a remote interpreter for staging checks, and Xdebug over an SSH tunnel for cases where a staging-specific bug needs to be debugged. JetBrains Remote Development makes sense when the local machine is too weak for the project or when regulatory requirements demand that code not be stored locally.
Mironsoft
DevOps, remote development setups, and Magento 2 infrastructure
Setting up remote development for your team?
We configure SSH connections, remote interpreters, Xdebug tunnels, and SFTP sync for your PhpStorm environment, with bastion host support and JetBrains Remote Development for demanding setups.
SSH Setup
ControlMaster, jump hosts, agent forwarding, and multiplexing for fast remote connections
Xdebug Tunnel
Reverse SSH tunnel for staging debugging behind NAT and firewalls
Remote Dev
Setting up and securing JetBrains Remote Development on powerful servers
10. Summary
Remote development with PhpStorm ranges from a simple SFTP upload all the way to a full JetBrains Remote Development environment where the IDE backend runs on the server. The common denominator is a cleanly configured SSH connection with public key authentication, ControlMaster multiplexing, and, where needed, jump host support. Building on that, remote interpreters for quality tools, Xdebug tunnels for staging debugging, and SFTP sync for fast feedback can all be set up.
For Magento 2 projects the recommended combination is: local Docker development for the daily coding rhythm, a remote interpreter for staging CI parity, and Xdebug over an SSH tunnel for staging-specific bugs that can't be reproduced locally. JetBrains Remote Development pays off for teams that want to develop on powerful remote servers or where code locality isn't possible for compliance reasons.
Remote Development in PhpStorm: The Essentials at a Glance
SSH Configuration
~/.ssh/config with ControlMaster, ForwardAgent, and ProxyJump for jump hosts. ControlPersist 10m reduces connection latency for all PhpStorm functions.
Xdebug Tunnel
ssh -R 9003:localhost:9003 for a reverse tunnel. xdebug.client_host=127.0.0.1 on the remote server. Configure path mappings in PhpStorm.
Remote Interpreter
Settings → PHP → CLI Interpreter → SSH. PHP version and extensions on the remote host. Ideal for quality tools, too slow for interactive analysis.
JetBrains Remote Dev
IDE backend runs on the server, local client is a thin client. No SFTP sync, no path mapping. At least 4 GB RAM required on the server.
11. FAQ: Remote Development and SSH in PhpStorm
1SFTP deployment vs. JetBrains Remote Development?
2Xdebug behind NAT, how?
3What is ControlMaster and why does it matter?
4Jump hosts supported in PhpStorm?
5Configure path mappings for remote debugging?
6Restrict SFTP upload to specific directories?
7Server requirements for JetBrains Remote Dev?
8Debug a Magento cron job on the remote server?
9Performance: local vs. remote interpreter?
10Keep the SSH tunnel persistent?
Remote development and SSH workflows in PhpStorm can be used efficiently with the right configuration in a Docker Magento setup. The key lies in stable path mappings and a well-configured SSH tunnel for Xdebug.