Remote Development with Coder - Third Time's the Charm?
I’ve tried Coder three times now. The first attempt was years ago, the second about a year after that - both ended in frustration. In early 2025 I went for round three, and this time the setup actually worked. 🎯
We have since moved back to local development anyway. But the setup was solid, I learned a lot, and the reasons we left had little to do with Coder itself - so here’s the whole story.
Why keep trying?
The first two attempts died on the same hills:
- Port forwarding - our project needed a bunch of ports exposed, and getting them from the app through the workspace to the outside world was painful.
- Docker inside the workspace - our project runs in Docker, so the workspace needs Docker inside it. Docker-in-Docker either wasn’t there yet or wasn’t stable and performant enough.
- Performance doubts - could one server handle a whole team running
composer installand behat test suites at the same time? Nobody knew.
So why come back? Because the promise is just too good:
- Choose your own machine and OS. Docker performance on macOS is sad, and work requires MS Office, so LibreOffice on Linux doesn’t cut it either. With remote workspaces, the laptop is just a screen with a keyboard - it can be a potato. 🥔
- The IDE runs completely remote. That kills the “works on my machine” discussions, and there is no code to sync around either. The alternative of running a local IDE plus rsync to a remote box falls apart the moment you’re on the move.
- Branches become URLs. With multiple workspaces per developer (one persistent, one for staging), any branch can be publicly reachable for code reviews and testing.
The Setup
The whole team - six developers - worked on one big box: the biggest dedicated-vCPU cloud instance Hetzner had at the time (CCX line, somewhere around 32-64 GB of RAM - the invoice has mercifully faded from memory).
Coder itself ran on that box via docker compose: coderd plus a Postgres container, nothing fancy.
Workspaces came from Coder’s official Docker template , tweaked for our needs. The one tweak that mattered most:
Sysbox: dind that actually works
The thing that killed attempt number two - Docker inside the workspace - turned out to be a one-line fix this time: run the workspace containers with the Sysbox runtime.
Install Sysbox on the host, then set the runtime in the template’s Terraform:
| |
That’s it. Every workspace gets its own real Docker daemon, unprivileged and without any socket-mounting hacks. Our dockerized project ran inside the workspace without a single problem. After two failed attempts I did not expect this to be the easy part.
Public URLs for every developer
The second old pain point, getting ports out, we solved with the nginx-proxy-manager that was already running in front of everything.
Each developer got a proxy host like coder-<user>.domain.tld, with HTTPS termination and password protection, pointing at their workspace’s published ports. Push a branch, start it in your workspace, and anyone on the team can click through it for a review instead of asking you to share your screen.
The IDE situation
We need PHPStorm, so the lineup was:
- JetBrains Gateway as the primary way in - PHPStorm backend runs in the workspace, thin client locally.
- VS Code desktop as the easy alternative - the Remote SSH experience is more mature.
- code-server in the browser as the absolute fallback for quick fixes from anywhere.
Gateway was rough at the start, but it genuinely got better over time - JetBrains kept tweaking it and it became noticeably faster and more usable. Some features of a full-blown local PHPStorm simply weren’t implemented though, and you’d bump into those gaps at random moments.
SSH config
The Coder CLI makes SSH access painless:
| |
The second command writes Host coder.* entries into your ~/.ssh/config, so ssh coder.<workspace> just works. Everything built on top of SSH benefits from that too, like VS Code Remote and rsync.
Shell autocomplete
A minor thing, but it makes daily use noticeably nicer:
| |
It detects your shell and installs the completions. Tab your way through workspace names instead of typing them out. There is no reason to skip this.
How to start your work day
This was the part I loved most, because there is almost nothing to it:
- Open JetBrains Gateway.
- Click your workspace.
Coder starts the workspace if it was auto-stopped overnight, Gateway connects, and you’re coding. Go grab a coffee while it boots. ☕
Why we moved away anyway
In the end, the team never adopted it.
The main reason was performance, though.
Our project is large and was never optimized for this workflow, so the first impression for everyone trying a workspace was slow. That impression stuck: nobody besides me used it for longer than two weeks, and then everyone drifted back to their local setups.
I’m fairly sure that if a few more people had pushed through those first weeks, we would have dug deeper into profiling the bottlenecks and tuning the project for the new workflow. But with nobody left on the workspaces there was nothing to tune for, so we let it go.
Would I try a fourth time? With a project that’s actually built for it, absolutely. Sysbox fixed Docker-in-Docker and Gateway has become genuinely usable.