Self-hosted code streaming
Tags: programming, tooling
Published: 2022-12-15 16:09:30

This article will present how to self-host a code streaming server that is independant from the code editor that you use. You won't get a two-way pair-programming solution, only streaming.

The solution relies on [Pair-ls - Editor-agnostic remote pair programming](https://github.com/stevearc/pair-ls). It will involve 4 elements:

- a `Pair-ls` relay server,
- a Nginx reverse proxy to make the relay server accessible from the Web
- a `Pair-ls` LSP server (started automatically by your editor) that will stream code to the relay server
- a code editor (of you choice!)

## Configure the server

### Pair-ls service

Download and install `pair-ls` binary:

```sh
$ wget https://github.com/stevearc/pair-ls/releases/download/v0.1.1/pair-ls-linux64 -O /usr/local/bin/pair-ls
$ chmod +x /usr/local/bin/pair-ls
```

To have it started by the system, create a Systemd unit file named `/etc/systemd/system/pair-ls.service`:

```desktop
[Unit]
Description=Pair-ls Code Streaming

[Service]
User=nobody
Environment="XDG_CONFIG_HOME=/tmp"
Environment="XDG_CACHE_HOME=/tmp"
ExecStart=pair-ls -config /dev/null -logfile /tmp/pair-ls.log -loglevel 10 relay -port 8888

[Install]
WantedBy=multi-user.target
```

Reload Systemd config and start the service:

```sh
systemctl daemon-reload
systemctl enable pair-ls.service
systemctl start pair-ls.service
```

### Nginx reverse proxy

Create a Nginx config file named `/etc/nginx/sites-available/pair-ls`. Paste this contents and adjust the server FQDN:

```nginx
server {
    listen    443 ssl;

    # Your serveur FQDN
    server_name  your.domain.tld;

    # There will be no static files to serve, so we don't need a root folder
    root /dev/null;
    server_tokens off;

    # The SSL-related stuff
    ssl_certificate      /path/to/cert.pem;
    ssl_certificate_key  /path/to/private.key;

    # The logs
    access_log  /var/log/nginx/access.log;
    error_log   /var/log/nginx/error.log;

    # Pass all traffic to the pair-ls daemon listening on port 8888
    location / {
        proxy_pass http://localhost:8888;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }
}
```

Enable the Nginx host and reload the config:

```sh
$ ln -s /etc/nginx/sites-available/pair-ls /etc/nginx/sites-enabled/pair-ls
$ systemctl reload nginx.service
```

Your code streaming relay is ready. Go to [https://your.domain.tld/](https://your.domain.tld/) to watch the stream.

## Configure the editor

Install the editor plugin :

- [for VSCode](https://github.com/stevearc/pair-ls-vscode/)
- [for NeoVim](https://github.com/stevearc/pair-ls.nvim)

Configure the plugin to start the `pair-ls` with the following arguments:

```sh
lsp -forward wss://your.domain.tld
```

You can now start your code streaming session through the plugin command `Pair` and stop through `PairStop`.

If you don't use VSCode or NeoVim, you can configure your editor to run Pair-ls as a LSP server and connect to it. You'll probably find how to do so in your editor documentation.

## Final thoughts

The solution presented here has no access-control at all. That means that anyone knowing the relay server URL will be able to watch your code streaming session.

There are ways to secure this:

- Pair-ls relay server can be configured to prompt for a password on its Web frontend
- Pair-ls LSP server can be configured to be accessed through a token-secured WebRTC connection