code-server-ipad I believe that browser based development has finally become just as good as running an IDE locally on your device. You can have all the benefits of local development: competent hardware, familiar IDE with keyboard shortcuts, and not having to worry about platform compatibility. All of this, in addition to the portability benefits of it being fully contained in the browser. This means all your installed extensions and settings follow you to every device — including an iPad!

There are several tutorials on how to set up code-server, but code-server by itself is not safe to expose over the internet. In this guide, we’ll set up code-server behind a secure VPN and handle all the requirements for HTTPs with a few configurations and commands.

Requirements

To accomplish this, we’ll be using the following technologies:

  • Code Server — one of the most popular code editors is now available in a browser. While the official release (at the time of this writing) is still in private preview, there are 3rd party implementations that are available.
  • Tailscale — a zero config VPN that will greatly simplify how we access code-server in a secure and encrypted way. I’ve already mentioned in a previous post some of the other reasons why I think it’s great.
  • Caddy — A web server that provides automatic HTTPS. This is important as certain features on code-server are restricted unless they’re over TLS.
  • Docker Compose — While you can install all of the above onto the host itself, I like to containerize my installations as much as possible. Docker Compose will help keep our configurations to a single file and keep maintenance nice and tidy.

You’ll also need:

  • A host (on GCP, AWS, DigitalOcean, etc.,) with at least 2 cores and 1GB memory — the recommended reqs to run code-server
  • A free account on Tailscale
  • Tailscale installed on any device you want to be able to access your code-server from

Setup

For this setup, I’ll be walking through the steps to set this up on a host running Ubuntu 22.04 (Jammy). If you’re using something else, see the notes below. Most of the steps should still be applicable. We’ll be installing Tailscale and docker/docker-compose on the host itself. Everything else will be run as a docker container.

Install docker and docker-compose.

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update -y && apt-get install -y docker-ce docker-compose

Install Tailscale using the sources for your OS. See here if you’re using something other than Jammy.

curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/jammy.noarmor.gpg | sudo tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/jammy.tailscale-keyring.list | sudo tee /etc/apt/sources.list.d/tailscale.list
sudo apt-get update -y && apt-get install -y tailscale

Bring up tailscale. Running this for the first time will provide you with a link that will allow you to authenticate through a browser

sudo tailscale up

Once authenticated, this will add your host to your Tailscale network and you’ll need to Enable HTTPS under the DNS page. When complete, you’ll be provided a domain alias in the form of <hostname>.<domain_alias>.ts.net that we’ll need to add to our configurations below.

Create the data volumes for code-server and caddy:

mkdir ~/code-server
docker volume create --name=caddy_data

And finally, create the following configuration files:

~/Caddyfile

hostname.domain_alias.ts.net {
    redir /code /code/

    route /code/* {
        uri strip_prefix /code
        reverse_proxy code-server:8443
    }
}

~/docker-compose.yml

version: "2.1"

networks:
  code-net:

services:
  code-server:
    image: lscr.io/linuxserver/code-server:latest
    container_name: code-server
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/Los_Angeles
      - DEFAULT_WORKSPACE=/config/workspace 
    volumes:
      - ~/code-server/config:/config
      - /var/run/docker.sock:/var/run/docker.sock # Allows ability to fetch tailscale certs
    networks:
      - code-net
    ports:
      - 127.0.0.1:8443:8443 # reverse proxy code-server
    restart: unless-stopped
  caddy:
    image: caddy:latest # this is NOT recommended for a production site. Pin to a stable version
    container_name: caddy
    restart: unless-stopped
    volumes:
      - ~/Caddyfile:/etc/caddy/Caddyfile
      - /var/run/tailscale:/var/run/tailscale
      - caddy_data:/data
      - caddy_config:/config
    networks:
      - code-net
    ports:
      - 80:80 # caddy http
      - 443:443 # caddy https
volumes:
  caddy_data:
    external: true
  caddy_config:

Bring up the containers:

docker-compose up -d

And that’s it! From here you should be able to access your code-server environment via https://<tailscale_host>.<tailscale_subdomain>.ts.net/code