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
libfluxcorepackage built withwasm-bindgen; - Rspack handling for
.wasmassets; onnxruntime-webWASM 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.
Pre-Requisites - Docker
Install Docker on your system before proceeding:
- Linux: Official Docker Engine install guide
- Windows / Mac: Docker Desktop
Verify installation: docker --version && docker compose version
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
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
.envfile.
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
Is Fluxer a PWA?
Yes, the browser client has PWA-related behavior: a web manifest, mobile web app tags, app icons, service worker registration, app-shell navigation caching, push-notification handling, and badge support.
The PWA layer is the client shell. It is not a replacement for the backend.
Can I use Cloudflare Pages?
Not for a full Fluxer deployment. Cloudflare Pages can serve static assets, but Fluxer requires API, gateway, media, LiveKit, storage, database, queue, search, and worker services.
Use Cloudflare Tunnel to expose the Docker stack instead.
Does Fluxer use Vite?
Does Fluxer use WASM or Pyodide?
It uses WASM in the browser. The repo includes a Rust libfluxcore package built with wasm-bindgen, Rspack .wasm asset handling, ONNX Runtime Web WASM assets, and audio/noise-processing WASM assets.
I did not find Pyodide usage.
Can I run only the frontend?
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.
Comments