Skip to main content
Floe publishes two images to GitHub Container Registry. docker-compose.yml pulls both, so self-hosting needs no clone, no Node, and no build. Both are public, so docker pull needs no login.

Tags

Pin a tag with FLOE_IMAGE_TAG:
The variable is FLOE_IMAGE_TAG, not FLOE_VERSION. FLOE_VERSION belongs to the CLI installer and is written with a leading v, as in v1.9.1. Image tags carry no v, so reusing that name would resolve to a tag that does not exist.

Pinning a digest

A tag can be repointed. A digest cannot, so it is the strongest pin:
Take the digest it prints and pin that instead of the tag:
Every tag is verified to resolve to a digest that passed a smoke test before it was applied, so a tag and its digest always refer to an image that was actually started and exercised.

Architectures

Both images are published for linux/amd64 and linux/arm64. Docker picks the right one automatically, so Raspberry Pi, Oracle Ampere, AWS Graviton, and Apple silicon all work with the same commands as anywhere else.
It lists one entry per platform, so you can confirm your architecture is covered.
Each architecture is built and smoke-tested on its own hardware before any tag points at it, and a tag is only published once every architecture of both images has passed. A partly-built release is never visible.That matters more than it sounds. The image optimiser fails at load time rather than at build time, and when it fails it does not error: it quietly serves the original file. So a broken ARM image would look perfectly healthy to anything that only checks whether the page loads. The smoke test asserts the optimiser actually returns WebP, on real ARM.
32-bit ARM (linux/arm/v7, older Raspberry Pi models) is not published. Node dropped support for it and no prebuilt image-processing binaries exist.

Building from source

Contributors, and anyone who wants their own domain in share previews, add the build overlay:
The overlay tags its output floe-server:dev and floe-client:dev, so a local build never replaces a pulled image under the same name. These have to be written into the HTML when the app is built, so a shared image cannot know which domain it will be served from. Claiming one would mean every self-hosted instance advertising somebody else’s site to crawlers, so the published image emits only what is true without knowing its own origin: To put your own domain in them, build the client yourself:
This affects only SEO and link previews. Transfers, the signaling connection, and the relay are unaffected, and all of those are configured at runtime.

Updating

See Operations for backups, logs, and health checks.