What This Article Solves
If you want to put code-server on a VPS, access it from the browser, and then install Codex inside it, this article is written for that exact situation. The point is not just to make the editor open. The point is to make the whole workflow usable, including login and normal daily use.
- You have a Linux VPS.
- You can reverse proxy a web service to a domain or subpath.
- You want Codex inside code-server, not just a local desktop VS Code.
The Short Version
The tricky part is not installing code-server. The tricky part is that some authentication flows assume localhost means your own laptop. Inside code-server, localhost often means the remote server process instead. If Codex or a related login flow opens a localhost callback, you need to route that callback correctly.
My Setup
- A Linux VPS running code-server.
- A domain pointed to that VPS and reverse proxied with Nginx.
- Browser access over HTTPS.
- Codex installed inside the remote editor.
Step 1: Make code-server Stable First
Before touching Codex, make sure code-server itself is boring. It should already be reachable through one stable URL, protected the way you want, and not dependent on random temporary tunnels.
- The reverse proxy can serve code-server consistently.
- WebSocket upgrade is working.
- Your browser session is not being broken by mixed HTTP/HTTPS routing.
curl -fsSL https://code-server.dev/install.sh | sh
sudo systemctl enable --now code-server@$USER
sudo systemctl status code-server@$USER
If you are already using a containerized environment like NerdVM or OpenClaw, the exact startup command may differ, but the principle is the same: the editor service must be stable before the plugin layer is worth debugging.
Step 2: Install Codex Inside code-server
Once the editor itself works, install Codex the same way you would install any other extension inside code-server. If the extension can load, but login fails later, that usually means the editor layer is fine and the callback layer is where you should look next.
Step 3: Understand Why Login Fails
When a login flow opens a localhost callback, there are at least two machines in the picture: your browser on your own computer, and the remote code-server process running on the VPS. If the plugin expects the callback to reach the remote process, but the browser opens localhost on your own machine, the login will hang or fail in a way that looks confusingly half-correct.
In this setup, localhost is not one place. It depends on which process is talking.
Step 4: Fix the Callback with SSH Port Forwarding
The clean fix for me was classic SSH port forwarding. Once I confirmed the remote process was waiting on a local callback port, I forwarded that port through SSH so the browser callback could land where the remote process actually expected it.
ssh -L 1455:127.0.0.1:1455 root@your-vps-ip
The exact port will depend on what the login flow is using. The important part is not the number. The important part is matching the callback port expected by the remote process.
How to Confirm You Are Forwarding the Right Port
Do not guess blindly. Watch logs or process output when the login starts. Usually the plugin, helper process, or CLI behind it will print the callback URL or listening port.
ss -ltnp
# or
netstat -ltnp
If you suddenly see a local listener appear only while login is in progress, that is usually your clue.
Common Failure Modes
- The login page opens, but the editor never finishes sign-in.
- The callback opens localhost on your laptop, but nothing is listening there.
- The reverse proxy is fine, but the plugin still looks broken because the callback never reaches the remote process.
- You fix the browser URL but forget that HTTPS, WebSocket, and login callback are three different layers.
What Worked for Me in Practice
- Make code-server reachable first.
- Install Codex only after the editor is stable.
- When login gets stuck, stop treating it like a UI bug and inspect the callback path.
- Use SSH local port forwarding when the callback expects a remote localhost listener.
If I Were Doing It Again
I would treat the whole system as three separate layers from the beginning: editor access, auth gateway, and callback routing. That mental split would have saved me time. code-server and Codex can work well together remotely, but they stop feeling mysterious as soon as you stop collapsing everything into one vague 'login problem' bucket.