--- title: "How to Install code-server on Ubuntu 24.04 with HTTPS" description: "Run VS Code in your browser with code-server on Ubuntu 24.04: install it as a systemd service, set a hashed password and serve it over HTTPS with Nginx." category: "Development Tools" language: en source: https://cubepath.com/docs/development-tools/code-server-vscode-browser-installation updated: 2026-09-25 --- # How to Install code-server on Ubuntu 24.04 with HTTPS code-server is an open source project by Coder that runs Visual Studio Code on a remote server and serves it to any web browser. Your code, terminals and extensions live on the server, so you can work from a laptop, a tablet or a borrowed machine with the same environment every time. In this tutorial you will install code-server on Ubuntu 24.04, run it as a systemd service for your user, protect it with a hashed password, and publish it at `https://code.your_domain` behind Nginx with a free Let's Encrypt certificate. ## Prerequisites To follow this tutorial, you will need: - A server running Ubuntu 24.04 LTS with at least 2 GB of RAM (1 GB works for light use, but the language servers of most extensions need more). A CubePath VPS with 2 vCPU and 4 GB of RAM is a comfortable size. - A non-root user with `sudo` privileges. The IDE will run as this user, and its integrated terminal will have the same permissions. - Nginx installed, with UFW allowing SSH and the `Nginx Full` profile. - A domain or subdomain, for example `code.your_domain`, with a DNS A record pointing to `your_server_ip`. Let's Encrypt needs this record to issue the certificate. > Warning: Anyone who logs in to code-server gets a shell on your server as your user. Always put it behind HTTPS with a strong password, and never expose port 8080 directly to the Internet. ## Step 1 - Installing code-server Coder publishes `.deb` packages for every release, and the official install script picks the right one for your distribution and installs it with `apt`. Download the script first so you can read what it does before running it: ```bash curl -fsSL https://code-server.dev/install.sh -o install-code-server.sh less install-code-server.sh ``` You can preview the actions it will take without changing anything using `--dry-run`: ```bash sh install-code-server.sh --dry-run ``` When you are happy with it, run the installation: ```bash sh install-code-server.sh ``` The script downloads the latest release from GitHub, installs it with `sudo`, and prints how to start the service. Confirm that the binary is available: ```bash code-server --version ``` ```output 4.x.x 1a2b3c4d... with Code 1.x.x ``` The exact version numbers will differ. The package also installs a systemd template unit, `code-server@.service`, that runs code-server as the user named after the `@`. ## Step 2 - Starting code-server as a systemd service Enable and start the service for your user. The `$USER` variable expands to your current username: ```bash sudo systemctl enable --now code-server@$USER ``` Check that it is running: ```bash systemctl status code-server@$USER ``` ```output ● code-server@sammy.service - code-server Loaded: loaded (/usr/lib/systemd/system/code-server@.service; enabled; preset: enabled) Active: active (running) since ... ``` On first start code-server creates its configuration file at `~/.config/code-server/config.yaml` with a random password. Confirm that it is listening only on the loopback interface: ```bash ss -tlnp | grep 8080 ``` ```output LISTEN 0 511 127.0.0.1:8080 0.0.0.0:* users:(("node",pid=1234,fd=20)) ``` The address `127.0.0.1:8080` means code-server is not reachable from outside the server. Nginx will be the only public entry point. ## Step 3 - Setting a hashed password The generated config stores the password in plain text. code-server also accepts a `hashed-password` key with an Argon2 hash, so the real password never sits on disk. Install the `argon2` command line tool: ```bash sudo apt update sudo apt install -y argon2 ``` Generate a hash. Replace `your_strong_password` with a long, unique password; the leading space keeps the command out of your shell history in the default Ubuntu Bash configuration: ```bash echo -n 'your_strong_password' | argon2 "$(openssl rand -base64 16)" -e ``` ```output $argon2i$v=19$m=4096,t=3,p=1$Zm9vYmFyYmF6cXV4$... ``` Now open the configuration file: ```bash nano ~/.config/code-server/config.yaml ``` Replace its contents with the following, pasting your hash inside single quotes (the `$` characters must not be interpreted): ```yaml bind-addr: 127.0.0.1:8080 auth: password hashed-password: '$argon2i$v=19$m=4096,t=3,p=1$Zm9vYmFyYmF6cXV4$...' cert: false ``` Each key does the following: - `bind-addr` keeps code-server on localhost, behind Nginx. - `auth: password` enables the login page. - `hashed-password` replaces the plain `password` key. Do not keep both. - `cert: false` leaves TLS to Nginx. Restart the service to apply the change: ```bash sudo systemctl restart code-server@$USER ``` If the service fails to start, `journalctl -u code-server@$USER -n 50` shows the reason, usually a YAML syntax error. ## Step 4 - Configuring Nginx as a reverse proxy code-server relies on WebSockets for the editor, the terminal and file watching, so the proxy must pass the `Upgrade` and `Connection` headers. Create a server block for your subdomain: ```bash sudo nano /etc/nginx/sites-available/code-server ``` Add the following configuration, replacing `code.your_domain` with your subdomain: ```nginx server { listen 80; listen [::]:80; server_name code.your_domain; location / { proxy_pass http://127.0.0.1:8080/; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; proxy_set_header Accept-Encoding gzip; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_read_timeout 1h; } } ``` `proxy_http_version 1.1` is required for WebSocket upgrades, and the one hour `proxy_read_timeout` stops Nginx from closing idle terminal sessions after the default 60 seconds. Enable the site, test the syntax and reload Nginx: ```bash sudo ln -s /etc/nginx/sites-available/code-server /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginx ``` ```output nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful ``` At this point `http://code.your_domain` shows the code-server login page, but over plain HTTP. Do not log in yet. ## Step 5 - Securing code-server with Let's Encrypt Install Certbot and its Nginx plugin from the Ubuntu repositories: ```bash sudo apt install -y certbot python3-certbot-nginx ``` Request a certificate. Certbot finds the matching `server_name`, adds the TLS configuration and sets up a redirect from HTTP to HTTPS: ```bash sudo certbot --nginx -d code.your_domain ``` Enter an email address for expiry notices and accept the terms when prompted. When it finishes you will see: ```output Successfully deployed certificate for code.your_domain to /etc/nginx/sites-enabled/code-server Congratulations! You have successfully enabled HTTPS on https://code.your_domain ``` The Ubuntu package installs a systemd timer that renews certificates automatically. Test the renewal process: ```bash sudo certbot renew --dry-run ``` ## Step 6 - Logging in and verifying the setup Open `https://code.your_domain` in your browser and log in with the password you hashed in Step 3. You should see the VS Code welcome screen. To confirm that WebSockets work through the proxy, open the integrated terminal with **Ctrl+`** (or **Terminal > New Terminal** from the menu) and run: ```bash whoami ``` The terminal should print your username. If the terminal stays blank or the editor keeps reconnecting, see the troubleshooting section below. Finally, make sure port 8080 is not reachable from outside. From your local machine: ```bash curl -m 5 http://your_server_ip:8080 ``` ```output curl: (28) Connection timed out after 5001 milliseconds ``` A timeout or "connection refused" is the expected result. ## Step 7 - Installing extensions code-server uses the [Open VSX](https://open-vsx.org) registry, not the Microsoft Marketplace, because Microsoft's license only allows the Marketplace in its own products. Most popular extensions (Python, Go, Prettier, ESLint, GitLens) are published there. You can install them from the Extensions view in the browser or from the server shell: ```bash code-server --install-extension ms-python.python code-server --install-extension esbenp.prettier-vscode ``` List what is installed: ```bash code-server --list-extensions ``` ```output esbenp.prettier-vscode ms-python.python ``` If an extension is not on Open VSX, download its `.vsix` file on your computer and upload it to the server, then install it from the file: ```bash code-server --install-extension ~/extension-name.vsix ``` Extensions are installed per user in `~/.local/share/code-server/extensions`, so they survive code-server upgrades. ## Upgrading code-server To update, download and run the install script again as in Step 1. It installs the newest package over the existing one. Then restart the service: ```bash sudo systemctl restart code-server@$USER ``` Your settings, extensions and configuration file are kept. ## Troubleshooting **The editor loads, but the terminal is empty or shows "Reconnecting".** WebSocket upgrades are not reaching code-server. Check that the `location` block contains `proxy_http_version 1.1`, `Upgrade` and `Connection` headers, and that Certbot did not create a second `server` block without them. If you use Cloudflare in proxied mode, WebSockets must be enabled for the zone. **Nginx returns "502 Bad Gateway".** code-server is not running or listens on a different port. Check `systemctl status code-server@$USER` and compare `bind-addr` in `config.yaml` with the `proxy_pass` port. **The login page rejects the correct password.** Make sure the hash is wrapped in single quotes, that the plain `password` key was removed, and that you restarted the service after editing the file. **The server runs out of memory.** Extensions and language servers can use several gigabytes on large projects. You can cap code-server with a systemd drop-in: ```bash sudo systemctl edit code-server@$USER ``` Add the following in the editor that opens, then save: ```ini [Service] MemoryMax=2G ``` Restart the service to apply it. If code-server keeps hitting the limit, resize your server instead. ## Conclusion You now have VS Code running on your Ubuntu 24.04 server, available at `https://code.your_domain` with TLS and a hashed password, and managed by systemd. As next steps, you can clone your repositories into your home directory and add an SSH key for Git, install the toolchains your projects need (Node.js, Python, Go) directly on the server, or add a second authentication layer such as an SSO proxy in front of Nginx if several people will use the instance.