Choosing a transport

The make host, host-direct, relay-setup and tunnel-setup commands run from a checkout of the open repository github.com/sleep3r/colloq at the tag of the chosen release; that commit is recorded in the sourceCommit field of release.json. Of these tools, the colloq-deploy.tar.gz archive contains only scripts/host.sh. It works with a relay and with a Cloudflare tunnel, while direct mode and the first-time setup of a relay or named tunnel need a checkout. You can also do without these tools and set up your own HTTPS reverse proxy to 127.0.0.1:30080. For a class on your own computer after pip install colloq, colloq host <name> publishes the server the same way; without a name, it starts a quick tunnel. colloq start --share starts the class and the quick tunnel in one step and prints the link for students; see One link from your own computer.

SituationMethodWhat you need
Your own public IP and ports 80/443Direct CaddyA domain, root access and DNS setup.
A laptop or VM behind NATYour own relay with FRPA public relay with Caddy/frps and an outbound connection.
A short demoQuick Cloudflare tunnelCloudflare reachable from the audience's network; the URL changes each time.
A permanent address through CloudflareNamed tunnelTunnel and DNS set up in advance.

Check that the chosen transport is reachable from the students' real network. A Cloudflare tunnel may be unreachable from some Russian networks; a permanent domain name does not change that route by itself.

Every transport publishes only a server that confirms room isolation: the isolation field of /api/health must say docker (one container per room) or broker (a Pod per room on k3s). Otherwise make host, colloq host, --share and --host refuse before opening anything. The field appears only when the kernel check has passed, so a server with Docker down, or one too old to report the field, is not published.

One link from your own computer

After pip install colloq, one command starts a class and puts it online:

colloq start --share

Colloq starts the class, opens a quick Cloudflare tunnel and prints one block in the terminal: the class link to give your students, https://….trycloudflare.com/s/…. If there is no class yet, the block gives the panel on the public address: create a class there and copy its link from the list — the links in the list already use the public address. Links with /admin/ in them are keys to the panel; never share them.

The link works while the terminal is open; Ctrl+C closes it together with the class. A quick tunnel gets a new address on every start, so send the new link each time. Cloudflare addresses do not open from Russia: for students there, publish through your own relay with colloq start --host <name> instead.

If cloudflared is not installed, the first --share downloads a pinned release from GitHub into ~/.colloq/bin and checks its SHA-256 before running it. COLLOQ_CLOUDFLARED=/path/to/cloudflared uses your own file; COLLOQ_CLOUDFLARED_DOWNLOAD=0 forbids the download. macOS and Linux are supported; on Windows, use WSL 2.

A class is published only when every room's kernel runs in a container of its own: Docker must be running, and the server must confirm the isolation in /api/health. Otherwise --share, --host and colloq host refuse, and the class keeps running locally. Rooms are hardened containers cut off from your home network, but the link is still a door: anyone who has it runs code in a sandbox on your computer. Keep it for your class.

Direct public server

If the machine really has a public address and reachable TCP 80/443, the host tools can set up Caddy:

sudo make host-direct HOST=seminar.example.edu

The tools create the A record for the name themselves through the Cloudflare API, so the domain's zone must be served by Cloudflare. Put a CF_TOKEN with Zone:Read and DNS:Edit permissions into the checkout's .env. If the token cannot see the list of zones, also add CF_ZONE. Proxying is turned off for the record. These permissions are for the operator, not for the application. If ports 80 and 443 are closed from outside, the command refuses before changing anything; on a Vast VM this is always the case. Caddy runs on the host as a service, keeps running after you close the terminal, and proxies production to 127.0.0.1:30080. A k3s installation needs the same COLLOQ_CLUSTER=1 line in .env as the relay.

Your own relay

On a separate public machine, set up Caddy and FRP once:

DOMAIN=colloq.example.edu make relay-setup WHERE=root@your-relay
make host HOST=seminar.colloq.example.edu

Without DOMAIN, the script sets the relay up for the project's own colloq.ru zone, which you do not own. Point *.colloq.example.edu at the relay's address with an A record. If the zone is in Cloudflare, turn proxying off. Caddy gets a certificate for each name the first time it is requested; RELAY_WILDCARD=1 together with CF_TOKEN gets one certificate for the whole zone. A class name is a single label in front of the zone, for example seminar.colloq.example.edu: make host sends only names under RELAY_DOMAIN to the relay, and any other name goes to Cloudflare.

relay-setup prints ready-to-use RELAY_DOMAIN, RELAY_ADDR, RELAY_PORT and RELAY_TOKEN lines. Put them into the .env file in the tools directory on the Colloq machine: in the checkout or in the unpacked release archive. They do not belong in instance.env; the application does not read them. For a k3s installation, add a COLLOQ_CLUSTER=1 line to the same .env. Without it, the script looks for the application on the development port 3000 instead of 127.0.0.1:30080 and fails. Run make host as root on the Colloq machine: the new address is written by cluster.sh public-url, and the key for the owner's link is in the data directory, which ordinary users can't read. The command connects out to the relay on its own. You need frpc of the same version as frps on the relay (relay-setup installs 0.71.0); a k3s machine doesn't need Docker. From the release archive, without the Makefile:

sudo env COLLOQ_HOSTNAME=seminar.colloq.example.edu bash scripts/host.sh

The tunnel works only while the command runs, so run it in tmux or as a service. Vast uses the same transport, and vast-up keeps it in tmux for you. What happens to the address after Ctrl+C is described in Correct links.

Code still runs on the Colloq machine. The relay carries the traffic and becomes a single point of failure for every class that goes through it. Watch its bandwidth and resources; check how large an audience it handles with a load scenario.

The relay serves the built frontend itself. make host uploads assets/, fonts/ and pdf/ to it from the web/dist next to the script — from a checkout of the same release after npm run build, or from the pip package — so only the live room still has to go through the tunnel. The release archive has no frontend build, and then all static files go through the tunnel. The relay passes requests for missing or outdated files on to the tunnel, so the mirror never breaks a class. To check: curl -sI https://seminar.example.edu/assets/<file> — a response with X-Colloq-Mirror: hit came from the relay. Chunk names from the previous build stay available for 30 days.

Cloudflare tunnel

# Temporary address
make host

# Named tunnel: set it up first, then run it
make tunnel-setup HOST=seminar.example.edu
make host HOST=seminar.example.edu

The transport is chosen by name: a HOST under RELAY_DOMAIN goes through the relay, any other name goes through a named tunnel, and without HOST a quick tunnel starts. For Cloudflare, the Colloq machine needs cloudflared; if it is not on PATH, the script uses the pinned release that colloq downloads and checks by SHA-256 (see One link). A quick tunnel gets a random address and works only while the process runs. The script first gets the URL, then updates PUBLIC_URL. In a k3s installation, cluster.sh public-url restarts the application at that point, and open rooms reconnect. When the tunnel stops, the script takes its address off the k3s installation; see correct links. The printed /admin/t/… link is for the owner only. On a k3s installation the script reads the key from /var/lib/colloq/data/setup-token (COLLOQ_STATE_DIR sets another state directory). The data directory belongs to the application (UID 1000) and is closed to everyone else, so run the script with sudo; if it can't read the key, the script names the key's path instead of printing the link.

Correct links

PUBLIC_URL is the server's external origin, and all links are built from it. To change the address of an installed k3s instance, use:

sudo scripts/cluster.sh public-url https://seminar.example.edu

A tunnel's address lives only while make host runs. On a k3s installation, Ctrl+C makes the script set PUBLIC_URL back to http://127.0.0.1:30080, so the panel stops handing out links to the closed tunnel. The application restarts, which can take up to three minutes; don't press Ctrl+C a second time. The address is set back only if the cluster still has the one the script published: another address set in the meantime is left alone. If the cluster refuses — for example, the script isn't running as root, or another command holds the cluster state lock — the script prints the reason and the command to run by hand, and both the cluster and .env stay on the tunnel's address. Direct mode (host-direct) does not set the address back: Caddy keeps running as a service. Set the permanent address with the command above.

Do not leave localhost in external links. After the origin changes, the browser may ask the teacher to sign in again. Before class, check HTTPS, student sign-in, shared editing, running a cell and opening a file from another device.

Ports to keep private

The public entry point must lead to the application over HTTPS. Do not expose the runtime broker 8787, Jupyter 8888, the Kubernetes API 6443, kubelet 10250 or Flannel 8472. NodePort 30080 is bound to loopback for the host proxy.

A firewall that guards the public ports does not cover every request from a Pod to the local node. Read about the NetworkPolicy limitation before you allow untrusted code.