code-server is Coder's build of VS Code that runs on a server and serves the whole editor to any browser. On a VPS it turns into a personal cloud IDE you can open from a tablet, a work laptop with no admin rights, or a machine you don't trust with your SSH keys — but it is still a process on a small box, and the honest framing matters more than the install command.
What this is actually for, and what it isn't
A browser IDE on a 2 GiB VPS is for editing, running git, and light builds: a script, a static site, a small service you go build or npm run build locally on the box. It is not a replacement for a CI runner or a beefy workstation. The editor itself is lightweight, but the moment you open a real project, language servers and extensions are what eat the RAM, not the VS Code shell around them — a TypeScript server indexing a medium repo, rust-analyzer, or Pylance-equivalents each want their own few hundred megabytes, and they stay resident for as long as the folder is open.
That's the number to plan around, not the idle footprint. code-server itself idles well under 200 MB. Add one active language server and a handful of extensions and a real session settles closer to 700 MB–1 GiB, before the OS and Caddy. 1 GiB works only for light editing — config files, short scripts, no language server doing real indexing. 2 GiB is the realistic floor for a genuine coding session with one language server running. Compile anything non-trivial alongside it, or run a second always-on service on the same box, and that's a reason to size up rather than watch the OOM killer pick a fight with sshd.
Installing code-server
Coder publishes an install script, and the right way to run it is to read it first, not pipe it straight into a shell:
curl -fsSL https://code-server.dev/install.sh -o install-code-server.sh
less install-code-server.sh
sh install-code-server.sh
On Ubuntu the script detects the distribution and installs the .deb package it downloads, the same artifact published on the project's GitHub releases page. If you'd rather skip the script entirely, grab that .deb yourself and install it with apt, which resolves dependencies for you where a bare dpkg -i would not. code-server's release assets carry the version in the filename (code-server_4.92.2_amd64.deb, not a bare code-server_amd64.deb), so there's no unversioned shortcut URL — resolve the current tag first, then build the filename from it:
VERSION=$(curl -fsSL https://api.github.com/repos/coder/code-server/releases/latest | grep -Po '"tag_name": *"v\K[^"]+')
curl -fsSL -o code-server.deb "https://github.com/coder/code-server/releases/download/v${VERSION}/code-server_${VERSION}_amd64.deb"
sudo apt install ./code-server.deb
Either path installs the same package. Check the code-server releases page if you'd rather copy the current filename by hand instead of scripting it.
Running it as yourself, not as root
The package ships a systemd template unit, code-server@.service, meant to run as your normal non-root user — the @ takes the username. Never run an internet-facing editor as root; it has a terminal, and a terminal as root is the whole machine.
sudo systemctl enable --now code-server@$USER
systemctl status code-server@$USER
That starts code-server under your own account, reading its config from your own home directory, and restarts it automatically after a reboot or a crash. sudo journalctl -u code-server@$USER -f shows the live log if something isn't coming up.
The config file: bind-addr, auth, and what auth: none really means
First launch writes ~/.config/code-server/config.yaml with a random password already in it. Open it and set it deliberately instead of trusting the generated one blindly:
bind-addr: 127.0.0.1:8080
auth: password
password: <a long, random password, not the generated one if you didn't check it>
cert: false
bind-addr on 127.0.0.1:8080 means code-server only answers on the loopback interface — nothing on the open internet can reach port 8080 directly, only whatever reverse proxy runs on the same machine. Leave cert: false here; Caddy is doing TLS, not code-server itself.
auth: none exists, and it is not automatically wrong — but it is only sane when something else in front of code-server is doing the authenticating, a VPN you connect over first, or basic auth on the proxy in front of it (below). Turn off code-server's own password and put nothing else in its place, and you've published a shell to anyone who finds the hostname.
Restart after any change:
sudo systemctl restart code-server@$USER
HTTPS with Caddy — a browser IDE has no business on plain HTTP
code.example.com {
reverse_proxy 127.0.0.1:8080
}
That's the whole file, and it's enough because Caddy detects the WebSocket upgrade code-server's UI depends on and proxies it without extra configuration. Point the domain's A record at the VPS, let it propagate, and only then start Caddy — automatic HTTPS needs that record correct before it can request a certificate.
Read this before you buy: the NAT IPv4 catch for 443. Some overnight.host plans hand you 80 and 443 forwarded by default, some don't — check what your plan actually forwards before you point DNS anywhere, at NAT IPv4, ports and forwarding. If 443 isn't reachable, Caddy's automatic certificate issuance has nothing to answer the ACME challenge on, and it will sit there retrying instead of serving anything. A dedicated IPv4, where 443 is genuinely yours — on our plans that's arranged by e-mail — is the alternative; NAT IPv4 vs a dedicated IP covers the trade-off in more detail. Either way, a browser IDE must never end up reachable over plain HTTP on a public port — that password is the only thing standing between the internet and a terminal.
An IDE on the internet is a shell on your VPS
Say it plainly: code-server's whole value is a full terminal inside the browser tab, which means anyone who gets past auth: password has a shell on your machine, not just an editor. There's no built-in two-factor here — the password is doing all the work. A long, random, unique password is the floor, generated with something like openssl rand -base64 24 and stored in a password manager, not typed from memory.
Two ways to add a real second layer:
- Caddy basic auth in front of it, which stacks a second credential Caddy checks before it ever proxies to code-server:
code.example.com {
basic_auth {
<username> <bcrypt-hash-from-caddy-hash-password>
}
reverse_proxy 127.0.0.1:8080
}
-
A VPN in front of the whole thing, so
bind-addrand the Caddy site block only ever answer on an interface reachable through the tunnel, and the public internet never sees the hostname resolve to anything useful at all.
Pick at least one of these if the machine holds anything you'd mind losing.
Extensions come from Open VSX, not the Microsoft marketplace
code-server is configured out of the box to pull extensions from Open VSX (open-vsx.org), the open registry, rather than Microsoft's own marketplace — Microsoft's marketplace terms restrict its use to Microsoft's own products, and code-server isn't one. Install extensions the normal way, from the Extensions view in the UI or with code-server --install-extension <publisher.extension>, and it resolves against Open VSX automatically.
The catch worth knowing before you go looking for something: not every extension on the Microsoft marketplace has a matching listing on Open VSX. A handful of Microsoft-published ones simply aren't mirrored there, so if you're coming from desktop VS Code, budget a few minutes to confirm your must-haves exist before you build a whole workflow around them.
Settings Sync exists in code-server too, tied to a Microsoft or GitHub account, but it's worth treating as a convenience rather than a guarantee: because extensions still come from Open VSX on this end, syncing settings pulled from a desktop VS Code profile brings back the extensions that also exist on Open VSX and quietly skips the ones that don't.
Workspaces, and git over your dedicated SSH port
Your projects live as ordinary directories under your home directory on the VPS's own disk — no separate storage layer to configure, just ~/projects or wherever you'd naturally put them, opened from code-server's File → Open Folder. A handful of repos and their node_modules or build artifacts add up faster than the code itself, so keep an eye on df -h the same way you would on any other box.
Git works from the built-in terminal exactly as it would over SSH anywhere else — generate or copy an SSH keypair for this user, add the public half to GitHub, GitLab, or wherever your remotes live. The one thing that catches people out: if one of those remotes is a git server you also self-host behind NAT IPv4 — our own self-hosting Gitea on a VPS guide walks through exactly this — its SSH clone URL needs that server's forwarded port, not 22, so a plain git clone git@host:repo.git fails until you either add a Port line to ~/.ssh/config for that host or spell the port out in the URL.
Backups and updates
Two directories matter, and they're small: ~/.config/code-server (your config.yaml, including the password) and ~/.local/share/code-server (installed extensions and editor state), alongside whatever workspace directories you actually work in. None of that is backed up by anything running on the box on its own — copy it off the VPS on a schedule, the same as anything else you'd mind losing; back up your VPS covers what that looks like in practice.
Updating means installing a newer package: re-run the install script, which fetches the current release, or download the latest .deb from the releases page and sudo apt install it again the same way you did the first time, then sudo systemctl restart code-server@$USER to pick it up.
On overnight.host
Full disclosure: this is what we sell. The 2 GiB Basic is the realistic floor once a language server is actually running; the 1 GiB Starter only holds up for quick edits, and a build that leans on the CPU or a second service on the same box is a reason to move up to the 4 GiB Standard, not to fight the swap.
Linux KVM VPS — EUR 4.99 to EUR 59.99 a month, on our own single-tenant bare metal in Dallas, TX and Charlotte, NC. Full hardware virtualisation (KVM), your own kernel, full root. Six tiers, vps-starter to vps-ultra. Starter is 1 vCPU, 1 GiB RAM, 25 GB disk.
You order in the shop, pay by card (Stripe) or SEPA bank transfer, and your login details are e-mailed to you once the service is set up. Support is e-mail, run by one person, with no guaranteed response time. All prices are final totals under the German small-business rule (§19 UStG); no VAT is added or shown.
Order vps-basic → · Linux KVM VPS overview
FAQ
Can code-server compile a real project, not just edit files?
For light builds, yes — a script, a small service, a static site generator. For anything CPU- or memory-heavy, treat the VPS as an editor with a terminal attached, not a build farm, and run the actual compile step somewhere sized for it, or budget real RAM and CPU if you insist on doing it here.
Is a strong password enough, or do I need HTTPS too?
Both, always. HTTPS via Caddy stops the password itself from crossing the network in plain text; without it, anyone between you and the VPS can read the password off the wire the first time you type it in. A browser IDE reachable over plain HTTP is not a smaller risk than one with a weak password — it's the same risk from a different angle.
Why is an extension I use every day missing?
code-server pulls from Open VSX, not the Microsoft marketplace, and a small number of extensions — mostly Microsoft's own — are only published to the latter. Search Open VSX directly before assuming your install is broken; if it isn't listed there, it isn't coming through the Extensions view no matter what you try.
Can I browse or edit files outside my home directory?
Only as whatever your own Linux user can read or write, same as any shell session — code-server runs as you, under the systemd unit's %i substitution, with no extra privilege of its own. If a file needs sudo to touch from a terminal, it needs sudo here too, and code-server doesn't hand that out automatically.
What happens to my work if I just close the browser tab?
Nothing is lost. code-server runs as a systemd service on the VPS independent of any browser tab; closing the tab just disconnects the view. Unsaved editor state and any process you left running in an integrated terminal survive until you reconnect, restart the service yourself, or reboot the machine.
Originally published at overnight.host. We run a small, honest hosting company on dedicated bare metal: Linux & Windows VPS, game servers, web hosting. Live status at up.overnight.host.
Top comments (0)