The workflow that merges local and remote work
When development environments, databases and Docker containers live on a remote server, the quality of the SSH connection decides whether the work feels local or like a constant compromise. With a clean SSH config, VS Code Remote-SSH and targeted port forwarding, the remote server becomes a seamless extension of your own development environment.
Table of Contents
- 1. Why remote development over SSH is standard today
- 2. The SSH config as the foundation for productive connections
- 3. VS Code Remote-SSH: the editor runs local, the code runs remote
- 4. Port forwarding: making remote dev servers reachable locally
- 5. File synchronization: rsync, sshfs and alternatives
- 6. SSH agent forwarding for git and deployment
- 7. Connection multiplexing for faster connections
- 8. Common pitfalls in remote development
- 9. Remote development approaches compared
- 10. Summary
- 11. FAQ
1. Why remote development over SSH is standard today
Many development projects, especially in the Magento and PHP world, need resources that barely fit on a single laptop anymore: several Docker containers, a large database, Elasticsearch and a full web server stack running at the same time. Remote development over SSH solves this by shifting the actual computing load to a powerful server, while the local machine serves only as a thin client window. The result is a consistent environment for the whole team, independent of local hardware.
The second major benefit of remote development lies in the consistency of the environment itself. Instead of every developer maintaining a slightly different local PHP version, different Node module versions, or diverging system libraries, everyone works on the same server with identical configuration. This drastically reduces the classic "it works on my machine" problem, because development and production can share the same system environment.
SSH here is not just a transport mechanism for a terminal session, but the entire foundation of modern remote development tooling. VS Code Remote-SSH, JetBrains Gateway and similar solutions tunnel their complete communication over exactly the same SSH connection that is also used for a simple terminal session. Anyone who masters the basics of SSH configuration benefits from it equally in every one of these tools.
2. The SSH config as the foundation for productive connections
The file ~/.ssh/config is the central building block for efficient remote development, yet it is surprisingly often ignored. Instead of manually specifying host, username, port and key file on every connection, you define a descriptive alias once, through which the server can afterwards be reached with a single short command. This not only saves typing, it also reduces errors, for example accidentally connecting to the wrong server when hostnames look similar.
Particularly valuable for remote development is the ability to also store options for connection stability and speed in the SSH config. The option ServerAliveInterval sends regular keep alive packets so the connection is not dropped by a firewall due to inactivity, while ControlMaster and ControlPersist reuse subsequent connections over an already established channel instead of performing a completely new handshake every time.
# ~/.ssh/config - reusable host aliases for remote development
Host devserver
HostName 203.0.113.42
User deploy
Port 22
IdentityFile ~/.ssh/id_ed25519_devserver
ServerAliveInterval 30
ServerAliveCountMax 3
# Reuse an existing connection instead of a fresh handshake every time
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 10m
Host staging
HostName staging.internal.example.com
User www-deploy
Port 2222
IdentityFile ~/.ssh/id_ed25519_staging
# Jump through a bastion host before reaching the internal server
ProxyJump bastion.example.com
Host bastion.example.com
User jumpuser
IdentityFile ~/.ssh/id_ed25519_bastion
# One command replaces host, user, port and key file:
# ssh devserver
A frequently overlooked detail is the folder ~/.ssh/sockets/, which must already exist for ControlPath, otherwise connection multiplexing silently fails and every connection performs a fresh handshake again. Anyone managing several projects in parallel should create a clearly named host entry for each target system, instead of memorizing IP addresses or ports. This makes daily remote development noticeably faster and less error prone.
3. VS Code Remote-SSH: the editor runs local, the code runs remote
The Remote-SSH extension for VS Code is the entry point into structured remote development for many teams. The principle: the graphical interface of the editor keeps running locally, while a small server process is installed on the target machine that directly executes file access, language servers, terminal sessions and debugging requests on the remote system. The result feels like local work to the developer, even though all the code, all dependencies and the entire build process run remotely.
An important practical advantage of this model is that resource intensive operations, such as indexing a large codebase or compiling assets, happen on the powerful server, not on the often weaker laptop. The extension uses the same SSH connection also used for a normal terminal session, which is why a correctly configured ~/.ssh/config appears directly in VS Code as a connection target, without additional configuration inside the editor.
For Magento projects this approach is especially practical, because the full local Docker environment with PHP-FPM, Elasticsearch, Redis and MySQL no longer needs to be replicated on every single developer laptop. A single, well equipped development server is enough for the entire team, while each developer uses their own isolated working copy in the same server file system via Remote-SSH.
4. Port forwarding: making remote dev servers reachable locally
A central building block of productive remote development is local port forwarding, which makes a service running on the remote server, for example a PHP development server or a Vite instance, reachable in the local browser under localhost. The command ssh -L 8080:localhost:8080 devserver builds a tunnel through which every request to local port 8080 is transparently forwarded to the same numbered port on the server, without ever having to publicly expose the server's port.
VS Code Remote-SSH even automates this step to a large extent: if the extension detects that a process on the server opens a new port, it automatically offers to forward that port locally. For manual situations, for example working directly in the terminal without editor integration, the explicit -L option remains indispensable, especially when several ports need to be forwarded at once.
# Forward a remote dev server to localhost (single port)
ssh -L 8080:localhost:8080 devserver
# Forward multiple ports at once (web server, database, Elasticsearch)
ssh -L 8080:localhost:8080 \
-L 3306:localhost:3306 \
-L 9200:localhost:9200 \
devserver
# Run the forward in the background without opening an interactive shell
ssh -f -N -L 8080:localhost:8080 devserver
# Reverse forwarding: expose a local service to the remote server
# (useful for webhooks that must reach your local machine)
ssh -R 9000:localhost:9000 devserver
A subtle but important difference exists between local and remote forwarding. Local forwarding (-L) makes a remote service reachable locally, while remote forwarding (-R) goes the opposite way and makes a local service reachable on the remote server, for example for webhook testing where an external service needs to reach your own development machine. Both variants run over the same SSH connection and need no additional firewall opening.
5. File synchronization: rsync, sshfs and alternatives
Not every instance of remote development runs through a fully remote editor. Many developers still prefer their local IDE and synchronize files with the server only when needed. For this case, rsync is the most reliable tool because it only transfers changed file parts while correctly preserving permissions, timestamps and symbolic links. A typical watch workflow combines rsync with a file system watcher that syncs automatically on every change.
As an alternative, sshfs offers a way to mount a remote directory directly as a local file system. The advantage: the local IDE appears to work with local files, while all reads and writes actually go through SSH. The downside shows up on unstable connections or with operations touching very many small files, for example browsing a vendor directory, where the latency of every single file system operation becomes noticeable. For such cases, a remotely running editor like VS Code Remote-SSH is usually the significantly more performant choice.
6. SSH agent forwarding for git and deployment
Anyone who wants to run git operations against a private repository on the remote server, or start deployment scripts that themselves need to establish another SSH connection, faces a problem: the private key lives locally but is needed on the server. SSH agent forwarding solves this without ever copying the private key onto the server. With the option ForwardAgent yes in the SSH config, or the flag -A at connection time, the local SSH agent forwards signature requests over the existing tunnel, so the server can perform operations on the user's behalf without ever owning the key itself.
Important for security: agent forwarding should only be enabled for trusted servers, because root access on the target server could theoretically abuse the forwarded signature requests while the connection is active. For daily remote development with your own deployment server, the risk is usually acceptable, but on foreign or multi tenant servers you should be more restrictive and store project specific deploy keys directly on the server instead.
7. Connection multiplexing for faster connections
Every new SSH connection requires a full cryptographic handshake that costs noticeable time, especially with high latency between local machine and server. Connection multiplexing with ControlMaster solves this by keeping the first connection open, and every subsequent connection, for example for a new terminal window or an additional port forward, reuses the same already authenticated channel. The noticeable effect: instead of several seconds of waiting, a second connection opens practically instantly.
For remote development with many short commands, for example repeated rsync runs or git operations over SSH, this speed gain adds up noticeably. Configuration happens centrally in the SSH config with ControlPersist, which defines how long the connection stays open after the last use before it is automatically closed. A value of 10 minutes is a good compromise between speed and resource use on the server for most development sessions.
8. Common pitfalls in remote development
A common pitfall is excessive network latency between local machine and server, which shows up as sluggish input delay with a remotely running editor. VS Code Remote-SSH partially compensates through local buffering of input, but at latencies above roughly 150 milliseconds the work becomes noticeably unpleasant. In such cases, choosing a geographically closer server or switching to a local file synchronization workflow instead of a fully remote editor is worthwhile.
A second pitfall concerns resource contention on shared development servers. When several developers work simultaneously via VS Code Remote-SSH, a single resource hungry language server process, for example for a large TypeScript or PHP codebase, can noticeably slow down the server. Configuring per user resource limits, for example via cgroups or systemd slices, helps prevent a single process from slowing down the entire server.
Third, firewall configuration is often neglected. Anyone using port forwarding for development purposes should ensure that the forwarded ports are not accidentally also directly reachable on the network from the server itself. Since SSH tunnels bind only to localhost by default, the risk is low, but an explicit check with ss -tlnp on the server adds extra safety.
9. Remote development approaches compared
Depending on the project and team size, different approaches to remote development suit different needs. The table below compares the most important options.
| Approach | Latency sensitivity | Setup effort | Best suited for |
|---|---|---|---|
| VS Code Remote-SSH | Medium to high | Low | Large codebases, resource heavy builds |
| rsync watch sync | Low | Medium | Preference for local IDE, unstable connections |
| sshfs mount | High | Very low | Occasional file access, small projects |
| JetBrains Gateway | Medium | Medium | PHPStorm teams sharing a server |
For most Magento and PHP teams, VS Code Remote-SSH or JetBrains Gateway is the most productive solution, because resource intensive operations happen directly on the server. rsync based workflows remain the more robust choice on unstable connections, or when developers absolutely want to keep their familiar local IDE configuration.
Mironsoft
Remote development environments for Magento and PHP teams
A development server the whole team can use productively?
We set up remote development servers with SSH config, VS Code Remote-SSH and clean resource management, so your team works in a consistent environment independent of local hardware.
Server setup
Development servers with clean SSH configuration and access control
Team workflows
Consistent remote environments for several developers at once
Resource management
cgroups and limits against mutual slowdown within the team
10. Summary
Remote development via SSH is today the pragmatic answer to resource hungry projects and heterogeneous developer hardware. A well maintained SSH config with aliases, keep alive options and connection multiplexing forms the foundation on which VS Code Remote-SSH, JetBrains Gateway or classic rsync workflows build. Port forwarding makes remote services reachable locally, agent forwarding allows secure git operations without copying keys.
The choice between a fully remote editor and a local editor with file synchronization depends mainly on network latency and personal preference. In both cases, a well thought out server configuration matters, one that avoids resource contention between team members and keeps an eye on the security of forwarded connections. Once these building blocks are set up correctly, you benefit permanently from productive remote development that feels almost like local work.
For teams new to this topic, a step by step approach is advisable: first set up the SSH config with aliases and ControlMaster, then test VS Code Remote-SSH or JetBrains Gateway on the first projects, and only add extra building blocks such as agent forwarding or resource limits once genuinely needed. This gradual introduction avoids overwhelming a team with too many new concepts at once, and ensures each building block is actually understood and used before the next one is added.
Remote Development via SSH, the Essentials at a Glance
SSH config
Host aliases with ServerAliveInterval and ControlMaster save time and typing.
VS Code Remote-SSH
Editor local, compute load remote, ideal for large codebases and Docker stacks.
Port forwarding
ssh -L makes remote dev servers reachable locally without public exposure.
Agent forwarding
ForwardAgent allows git operations on the server without a copied private key.
11. FAQ: Remote Development via SSH
1Remote-SSH vs. file synchronization?
2Set up a reusable SSH alias?
3What does ControlMaster do?
4Make a remote dev server reachable locally?
5sshfs instead of Remote-SSH?
6Is agent forwarding safe?
7Why does the work feel sluggish?
8Prevent one developer slowing the server?
9Local vs. remote port forwarding?
10Own firewall configuration needed?
Last content review of this article: July 2026, example configurations tested with OpenSSH 9.x and VS Code Remote-SSH.