# How to Run code-server (VS Code in the Browser) in a Cloud Sandbox

> Install code-server with its official install script, set bind-addr 0.0.0.0:8080 in its config, enable the code-server@user systemd service, then run sbx host <id> 8080. The private hosted URL's token gates the editor, terminal WebSockets included, so auth none is safe as long as the port stays private.

Source: https://sandboxer.com/guides/run-code-server-vs-code-in-the-browser. Updated 2026-10-27.

**Short answer:** Install code-server with its official install script, set bind-addr 0.0.0.0:8080 in its config, enable the code-server@user systemd service, then run sbx host <id> 8080. The private hosted URL's token gates the editor, terminal WebSockets included, so auth none is safe as long as the port stays private.

## What we ran

Everything below ran on prod on 2026-10-27, on one `small` sandbox (2 vCPU, 4 GB), with code-server 4.143.1 (Code 1.143.1). Tokens and cookies are replaced with `<token>` and `<cookie>`. If you want your desktop VS Code or Cursor instead of a browser tab, see [SSH into a cloud sandbox from VS Code or Cursor](/guides/ssh-into-a-cloud-sandbox-from-vs-code-or-cursor). This page is for a full editor in any browser, with nothing installed on your computer.

| Step | Result |
| - | - |
| Install with the official script | 7.2 s |
| Editor page through the private URL | `200` in 0.23 s, workbench drawn in 4.3 s in headless Chromium |
| Request without the token | `401`, for the page and for the WebSocket handshake |
| Terminal in the browser | Worked over the hosted URL's WebSockets |
| Extension installed from the CLI | `esbenp.prettier-vscode@12.4.0` |
| After `sbx stop --wait` and `sbx resume` | Same process, same extension, URL answered `200` at once |
| Cold boot of a fork (disk only) | Service started on its own, extension kept |

## 1. Install code-server

code-server's [install docs](https://coder.com/docs/code-server/install) recommend its install script, which picks the package for your distribution. On a Sandboxer sandbox (Ubuntu, x86_64) it installs the `.deb`:

```bash
sbx new --name code-server --type small
sbx exec sb_wdrcyuwaak "curl -fsSL https://code-server.dev/install.sh | sh"
```

```text
+ sudo dpkg -i ~/.cache/code-server/code-server_4.143.1_amd64.deb
…
deb package has been installed.

To have systemd start code-server now and restart on boot:
  sudo systemctl enable --now code-server@$USER
…
```

`code-server --version` printed `4.143.1 22ddf60dbc52f164cff13620ab515086dd08c90a with Code 1.143.1`. The whole install took 7.2 seconds.

## 2. Configure it and run it as a service

code-server reads `~/.config/code-server/config.yaml`. By default it listens on `127.0.0.1:8080` with a random password. Bind it to all interfaces so the hosting proxy can reach it, and turn its own login off, because the hosted URL's token does that job (next section):

```bash
sbx exec sb_wdrcyuwaak 'cat > ~/.config/code-server/config.yaml <<EOF
bind-addr: 0.0.0.0:8080
auth: none
cert: false
EOF
sudo systemctl enable --now code-server@$USER'
```

The package ships a templated unit, `code-server@.service`, that runs code-server as the user you name, with `Restart=always`, and starts it at boot (`WantedBy=default.target`). Check it:

```bash
sbx exec sb_wdrcyuwaak "systemctl is-active code-server@user; ss -ltn | grep 8080"
```

```text
active
LISTEN 0      511          0.0.0.0:8080      0.0.0.0:*
```

## 3. Give it a private HTTPS URL

```bash
sbx host sb_wdrcyuwaak 8080 --title "code-server"
```

```text
https://hardy-lofty-seal-8080.box.sandboxer.com?_token=<token>
```

A hosted port is private by default ([Hosting](/docs/hosting)). Without the token, the Sandboxer proxy answers and code-server never sees the request:

```bash
curl -si https://hardy-lofty-seal-8080.box.sandboxer.com/ | head -1
```

```text
HTTP/2 401
```

The `401` page is titled "Access token required". With the token, the proxy sets a 30-day cookie and redirects to `/`, and the editor loads:

```text
HTTP/2 302
location: /
set-cookie: __sbx_auth=<cookie>; Path=/; Max-Age=2592000; HttpOnly; Secure; SameSite=Lax
```

```text
GET / with the cookie   ->  200 in 0.23 s
```

The HTML has no static `<title>`. VS Code sets it from script, so we opened the token link in headless Chromium (Playwright) and read it once the workbench was drawn:

```text
first response: 200
workbench visible after 4304 ms
final URL: https://hardy-lofty-seal-8080.box.sandboxer.com/
document.title: Welcome - code-server
```

## 4. The terminal and WebSockets

The workbench talks to the server over WebSockets, and the integrated terminal runs on them. In the same browser session we opened **Terminal: Create New Terminal** from the Command Palette and typed a command. It ran in the sandbox:

```bash
# typed into the browser terminal
echo term-ok from $(hostname) > /tmp/term-ok
```

```bash
sbx exec sb_wdrcyuwaak "cat /tmp/term-ok"
```

```text
term-ok from hardy-lofty-seal
```

Playwright saw two WebSockets, both carrying traffic through the hosted URL:

```text
websocket: wss://hardy-lofty-seal-8080.box.sandboxer.com/stable-22ddf60d…?reconnectionToken=…  frames received: 272 (open)
websocket: wss://hardy-lofty-seal-8080.box.sandboxer.com/stable-22ddf60d…?reconnectionToken=…  frames received: 62 (open)
```

This works because the browser sends the `__sbx_auth` cookie on the WebSocket handshake. A handshake to the same path without the cookie got `401` from the proxy. So the token gates the whole editor, not only the first page.

## auth none or code-server's password?

We tested both behind the private URL. Both work, WebSockets and terminal included.

| | `auth: none` | `auth: password` |
| - | - | - |
| Who can get in | Anyone with the token link or its cookie | Anyone with the token link **and** the password |
| First visit | Editor opens | `302` to `./login`, page titled "code-server login" |
| After login | | `302` to `./`, sets a `code-server-session` cookie, editor opens |
| Terminal over WebSockets | Worked | Worked |
| Use it when | It's just you, and the port stays private | You share the link, or want a second factor if the link leaks |

The code-server docs list `none` as an auth option and warn against exposing it unprotected ([FAQ](https://coder.com/docs/code-server/FAQ)). On Sandboxer, the private hosted URL is that protection. Two rules follow:

- **Never run `sbx host … --public` on a code-server with `auth: none`.** The editor's terminal is a shell as `user`, with `sudo`. A public URL would give it to anyone.
- **Treat the token link and cookie like a password.** To cut off everyone who has it, switch the port public and back to private, which mints a new token, or take it down with `sbx host hide` (hosting it again brings the old link back, so hide alone doesn't revoke it). Do the switch with code-server stopped or on `auth: password`.

For password mode, set `auth: password` and `password: <something long>` in the same config file and run `sudo systemctl restart code-server@user`.

## 5. Install an extension from the CLI

```bash
sbx exec sb_wdrcyuwaak --timeout 300 "code-server --install-extension esbenp.prettier-vscode; code-server --list-extensions --show-versions"
```

```text
Installing extensions...
Installing extension 'esbenp.prettier-vscode'...
Extension 'esbenp.prettier-vscode' v12.4.0 was successfully installed.
esbenp.prettier-vscode@12.4.0
```

code-server installs extensions from [Open VSX](https://open-vsx.org/), not Microsoft's marketplace ([FAQ](https://coder.com/docs/code-server/FAQ)), so search there for the ID. Extensions go to `~/.local/share/code-server/extensions` on the sandbox disk. On our first try the command stalled on a slow Open VSX request and hit the `exec` time limit. A retry finished in 1.4 seconds. Pass `--timeout` to `sbx exec` for long installs.

## 6. Stop and resume

```bash
sbx stop sb_wdrcyuwaak --wait
curl -s -o /dev/null -w "%{http_code}\n" -b cookies.txt https://hardy-lofty-seal-8080.box.sandboxer.com/
```

```text
404
```

While the sandbox is stopped, the URL answers `404`. Then:

```bash
sbx resume sb_wdrcyuwaak
```

The resume returned `"memoryRestored": true` in 1.4 seconds. The URL answered `200` with the same cookie from before the stop, and nothing had restarted:

```text
active
MainPID=3644          # same PID as before the stop
esbenp.prettier-vscode@12.4.0
```

Memory comes back only when the resume lands on a machine with the same CPU type. Otherwise the sandbox boots from disk (`memoryRestored: false`): files, extensions and hosted routes are kept, and processes start fresh.

The enabled systemd unit covers that case. To test a cold boot, we forked the sandbox, because a fork copies the disk only. On the fork, code-server was already running with a new PID, and the extension and project files were there:

```bash
sbx fork sb_wdrcyuwaak --wait --type small
sbx exec sb_5k0lnk4n7j "systemctl is-active code-server@user; systemctl show -p MainPID code-server@user; code-server --list-extensions --show-versions"
```

```text
active
MainPID=192
esbenp.prettier-vscode@12.4.0
```

A fork has its own subdomain and no hosted ports, so run `sbx host <fork-id> 8080` to get a URL for it.

## FAQ

### Do I need code-server's password if the URL is private?

No, if you keep the port private and the link to yourself. The proxy returns `401` to any request without the token or its cookie, WebSocket handshakes included. Add `auth: password` if you share the link.

### Why does the page say "Nothing is answering on port 8080"?

code-server is stopped, or still on its default `bind-addr: 127.0.0.1:8080`. Set `0.0.0.0:8080` and restart the service, or keep localhost and host the port with `--localhost`.

### Can I use Microsoft's extensions, like Pylance?

code-server uses Open VSX. Its FAQ explains why Microsoft's marketplace isn't available to it. Look for each extension on Open VSX first.

### Which size should I pick?

We ran it on `small` (2 vCPU, 4 GB). If language servers or builds in the terminal need more, `default` has 4 vCPU and 8 GB.

## Related

- [SSH into a cloud sandbox from VS Code or Cursor](/guides/ssh-into-a-cloud-sandbox-from-vs-code-or-cursor)
- [Give a sandbox port an HTTPS URL](/guides/give-a-sandbox-port-an-https-url)
- [Pause and resume a sandbox with its memory](/guides/pause-and-resume-a-sandbox-with-memory)
- [Hosting](/docs/hosting)
