Fluxer looks like a Discord-style community chat app at first glance.

Under the hood, it is much more than a frontend. It is a full messaging and VoIP platform with a browser app, realtime gateway, API, background workers, media proxy, LiveKit voice, object storage, search, queues, and several Rust service components.

That makes it interesting for self-hosters, but it also means you should approach it like infrastructure.

What is Fluxer?

Fluxer is a free and open-source instant messaging and VoIP chat app for friends, groups, and communities.

I inspected commit:

522cf08e6152bfd2dee8015a1f8288786633efa1

The repository is AGPL licensed and is organized as a TypeScript/Rust monorepo.

Why Self-Host It?

Fluxer is for people who want a self-hostable community chat system rather than another hosted SaaS workspace.

Good reasons to look at it:

  • community text chat;
  • group and direct messaging;
  • voice/VoIP rooms;
  • media uploads;
  • reactions, embeds, and unfurling;
  • a browser client with PWA behavior;
  • desktop packaging through Electron;
  • a public AGPL codebase that can be inspected and modified.

The tradeoff is complexity. This is not a “one container and SQLite” weekend app. Fluxer’s official self-hosting setup is a multi-service deployment.

Architecture

The repo contains several major components:

  • fluxer_app: React browser client.
  • fluxer_app_proxy: Rust app proxy that serves the app, service worker, manifest, bootstrap data, and security headers.
  • fluxer_api: TypeScript API service.
  • fluxer_gateway: realtime gateway.
  • fluxer_media_proxy: media upload and delivery proxy.
  • fluxer_admin: admin interface.
  • fluxer_messages, fluxer_users, fluxer_gifs, fluxer_snowflakes, fluxer_unfurl: Rust services with router/shard roles.
  • fluxer_static: static web, emoji, avatar, desktop, and media assets.
  • fluxer_desktop: Electron desktop shell.
  • packages: shared TypeScript packages for config, schemas, limits, logging, i18n, voice engine, OpenAPI, and utilities.

The self-hosted stack then adds:

  • Caddy as edge proxy;
  • PostgreSQL;
  • Valkey;
  • NATS with JetStream;
  • Meilisearch;
  • SeaweedFS as S3-compatible object storage;
  • LiveKit for voice/WebRTC.

So the clean mental model is:

Browser/PWA -> Caddy edge -> app proxy/API/gateway/media/admin/livekit
Backend services -> Postgres, Valkey, NATS, Meilisearch, SeaweedFS

PWA Details

Fluxer has a real browser UI and PWA hooks.

The app HTML links /manifest.json, includes mobile web app meta tags, references app icons, and registers a service worker from the production browser client.

The service worker is built by:

fluxer_app/scripts/build-sw.mjs

It handles same-origin app navigations, app-shell caching, /manifest.json, and /version.json. It also includes push-notification and app-badge code paths.

That is useful, but it does not make Fluxer an offline chat server. The service worker helps the browser shell behave like an installed app. Messaging, login, uploads, realtime gateway traffic, push delivery, and voice still need the backend.

Does It Use Vite?

Not for the main production web app.

The browser client uses React and Rspack. The fluxer_app/package.json production build runs WASM codegen, generated CSS/i18n assets, rspack build --mode production, and then the service worker build script.

You will see Vite-adjacent pieces in the repo, especially Vitest and a vite-env.d.ts type file. That does not mean the main app is a Vite static site.

Does It Use WASM or Pyodide?

Fluxer uses browser-side WASM.

The inspected client includes:

  • a Rust libfluxcore package built with wasm-bindgen;
  • Rspack handling for .wasm assets;
  • onnxruntime-web WASM assets;
  • audio/noise-suppression dependencies that ship WASM/worklet assets;
  • DeepFilterNet-related static assets.

I did not find Pyodide usage.

Can It Be Deployed Statically to Cloudflare Pages?

Not with full functionality.

You could host some browser build artifacts on a static host, but Fluxer as a product needs the backend. The app needs API routes, auth/session state, realtime gateway behavior, media upload/download routing, LiveKit signaling/media, service discovery, storage, search, and background jobs.

The official self-hosting deployment expects a complete service stack behind one public origin. Cloudflare Pages alone does not provide that.

A practical Cloudflare setup is different:

Cloudflare Tunnel -> local Fluxer Caddy edge -> Docker Compose stack

That gives you Cloudflare-managed ingress while keeping the backend services alive behind it.

Self-Hosting with Docker

I mirrored Fluxer’s official self-hosting Compose files into the Home-Lab snippet instead of writing a tiny incomplete compose.

The reusable Home-Lab config is here:

The site includes the same Compose file from the local snippets folder:

assets/snippets/fluxer/docker-compose.yml
includeyaml: file not found or not allowed by security.filesystem.allow: assets/snippets/fluxer/docker-compose.yml

Start by preparing the environment:

cd assets/snippets/fluxer
cp .env.sample .env
$EDITOR .env

Generate secrets:

openssl rand -hex 32
openssl rand -base64 32

You also need VAPID keys for web push.

Then start the stack:

docker compose up -d

The default mode expects Fluxer to bind public HTTP/HTTPS ports and obtain certificates through Caddy. For most home-lab users, I would put it behind an existing reverse proxy or a tunnel instead.

Reverse Proxy Mode

For nginx, Traefik, HAProxy, or another Caddy instance in front:

COMPOSE_FILE=docker-compose.yml:docker-compose.proxy.yml
FLUXER_EDGE_BIND=127.0.0.1:8080
FLUXER_PUBLIC_SCHEME=https
FLUXER_PUBLIC_PORT=443

Your proxy should forward the whole public hostname to:

http://127.0.0.1:8080

Do not route only / to the app. Fluxer also needs /api, /gateway, /media, /livekit, /admin, static asset paths, and /.well-known/fluxer.

Cloudflare Tunnel Mode

For Cloudflare Tunnel:

COMPOSE_FILE=docker-compose.yml:tunnel.compose.yml
FLUXER_HTTP_PORT=127.0.0.1:8080
FLUXER_PUBLIC_SCHEME=https
FLUXER_PUBLIC_PORT=443

Point the tunnel service at:

http://127.0.0.1:8080

That is the deployment mode that maps cleanly to Cloudflare without pretending this is a static Cloudflare Pages app.

Field Test

I validated the Docker Compose files with the sample environment:

docker compose --env-file .env.sample config >/tmp/fluxer-compose-config.yml
docker compose --env-file .env.sample -f docker-compose.yml -f docker-compose.proxy.yml config >/tmp/fluxer-compose-proxy-config.yml
docker compose --env-file .env.sample -f docker-compose.yml -f tunnel.compose.yml config >/tmp/fluxer-compose-tunnel-config.yml

All three rendered successfully.

I also checked OCI manifests for the default v1 images used by the stack:

ghcr.io/fluxerapp/fluxer-api:v1
ghcr.io/fluxerapp/fluxer-app-proxy-self-hosted:v1
ghcr.io/fluxerapp/fluxer-gateway:v1
ghcr.io/fluxerapp/fluxer-media-proxy:v1

I did not start the complete stack in this pass. It is a large production-style system with many services and required generated secrets, so the validation here is configuration rendering plus image availability, not a claim that I completed an end-to-end chat and voice test.

Operational Notes

Back up the volumes before upgrades:

  • Postgres;
  • Valkey;
  • NATS JetStream;
  • Meilisearch;
  • SeaweedFS;
  • the .env file.

The Valkey point is worth calling out because this deployment treats it as more than disposable cache for some durable queue state.

For production use, also plan:

  • outbound email if you want account email flows;
  • captcha if you expose public registration;
  • public HTTPS with correct forwarded client IP handling;
  • LiveKit TCP/UDP reachability for voice;
  • object storage capacity and backup policy;
  • monitoring on API, gateway, worker, and media services.

FAQ

Conclusion

Fluxer is one of the more serious open-source attempts at a modern community chat and VoIP stack.

It has the pieces self-hosters usually ask about: browser app, installable PWA behavior, desktop packaging, voice, media, admin, and a Docker Compose deployment.

The honest caveat is that it is infrastructure. If you want a tiny chat app, Fluxer is too much. If you want to run a Discord-like open chat system and are comfortable operating a multi-service stack, it is worth studying.