Flockdeck docs

Self-hosting

Deploying the relay

The relay is one Go program, flockdeck-relay, run as flockdeck-relay serve with flags (or the matching environment variables; see Configuration).

As a binary

The relay's source is in a private repository, so there is no public download or go install for it. A licensed company is given a kit for running it (the image, a Helm chart, and the upgrade and security guides, below); this page doesn't say whether a licence also includes read access to the source. With a checkout, the relay is pure Go, and one command builds it for the machine it runs on:

go build -trimpath -o flockdeck-relay ./cmd/flockdeck-relay

Building needs read access to the repository, a Go toolchain of the version in go.mod, and a git credential that can read the web client's module (github.com/Flockdeck/flockdeck-remote, also private), with GOPRIVATE set to it. Run the binary directly, or under whatever process supervisor your platform already uses (systemd, a container orchestrator's own restart policy, and so on). The relay itself doesn't daemonize.

As a container

The relay's repository has a Dockerfile. Building the image yourself needs a build secret, because the relay embeds Flockdeck's own web client and that module isn't public:

docker build --secret id=flockdeck_remote_token,env=FLOCKDECK_REMOTE_TOKEN -t flockdeck-relay .

A licensed company is given a built image, ghcr.io/flockdeck/flockdeck-relay, in a private registry: pulling it needs the pull token issued with the licence, so it doesn't need to build the image itself. The image's command is serve -data /data -addr :8080; -public-url has no default and is always given at run time. Running it looks like:

docker run \
  -p 127.0.0.1:8080:8080 \
  -v relay-data:/data \
  flockdeck-relay serve \
    -public-url https://relay.example.com \
    -addr :8080 \
    -trust-proxy \
    -data /data

-v relay-data:/data is the volume that has to survive restarts; see Storage and data. The image runs as a non-root user, and /data in it is owned by that user, so a fresh named volume works as is.

On Kubernetes

The relay's repository also has a Helm chart, deploy/helm/flockdeck-relay, for a licensed company running the relay on its own cluster. It runs exactly one pod and replaces it on an upgrade instead of rolling it: the relay keeps every desktop's tunnel in memory, so a second replica would be a second relay that knows about only some of the desktops. It needs Kubernetes 1.24 or later, Helm 3, an ingress that passes WebSockets through without buffering, a TLS certificate for the relay's hostname, and the pull token issued with the licence. The chart's own README walks through installing it.

Three ways to terminate TLS

1. The relay's own ACME client

If DNS for your relay's hostname points straight at the machine running it, the relay can get and renew its own certificate:

flockdeck-relay serve -acme-domain relay.example.com -acme-email ops@example.com -data /data

Use this when there's nothing else in front of the relay. It listens on :443 unless you give -addr, and on :80 for the challenges and a redirect to https. -public-url defaults to https:// and the first domain, and a list of domains (comma-separated) gets a certificate for each; one of them has to be the host of -public-url. The certificates are kept in acme under -data. It can't be combined with -tls-cert, and it can't get the wildcard certificate -desk-domain needs.

2. Your own certificate

flockdeck-relay serve -public-url https://relay.example.com -addr :443 -tls-cert /etc/relay/fullchain.pem -tls-key /etc/relay/privkey.pem -data /data

-tls-cert and -tls-key go together, and -public-url has to be https://. The relay watches these files and reloads them when they change, so a certificate renewal elsewhere on the machine doesn't need a restart.

3. Behind a reverse proxy or load balancer

If something else (an ingress controller, a load balancer, another proxy) already terminates TLS, run the relay on plain HTTP behind it:

flockdeck-relay serve -public-url https://relay.example.com -addr 127.0.0.1:8080 -trust-proxy -data /data

-public-url is what the relay tells desktops and devices to use, even though it's listening on plain HTTP internally. -trust-proxy tells it to take the client address from forwarded headers rather than the TCP connection, which is the proxy's, not the visitor's.

Whichever proxy sits in front, it has to forward WebSocket upgrades without buffering; see Requirements.

Confirm it's up

Two health endpoints: