diff --git a/astro.config.mjs b/astro.config.mjs
index 470001f..7cbe8da 100644
--- a/astro.config.mjs
+++ b/astro.config.mjs
@@ -59,12 +59,12 @@ export default defineConfig({
{
icon: "github",
label: "GitHub (App)",
- href: "https://github.com/Fancy-Mumble/FancyMumbleNext",
+ href: "https://github.com/Fancy-Mumble/FancyMumble",
},
{
icon: "github",
- label: "GitHub (Server)",
- href: "https://github.com/Fancy-Mumble/mumble-server",
+ label: "GitHub (Starling server)",
+ href: "https://github.com/Fancy-Mumble/starling",
},
],
editLink: {
@@ -168,33 +168,10 @@ export default defineConfig({
badge: { text: "Ops", variant: "note" },
items: [
{ label: "Docker quick start", link: "/server/docker/" },
- { label: "Setup wizard", link: "/server/wizard/" },
+ { label: "First-run setup", link: "/server/wizard/" },
{ label: "Configuration reference", link: "/server/config/" },
{ label: "Ports & networking", link: "/server/network/" },
- {
- label: "Feature deep-dives",
- collapsed: false,
- items: [
- { label: "Persistent chat", link: "/server/features/persistent-chat/" },
- { label: "Push notifications", link: "/server/features/push/" },
- { label: "Screen sharing relay", link: "/server/features/webrtc-sfu/" },
- { label: "File server", link: "/server/features/file-server/" },
- { label: "Link previews", link: "/server/features/link-previews/" },
- { label: "Reactions & polls", link: "/server/features/reactions/" },
- { label: "Watch Together", link: "/server/features/watch-together/" },
- { label: "Whiteboard", link: "/server/features/whiteboard/" },
- { label: "Live documents", link: "/server/features/live-doc/" },
- ],
- },
- {
- label: "Plugins",
- collapsed: false,
- items: [
- { label: "Plugin system overview", link: "/server/plugins/overview/" },
- { label: "Using plugins", link: "/server/plugins/using/" },
- { label: "Developing a plugin", link: "/server/plugins/developing/" },
- ],
- },
+ { label: "Feature availability", link: "/server/features/" },
{ label: "Customize & disable features", link: "/server/customize/" },
{ label: "Building from source", link: "/server/build/" },
{ label: "Upgrade & backup", link: "/server/upgrade/" },
diff --git a/public/examples/avatars/anime-demon.png b/public/examples/avatars/anime-demon.png
new file mode 100644
index 0000000..a0c24cf
Binary files /dev/null and b/public/examples/avatars/anime-demon.png differ
diff --git a/public/examples/avatars/anime-girl.png b/public/examples/avatars/anime-girl.png
new file mode 100644
index 0000000..b7021c9
Binary files /dev/null and b/public/examples/avatars/anime-girl.png differ
diff --git a/public/examples/avatars/anime-pastel.png b/public/examples/avatars/anime-pastel.png
new file mode 100644
index 0000000..3b3ae7c
Binary files /dev/null and b/public/examples/avatars/anime-pastel.png differ
diff --git a/public/examples/avatars/car-enthusiast.png b/public/examples/avatars/car-enthusiast.png
new file mode 100644
index 0000000..f689402
Binary files /dev/null and b/public/examples/avatars/car-enthusiast.png differ
diff --git a/public/examples/avatars/comics.png b/public/examples/avatars/comics.png
new file mode 100644
index 0000000..2081688
Binary files /dev/null and b/public/examples/avatars/comics.png differ
diff --git a/public/examples/avatars/dog.png b/public/examples/avatars/dog.png
new file mode 100644
index 0000000..51f4f69
Binary files /dev/null and b/public/examples/avatars/dog.png differ
diff --git a/public/examples/avatars/flowers.png b/public/examples/avatars/flowers.png
new file mode 100644
index 0000000..9819cbc
Binary files /dev/null and b/public/examples/avatars/flowers.png differ
diff --git a/public/examples/avatars/k-pop.png b/public/examples/avatars/k-pop.png
new file mode 100644
index 0000000..da4e393
Binary files /dev/null and b/public/examples/avatars/k-pop.png differ
diff --git a/public/examples/avatars/manga-reader.png b/public/examples/avatars/manga-reader.png
new file mode 100644
index 0000000..8d03790
Binary files /dev/null and b/public/examples/avatars/manga-reader.png differ
diff --git a/public/examples/banners/anime-demon.png b/public/examples/banners/anime-demon.png
new file mode 100644
index 0000000..7bbda3d
Binary files /dev/null and b/public/examples/banners/anime-demon.png differ
diff --git a/public/examples/banners/anime-pastel.png b/public/examples/banners/anime-pastel.png
new file mode 100644
index 0000000..fe6df41
Binary files /dev/null and b/public/examples/banners/anime-pastel.png differ
diff --git a/public/examples/banners/anime.png b/public/examples/banners/anime.png
new file mode 100644
index 0000000..13e4c2a
Binary files /dev/null and b/public/examples/banners/anime.png differ
diff --git a/public/examples/banners/cars.png b/public/examples/banners/cars.png
new file mode 100644
index 0000000..e335622
Binary files /dev/null and b/public/examples/banners/cars.png differ
diff --git a/public/examples/banners/cats.png b/public/examples/banners/cats.png
new file mode 100644
index 0000000..dd3c47e
Binary files /dev/null and b/public/examples/banners/cats.png differ
diff --git a/public/examples/banners/comics.png b/public/examples/banners/comics.png
new file mode 100644
index 0000000..74d4614
Binary files /dev/null and b/public/examples/banners/comics.png differ
diff --git a/public/examples/banners/dogs.png b/public/examples/banners/dogs.png
new file mode 100644
index 0000000..83cbf27
Binary files /dev/null and b/public/examples/banners/dogs.png differ
diff --git a/public/examples/banners/flowers.png b/public/examples/banners/flowers.png
new file mode 100644
index 0000000..40e505c
Binary files /dev/null and b/public/examples/banners/flowers.png differ
diff --git a/public/examples/banners/k-pop.png b/public/examples/banners/k-pop.png
new file mode 100644
index 0000000..c818737
Binary files /dev/null and b/public/examples/banners/k-pop.png differ
diff --git a/public/examples/banners/manga.png b/public/examples/banners/manga.png
new file mode 100644
index 0000000..0c72a03
Binary files /dev/null and b/public/examples/banners/manga.png differ
diff --git a/public/examples/community-scene.html b/public/examples/community-scene.html
new file mode 100644
index 0000000..c5b9d7a
--- /dev/null
+++ b/public/examples/community-scene.html
@@ -0,0 +1,135 @@
+
+
+
+
+
+ Fancy Mumble sample community scene
+
+
+
+
+
F Fancy Mumble Community voice − □ ×
+
+
+ ⌕ Search channels and members
+ Channels
+ # lounge General conversation · 5 members
+ In this channel
+ Rin Drawing tonight
+ Torque Car club
+ Hana Playlist curator
+ Flora Garden updates
+ Scout Walk break
+
+
+
+ ✦ Welcome to the community lounge. Say hello and share your interests.
+ Today
+
+
Torque Car club 19:42
Just finished the night drive. That coastal road was incredible.
🏁 3 ✨ 2
+
Rin Artist 19:44
That sounds like a perfect reference for my next illustration!
+
Hana Music 19:46
I made a playlist for tonight's sketch session. 🎵
+
Flora Gardener 19:49
I'll bring the flower references. My roses are finally blooming.
🌸 4
+
+ + Write a message… ➤
+
+
+
Member profile ×
+
+
+
+
+
Rin
+
@rin · Online
+
Artist
+
Illustrating imaginary places, collecting color palettes, and meeting friends in voice chat.
+
✦ Sketchbook open · Listening to Hana's playlist
+
+
+
Select a member to see their avatar, banner, bio, and status.
+
+
+
+
+
+
diff --git a/public/examples/sample-avatar.png b/public/examples/sample-avatar.png
new file mode 100644
index 0000000..9909fbe
Binary files /dev/null and b/public/examples/sample-avatar.png differ
diff --git a/public/examples/sample-chat-background.png b/public/examples/sample-chat-background.png
new file mode 100644
index 0000000..8309151
Binary files /dev/null and b/public/examples/sample-chat-background.png differ
diff --git a/public/examples/sample-profile-banner.png b/public/examples/sample-profile-banner.png
new file mode 100644
index 0000000..0b5041b
Binary files /dev/null and b/public/examples/sample-profile-banner.png differ
diff --git a/public/mainpage.png b/public/mainpage.png
index 9e2190c..aa6e0e9 100644
Binary files a/public/mainpage.png and b/public/mainpage.png differ
diff --git a/public/preview.png b/public/preview.png
index 7671f15..aa6e0e9 100644
Binary files a/public/preview.png and b/public/preview.png differ
diff --git a/public/screenshot-getting-started-connect-1.png b/public/screenshot-getting-started-connect-1.png
index 80e8d3d..5016cca 100644
Binary files a/public/screenshot-getting-started-connect-1.png and b/public/screenshot-getting-started-connect-1.png differ
diff --git a/public/screenshot-getting-started-connect-2.png b/public/screenshot-getting-started-connect-2.png
index 14079e7..bb88c34 100644
Binary files a/public/screenshot-getting-started-connect-2.png and b/public/screenshot-getting-started-connect-2.png differ
diff --git a/public/screenshot-getting-started-install-2.png b/public/screenshot-getting-started-install-2.png
index 80e8d3d..915bf16 100644
Binary files a/public/screenshot-getting-started-install-2.png and b/public/screenshot-getting-started-install-2.png differ
diff --git a/public/screenshot-users-chat-community.png b/public/screenshot-users-chat-community.png
new file mode 100644
index 0000000..c7376d4
Binary files /dev/null and b/public/screenshot-users-chat-community.png differ
diff --git a/src/components/ChatBackgroundExample.astro b/src/components/ChatBackgroundExample.astro
new file mode 100644
index 0000000..5105518
--- /dev/null
+++ b/src/components/ChatBackgroundExample.astro
@@ -0,0 +1,40 @@
+
+
+
+
+
+
# lounge
+
Sam Ready to join the call?
+
Alex Yep, I can see the lake behind our chat.
+
Write a message…
+
+
+ Illustrative preview with the sample wallpaper, a dark overlay, and readable messages.
+
+
+
diff --git a/src/components/ProfileExample.astro b/src/components/ProfileExample.astro
new file mode 100644
index 0000000..38dc8c7
--- /dev/null
+++ b/src/components/ProfileExample.astro
@@ -0,0 +1,141 @@
+---
+const profiles = [
+ { label: 'Cats', name: 'Alex', tagline: 'Here for the late-night conversations.', avatar: '/examples/sample-avatar.png', avatarAlt: 'Black cat wearing blue headphones', banner: '/examples/banners/cats.png', bannerAlt: 'Cats at a glowing night window' },
+ { label: 'Dogs', name: 'Scout', tagline: 'Walk break and voice chat.', avatar: '/examples/avatars/dog.png', avatarAlt: 'Golden retriever wearing a teal scarf', banner: '/examples/banners/dogs.png', bannerAlt: 'Sunset over a meadow and trail' },
+ { label: 'Cars', name: 'Torque', tagline: 'Back from the coastal drive.', avatar: '/examples/avatars/car-enthusiast.png', avatarAlt: 'Midnight-blue sports coupe', banner: '/examples/banners/cars.png', bannerAlt: 'Sports car on a coastal road at dusk' },
+ { label: 'Anime · pop', name: 'Rin', tagline: 'Sketchbook open.', avatar: '/examples/avatars/anime-girl.png', avatarAlt: 'Original pop-color anime character', banner: '/examples/banners/anime.png', bannerAlt: 'Two anime friends against vivid graphic color' },
+ { label: 'Anime · VN', name: 'Mira', tagline: 'A little art and a little tea.', avatar: '/examples/avatars/anime-pastel.png', avatarAlt: 'Original visual-novel anime character', banner: '/examples/banners/anime-pastel.png', bannerAlt: 'Two anime friends on a clean white background' },
+ { label: 'Anime · demon', name: 'Nyx', tagline: 'Game night starts at eight.', avatar: '/examples/avatars/anime-demon.png', avatarAlt: 'Original cartoon demon character', banner: '/examples/banners/anime-demon.png', bannerAlt: 'Two cartoon demon friends on a burgundy background' },
+ { label: 'Manga', name: 'Sora', tagline: 'One more chapter.', avatar: '/examples/avatars/manga-reader.png', avatarAlt: 'Monochrome ink portrait of a manga reader', banner: '/examples/banners/manga.png', bannerAlt: 'Ink-style rainy street and bookshop' },
+ { label: 'K-pop', name: 'Hana', tagline: 'Playlist curator.', avatar: '/examples/avatars/k-pop.png', avatarAlt: 'Fictional pop performer under stage lights', banner: '/examples/banners/k-pop.png', bannerAlt: 'Lavender and cyan concert lights' },
+ { label: 'Comics', name: 'Comet', tagline: 'Panels, capes, and big ideas.', avatar: '/examples/avatars/comics.png', avatarAlt: 'Original comic explorer wearing an amber visor', banner: '/examples/banners/comics.png', bannerAlt: 'Graphic futuristic city at sunset' },
+ { label: 'Flowers', name: 'Flora', tagline: 'Roses are blooming.', avatar: '/examples/avatars/flowers.png', avatarAlt: 'Peony and rose arrangement', banner: '/examples/banners/flowers.png', bannerAlt: 'Three flowers against an airy peach backdrop' },
+];
+---
+
+
+
+
+
+
+
+
+
+ {profiles[0].name}
+ {profiles[0].tagline}
+
+
+
+ Example profile preview. Select a person to see their avatar and matching banner.
+
+ {profiles.map((profile, index) => (
+
+
+
+ {profile.label}
+
+
+
+ ))}
+
+ Cats profile selected
+
+
+
+
+
diff --git a/src/content/docs/admin/bans.mdx b/src/content/docs/admin/bans.mdx
index 277599e..9177cb5 100644
--- a/src/content/docs/admin/bans.mdx
+++ b/src/content/docs/admin/bans.mdx
@@ -48,10 +48,9 @@ Open **Admin, Ban list**, click **Add ban**:
Useful when you know who you want to block before they connect.
-## Auto-ban
+## Auto-ban on the older C++ server
-The server can auto-ban brute-force connection attempts. Add these
-to the `environment:` block of your `docker-compose.yml`:
+The settings below apply only to the older C++ server image. They are not Starling configuration. For Starling, consult its [current TOML reference](https://github.com/Fancy-Mumble/starling/blob/main/examples/reference.toml) before configuring connection limits:
```yaml
environment:
diff --git a/src/content/docs/admin/server-plugins.mdx b/src/content/docs/admin/server-plugins.mdx
index 90184b3..3f11c1d 100644
--- a/src/content/docs/admin/server-plugins.mdx
+++ b/src/content/docs/admin/server-plugins.mdx
@@ -1,84 +1,10 @@
---
-title: Server Plugins
-description: Install, enable, disable, and remove server-side plugins from the admin panel.
-sidebar:
- order: 10
+title: Server plugins
+description: Understand Starling's plugin host and its current installation path.
---
-import { Steps, Aside, Card } from '@astrojs/starlight/components';
+Starling has a plugins service and a Rust plugin host. It can load native plugins and WebAssembly components from its configured plugin directory. The host has been exercised with the published native examples and a WebAssembly component; installing plugin bytes over the wire and operator REST routes remain unfinished in the checked-out implementation.
-The **Server Plugins** tab in the admin panel lets you manage all
-plugins running on your Fancy Mumble server. Plugins extend the
-server with new behaviour — slash commands, interactive message cards,
-modals, live settings panels, and more.
+For now, operators place a compatible plugin binary in the configured plugins directory and enable it through the available plugin RPC. Check its startup logs and advertised plugin registry before expecting client controls to appear. A built-in service named plugins does not mean every plugin from the older C++ server has been ported.
-
-Plugin administration requires **Fancy Mumble Server 0.4.0 or newer**.
-On older servers the tab shows an "unsupported" notice and all controls
-are disabled.
-
-
-
- Screenshot placeholder: Server Plugins tab with three installed plugins.
-
-
-## What the list shows
-
-Each row in the plugin list displays:
-
-| Field | Meaning |
-|-------|---------|
-| **Name** | Internal plugin identifier (e.g. `fancy-greeter`). |
-| **Version** | Installed version string. |
-| **Status** | Enabled (green) or disabled (grey). |
-| **Loaded** | Whether the plugin process is currently running. |
-| **Marketplace** | Badge if the plugin was installed from the marketplace. |
-| **Installed at** | UTC timestamp of when the plugin was installed. |
-
-## Enable and disable plugins
-
-Toggle the power-button icon next to a plugin to enable or disable it
-without uninstalling. A disabled plugin stays on disk but its process
-is stopped and its manifest is no longer advertised to clients.
-
-The change is confirmed by a `plugin-admin-ack` event from the server.
-If the server returns an error it is shown in a banner above the list.
-
-## Uninstall a plugin
-
-Click the **trash icon** next to a marketplace-installed plugin and
-confirm the dialog.
-
-
-Built-in plugins (shipped with the server binary) and plugins
-installed manually (not from the marketplace) do not show a delete
-button. Remove them by editing the server's `plugins/` directory
-directly.
-
-
-## Install from the Marketplace
-
-The **Marketplace** tab (see [Marketplace](./marketplace)) lets you
-browse and install community plugins. Once installed they appear in
-this list automatically.
-
-## Refresh
-
-Click **Refresh** (or the icon in the toolbar) to re-fetch the current
-plugin list from the server. The list refreshes automatically after
-every install, enable, or disable action.
-
-## Troubleshooting
-
-**"Load timed out"** — The server did not respond within 10 seconds.
-Check that the server process is running and that you have admin
-(Write permission on the root channel) rights.
-
-**"Unknown error"** — The server returned an error without a message.
-Check the server logs for more detail.
-
-## See also
-
-- [Marketplace](/admin/marketplace/) — install new plugins from the community catalogue.
-- [Using plugins (server config)](/server/plugins/using/) — enable and disable plugins via `mumble-server.ini`, add plugins via Docker volume mount, and view startup logs.
-- [Plugins (user view)](/users/plugins/) — what your users see when a new plugin appears on the server (trust prompt, slash commands, capability management).
+See the [Starling plugin-host status and porting plan](https://github.com/Fancy-Mumble/starling/blob/main/docs/PLUGIN-HOST-PLAN.md) and [feature availability](/server/features/). The older [plugin guides](/server/plugins/overview/) describe the C++ fork's host and INI configuration.
diff --git a/src/content/docs/admin/superuser.mdx b/src/content/docs/admin/superuser.mdx
index b12f7ce..0a87ed6 100644
--- a/src/content/docs/admin/superuser.mdx
+++ b/src/content/docs/admin/superuser.mdx
@@ -1,148 +1,18 @@
---
-title: SuperUser & first login
-description: Take ownership of your fresh server with the SuperUser admin account.
-sidebar:
- order: 1
+title: SuperUser and first login
+description: Sign in with Starling's first-run administrator account.
---
-import { Steps, Aside, Card, CardGrid } from '@astrojs/starlight/components';
+Starling creates the built-in SuperUser account on first start and prints a generated password. Save it in a password manager. In the distributed Docker stack, inspect `docker compose logs userdata`; in the all-in-one service, use `docker compose logs starling`. The password is only printed when it is created; it does not appear on every restart.
-Every Mumble server has a built-in **SuperUser** account. It is the
-one account that bypasses every ACL on the server, so it is what you
-use to **bootstrap your community**. Once you have set up roles and
-registered users, you will almost never log in as SuperUser again.
+Open Fancy Mumble, connect to your server, enter SuperUser as the username, and use the generated password when prompted. The SuperUser bypasses channel ACLs and can bootstrap channels, accounts, and server settings.
+If you lose the password, stop the server and run the command against the same data directory or service configuration as the running server:
-
- Screenshot placeholder: admin panel after first SuperUser login, with empty role and user lists.
-
+~~~sh
+starling set-superuser-password "a-new-strong-password" --server 1 --config starling.toml
+~~~
-## Set the SuperUser password
+Omit the server argument for the first configured instance. The older Docker variable MUMBLE_SUPERUSER_PASSWORD and the C++ mumble-server --set-su-pw command do not configure Starling.
-If you set `MUMBLE_SUPERUSER_PASSWORD` in your Docker setup, you
-already have a password. Skip ahead.
-
-If not, the password was randomly generated on the first boot. Find
-it in the logs:
-
-```bash
-docker logs mumble-server 2>&1 | grep -i superuser
-```
-
-Or set a new one any time:
-
-```bash
-docker exec mumble-server mumble-server \
- --ini /data/mumble_server_config.ini \
- --set-su-pw "your-strong-password"
-```
-
-
-Anyone with the SuperUser password can do anything on the server.
-Keep the password in a secure place (your password manager). Do not
-share it.
-
-
-## Log in as SuperUser
-
-
-1. Open Fancy Mumble.
-2. Connect to your server.
-3. When the wizard asks for a username, type `SuperUser`.
-4. When the password dialog appears, paste your password.
-5. The admin button next to the
- disconnect button should now be visible. Click it to open the admin panel.
-
-
-The first time you do this on a fresh server, the SuperUser is the
-**only** account, and everyone else who connects is unauthenticated.
-
-## First steps on a fresh server
-
-The big checklist:
-
-
-
-1. **Set up the welcome text** in **Admin, Server settings**, so new
- joiners see a friendly message.
-
-2. **Create your top-level channels**: lobby, voice, off-topic, and
- so on. See [Channels](/admin/channels/).
-
-3. **Create a "Moderator" role** with channel-management and mute
- permissions, and assign it to your most-trusted friends.
- See [Roles & permissions](/admin/roles/).
-
-4. **Create a "Member" role** that gives chat write access to the
- right channels, and decide whether you want to require registration
- to chat.
-
-5. **Set up the onboarding flow** if you want new members to pick
- their interests on first join. See
- [Onboarding workflow](/admin/onboarding/).
-
-6. **Upload a few custom emotes** as a community starter pack. See
- [Custom emotes](/admin/emotes/).
-
-7. **Take a backup**. See [Upgrade & backup](/server/upgrade/).
-
-
-
-## Disable SuperUser after setup
-
-For ongoing administration, you should **not use SuperUser**. Instead:
-
-
-1. Connect with your own user account.
-2. As SuperUser, register your account: right-click your name, **Register**.
-3. As SuperUser, give your account the **Administrator** role.
-4. Disconnect.
-5. Reconnect as your normal user. Verify you have admin access.
-
-
-You can either:
-
-- **Keep SuperUser as a break-glass account** (recommended), or
-- **Disable it** by leaving the password unset and starting the server
- fresh. Hard to reverse, so be sure.
-
-## When to use SuperUser
-
-Only in two situations:
-
-- You locked yourself out of the admin role and need to fix the ACL.
-- A bug or accident has corrupted permissions and only the
- unconditional-bypass account can fix it.
-
-For everything else, use a regular admin account.
-
-## Recovering from "I locked myself out"
-
-If you accidentally removed your own admin role:
-
-
-1. Find the SuperUser password (or reset it as above).
-2. Log in as SuperUser.
-3. Restore your role.
-4. Log out again.
-
-
-## Pitfalls
-
-- **Cannot log in as SuperUser**: the password is wrong. Reset it
- with the `--set-su-pw` command.
-- **Register as SuperUser**: not possible by
- design. SuperUser is hard-coded outside the user table.
-- **Lost the password**: same fix, `--set-su-pw` to set a new one.
-- **Changed a password in the app and SuperUser login broke**: the
- in-app password in your profile settings applies to your *regular
- user account*, not to SuperUser. SuperUser has no profile in the
- app - its password is set only via `--set-su-pw` or the
- `MUMBLE_SUPERUSER_PASSWORD` environment variable.
-- **Can't talk as SuperUser**: you are logged in as SuperUser, but
- you cannot talk or see channels. This is normal. SuperUser bypasses
- ACLs, but it can also not talk by default.
-
-## Next step
-
-Continue with [Channels](/admin/channels/) to set up your space.
+After logging in, set a welcome text, create channels, configure ACLs and roles, and make a [backup](/server/upgrade/).
diff --git a/src/content/docs/admin/users.mdx b/src/content/docs/admin/users.mdx
index c36660f..38dfc6e 100644
--- a/src/content/docs/admin/users.mdx
+++ b/src/content/docs/admin/users.mdx
@@ -34,13 +34,7 @@ The user right-clicks their own name in the user list and picks
- **Auto-approves** (default for many servers).
- **Queues for admin approval**.
-Configure the gate with:
-
-```yaml
-environment:
- MUMBLE_CONFIG_ALLOWREGISTRATION: true
- MUMBLE_CONFIG_REGISTRATIONREQUIRESAPPROVAL: false
-```
+Registration policy depends on the server implementation. The older C++ image uses MUMBLE_CONFIG_* variables; they do not configure Starling. Check the current [Starling settings reference](https://github.com/Fancy-Mumble/starling/blob/main/examples/reference.toml) and test the desired approval flow before inviting users.
### Admin-initiated
diff --git a/src/content/docs/getting-started/connect.mdx b/src/content/docs/getting-started/connect.mdx
index 7b2d9d2..38055a7 100644
--- a/src/content/docs/getting-started/connect.mdx
+++ b/src/content/docs/getting-started/connect.mdx
@@ -1,156 +1,37 @@
---
title: Connect to a server
-description: How to join a server with Fancy Mumble, including password prompts and the public server list.
-sidebar:
- order: 2
+description: Add a saved server, choose an identity, and connect in Nebula or Standard.
---
-import { Steps, Tabs, TabItem, Aside, Card, CardGrid } from '@astrojs/starlight/components';
-import PlantUML from '../../../components/PlantUML.astro';
-import { Icon } from 'astro-icon/components';
+Fancy Mumble can connect to Starling and to standard Mumble servers. Ask the server owner for its host name, port if different from **64738**, and any password.
-You have installed the app. Now you need somewhere to talk. This page
-covers three ways to connect:
+## Add a server in Nebula
-1. A server address from a friend or admin (most common).
-2. Browsing the **Public server list**.
-3. Your own self-hosted server (see [Docker quick start](/server/docker/)).
+Nebula is the design for a new profile.
-## The Connect screen
+1. Open **Add server** from the server rail or choose **Add server by address…** from **Quick connect**.
+2. Enter the host, port, and the username others should see. The dialog can also save a friendly label, certificate identity, and password.
+3. Save the server. Select it in the server rail, then choose **Connect** on its server screen.
+4. If prompted, enter the server password or account credentials. The app can remember a password in the operating system's credential store.
-When you open Fancy Mumble it shows the **Connect** screen. Three views
-are available from the bottom strip:
+
-- **Servers**, your saved servers (default).
-- **Public**, browse the global directory.
-- **Wizard**, add a new server step by step.
+After saving, the server screen shows the identity and **Connect** action. The example address in these screenshots is illustrative; use the address from your server owner.
+
-
+To find a server instead, choose **Browse public servers** from Quick connect. A server must opt into the public directory to appear there.
-## Quick-add a server
+## Add a server in Standard
-
+Open the **Connect** screen and use the **Wizard** or **+ Add Server** action. Enter the address and username, save, then select the server card to connect. Standard also has a **Public** view for browsing listed servers. Existing profiles that use Standard keep that design.
-1. Tap the **+** button (or **Wizard** at the bottom).
+## Certificate and identity
-2. **Server address**: type the address you were given, for example
- `mumble.example.org` or `mumble.example.org:64738`. If no port is
- given, the default `64738` is used.
+The app remembers a server's TLS certificate after the first connection. If its fingerprint changes later, confirm the change with the server owner before accepting it. The owner may have restored a new data directory or replaced the certificate.
-
- In **Normal mode** the port and label fields are hidden, so you only
- need to enter the address and your name. Turn on **Expert mode**
- under [Privacy & advanced settings](/users/privacy/) if you need
- the extra fields.
-
-
-3. **Your identity**: pick a username. This is the name others will
- see. 3 to 15 characters, letters, numbers, dashes, or underscores
- by default. Some servers allow other patterns.
-
-4. **Give it a name** (Expert only): a friendly label like *Saturday
- D&D*. Leave it blank to use the server address.
-
-5. Click **Save**. The server now appears in your **Servers** list.
-
-
-
-## Connect
-
-Click any saved server card to connect. The status indicator goes
-through these stages:
-
- Idle
-Idle --> Connecting : connect
-Connecting --> Bootstrapping : handshake complete
-Bootstrapping --> Connected : channels & users loaded
-Connected --> [*] : disconnect
-@enduml
-`} />
-
-The progress bar stays up not just during the connection handshake
-but also while channels, users, and your own session are fetched, so
-you do not land on an empty room.
-
-
-
-
-## Password-protected servers
-
-If the server is locked with a password, Fancy Mumble pops up a small
-dialog after the handshake.
-
-
-
-
-Type the password and click **Retry**. The app offers to **remember**
-the password in your operating system's secure storage so you do not
-get asked again.
-
-## Untrusted certificate?
-
-The first time you connect to a server, the app pins the server's
-identity. If that identity later changes (for example, the server was
-reinstalled), the app refuses to connect and shows you the new details.
-
-- If the change is legitimate (the admin told you), click **Accept**.
-- If you did not expect a change, **close the dialog** and ask the
- admin to confirm.
-
-
-Fancy Mumble does not silently accept changed certificates. That is a
-feature, not a bug. It protects you from someone impersonating the
-server.
-
-
-## Browse public servers
-
-The **Public** tab lists servers from the global directory. You can
-filter by **country**, **users online**, and **name**. Click a row to
-connect (no save required).
-
-
-
-
-
-Public servers are not vetted. Treat them like a random group chat,
-do not share private information.
-
-
-## Common connection issues
-
-
-
- The most common cause. Double-check the address. The default port
- is **64738**.
-
-
- Older servers may not understand the newer handshake. Ask the
- admin to update the server.
-
-
- Corporate firewall blocking 64738? Try **Force TCP** under
- [Audio settings](/users/audio/#network).
-
-
- See "Untrusted certificate" above. Do not accept unless the admin
- told you the server was reinstalled.
-
-
-
-If none of these help, see [Connection problems](/troubleshooting/connection/).
+A saved certificate identity matters for registration and some Fancy features. Nebula selects an existing default certificate when you add a server, while an existing saved server keeps the identity you chose. For account or server password problems, see [Connection troubleshooting](/troubleshooting/connection/).
## Next step
-Continue with [Your first voice call](/getting-started/first-call/).
+[Join a channel and make your first call](/getting-started/first-call/).
diff --git a/src/content/docs/getting-started/first-call.mdx b/src/content/docs/getting-started/first-call.mdx
index a99bec7..0b0d754 100644
--- a/src/content/docs/getting-started/first-call.mdx
+++ b/src/content/docs/getting-started/first-call.mdx
@@ -10,6 +10,10 @@ import { Icon } from 'astro-icon/components';
You are connected. Here is how to start **talking**.
+
+The channel click sequence and screenshots below describe Standard. Nebula is the default for new profiles; select a channel and use its Join action to enter voice.
+
+
## 1. Move into a channel
Mumble does not have one big room, channels are explicit. In the left
diff --git a/src/content/docs/getting-started/install.mdx b/src/content/docs/getting-started/install.mdx
index cc9d3ab..cea9a12 100644
--- a/src/content/docs/getting-started/install.mdx
+++ b/src/content/docs/getting-started/install.mdx
@@ -11,8 +11,12 @@ import { Icon } from 'astro-icon/components';
Fancy Mumble runs on Windows, Linux, and Android. Pick your platform
below.
+
+New profiles use the Nebula design shown below. Existing Standard profiles can connect to the same servers.
+
+
-
+
@@ -20,7 +24,7 @@ Pre-built downloads are available in two places:
- The official website at [fancy-mumble.com](https://fancy-mumble.com/),
which is the easiest starting point for most users.
-- The [GitHub releases page](https://github.com/Fancy-Mumble/FancyMumbleNext/releases),
+- The [GitHub releases page](https://github.com/Fancy-Mumble/FancyMumble/releases),
which always has the most recent build (including pre-releases).
Both serve the same installers. Pick the latest stable version.
@@ -36,7 +40,7 @@ Both serve the same installers. Pick the latest stable version.
1. Download the `.exe` or `.msi` installer from
[fancy-mumble.com](https://fancy-mumble.com/) or the
- [GitHub releases page](https://github.com/Fancy-Mumble/FancyMumbleNext/releases).
+ [GitHub releases page](https://github.com/Fancy-Mumble/FancyMumble/releases).
2. Run the installer. Windows SmartScreen may warn you on the
first run. Click **More info** then **Run anyway**.
3. Launch **Fancy Mumble** from the Start menu.
@@ -101,7 +105,7 @@ Both serve the same installers. Pick the latest stable version.
is under **System, Apps, Special access, Install unknown apps**.
2. Download `fancy-mumble-x.y.z.apk` from
[fancy-mumble.com](https://fancy-mumble.com/) or the
- [GitHub releases page](https://github.com/Fancy-Mumble/FancyMumbleNext/releases).
+ [GitHub releases page](https://github.com/Fancy-Mumble/FancyMumble/releases).
3. Tap the file to install.
4. Open the app and continue to [Mobile (Android)](/getting-started/android/).
@@ -110,11 +114,12 @@ Both serve the same installers. Pick the latest stable version.
## Verify the install
-Launch the app. You should see the **Welcome / Connect** screen with a
-list of saved servers (empty on first run) and a **+** button.
+Launch the app. On a new profile, the **Welcome** setup asks for a display
+name, interface mode, and theme. Choose **Get started** to open the server
+list, which is empty until you add a server.
-
+
If you do not see this screen, check
[Common issues](/troubleshooting/common-issues/).
diff --git a/src/content/docs/index.mdx b/src/content/docs/index.mdx
index 95f9df3..872468c 100644
--- a/src/content/docs/index.mdx
+++ b/src/content/docs/index.mdx
@@ -5,7 +5,7 @@ template: splash
hero:
tagline: A modern, feature-rich voice chat for gaming, podcasts, communities, and study groups.
image:
- html: ' '
+ html: ' '
actions:
- text: Get started in 5 minutes
link: /getting-started/install/
@@ -33,7 +33,7 @@ These docs are still being written. Some pages may be incomplete, missing, or no
-
+
@@ -48,15 +48,15 @@ These docs are still being written. Some pages may be incomplete, missing, or no
[View on GitHub →](https://github.com/Fancy-Mumble/FancyMumble)
-
- The self-hosted backend responsible for channel management, authentication, and message routing.
+
+ The current Rust server: a Mumble gateway with separate voice, chat, files, and other services.
- [View on GitHub →](https://github.com/Fancy-Mumble/mumble-server)
+ [View on GitHub →](https://github.com/Fancy-Mumble/starling)
-
- A production-ready container image bundled with an interactive setup wizard for zero-configuration deployment.
+
+ Use the maintained Starling Compose deployment or a release package. The older C++ Docker image remains for existing servers.
- [View on GitHub →](https://github.com/Fancy-Mumble/mumble-docker)
+ [Docker quick start →](/server/docker/)
The source for this site - guides, reference pages, and configuration examples. Contributions welcome.
diff --git a/src/content/docs/reference/config-keys.mdx b/src/content/docs/reference/config-keys.mdx
index 94b97c2..e247f15 100644
--- a/src/content/docs/reference/config-keys.mdx
+++ b/src/content/docs/reference/config-keys.mdx
@@ -1,187 +1,18 @@
---
title: Server config keys
-description: Reference of the documented server settings.
-sidebar:
- order: 3
+description: Where to find the complete Starling TOML schema and common settings.
---
-import { Aside } from '@astrojs/starlight/components';
+Starling validates starling.toml at startup. Use its maintained [reference TOML](https://github.com/Fancy-Mumble/starling/blob/main/examples/reference.toml) for every key, default, and explanation. The shorter [example TOML](https://github.com/Fancy-Mumble/starling/blob/main/starling.example.toml) is the best file to copy for a small server.
-This page lists the documented server-side settings. There are two
-shapes:
+Common keys:
-- **Top-level settings**, set as `MUMBLE_CONFIG_` environment
- variables (or as `=` in a custom INI file).
-- **Plugin settings**, set as `=` in a
- mounted INI file. Only the file-server plugin exposes public keys
- today.
+| TOML location | Use |
+| --- | --- |
+| instances name and port | Server name and Mumble TCP/UDP port. |
+| instances.settings max_users, password, welcome_text | Initial operational settings, also editable at runtime. |
+| services.files listen and public_url | HTTP listener and client-facing file URL. |
+| services.screenshare public_url | Reachable screen-share media endpoint. |
+| services.NAME enabled | Explicitly disable a built-in service. |
-See [Configuration reference](/server/config/) for where these files
-live on disk.
-
-
-This is the public surface that ships with the example
-`mumble-server.ini`. The server has many more upstream Mumble
-settings; for those, see
-[wiki.mumble.info/wiki/Murmur.ini](https://wiki.mumble.info/wiki/Murmur.ini).
-
-
-## Server identity and limits
-
-| Key | Default | Description |
-|-----|---------|-------------|
-| `database` | `/data/mumble-server.sqlite` | Path to the SQLite database. |
-| `port` | `64738` | TCP/UDP port the server listens on. |
-| `host` | empty | Bind address. Empty means "all interfaces". |
-| `welcometext` | empty | HTML welcome message sent on connect. Supports HTML even when `allowhtml` is false. |
-| `serverpassword` | empty | Optional shared password. Registered users bypass this. |
-| `registerName` | empty | Public display name. Required for the public directory. |
-| `users` | `100` | Maximum simultaneous users. |
-| `usersperchannel` | `0` | Per-channel limit. 0 means unlimited. |
-| `bandwidth` | `558000` | Max bits/s per user for audio. Hard ceiling is ~134 400 bit/s. |
-| `textmessagelength` | `500000` | Max characters per text message. 0 = unlimited. |
-| `imagemessagelength` | `1048576` | Max bytes for inline images. 0 = unlimited. |
-| `allowhtml` | `true` | Render HTML in chat and comments. |
-| `defaultchannel` | `0` | Channel ID new users land in. 0 = root channel. Registered users ignore this unless `rememberchannel` is false. |
-| `rememberchannel` | `true` | If true, registered users rejoin the channel they were last in. If false, everyone lands in `defaultchannel`. |
-| `rememberchannelduration` | `0` | How long (in seconds) the server remembers a registered user's last channel. `0` = remember forever. If a user was away longer than this value, they land in `defaultchannel` instead. |
-| `channelnestinglimit` | `10` | Maximum nesting depth for channels. Prevents infinite trees. |
-| `timeout` | `30` | Seconds before an unresponsive client is disconnected. |
-
-## Name constraints
-
-| Key | Default | Description |
-|-----|---------|-------------|
-| `username` | (see below) | Regular expression for allowed username characters. Default pattern (`[ -=\w\[\]\{\}\(\)\@\|\.]+`) allows spaces, letters, digits, and common symbols. |
-| `channelname` | (see below) | Regular expression for allowed channel name characters. Default (`[ -=\w\#\[\]\{\}\(\)\@\|]+`) allows spaces, `#`, and common symbols. Max 512 characters. |
-
-## Client suggestions
-
-These send a recommendation to the client if their setting differs. The client shows a notice; it does not force the change. Set to an empty string (`""`) to disable a suggestion entirely.
-
-| Key | Default | Description |
-|-----|---------|-------------|
-| `suggestversion` | empty | Minimum version string (e.g. `1.4.0`). Clients below this version see a "please update" notice. |
-| `suggestpushtotalk` | empty | Set to `true` to nudge voice-activation users to switch to push-to-talk. |
-| `suggestpositional` | empty | Set to `true` or `false` to recommend a positional audio setting. |
-
-## Discovery
-
-| Key | Default | Description |
-|-----|---------|-------------|
-| `bonjour` | `true` | Advertise the server on the local network via mDNS/Bonjour. The service name comes from `registerName`. |
-| `allowping` | `true` | Allow unauthenticated ping queries that report user count and server info. Required for the public server directory. |
-| `sendversion` | `true` | Include the server OS in the version string sent to clients. |
-
-## Security and bans
-
-| Key | Default | Description |
-|-----|---------|-------------|
-| `certrequired` | `false` | If true, anonymous clients are rejected. |
-| `sslCert` | empty | Path to TLS certificate. Auto-generated if missing. |
-| `sslKey` | empty | Path to TLS private key. |
-| `autobanAttempts` | `0` | Failed connections that trigger an auto-ban. 0 = off. |
-| `autobanTimeframe` | `120` | Window (seconds) for counting attempts. |
-| `autobanTime` | `300` | How long the auto-ban lasts (seconds). |
-| `obfuscate` | `false` | Hash IPs in logs. Good for privacy. |
-
-## Logging
-
-| Key | Default | Description |
-|-----|---------|-------------|
-| `logdays` | `31` | Days of log retention in the database. |
-
-## Persistent chat
-
-| Key | Default | Description |
-|-----|---------|-------------|
-| `pchatenabled` | `true` | Master toggle. |
-| `pchatrequireregistration` | `false` | Only registered users may post. |
-| `pchatdefaultmaxhistory` | `5000` | Messages kept per channel. |
-| `pchatdefaultretentiondays` | `90` | Days messages live. |
-| `pchatmaxpayloadsize` | `1048576` | Max bytes per stored message. |
-| `pchatpendingkeyrequestmaxdays` | `7` | Days before an unfulfilled key request expires. |
-| `pchatpendingfulfilledmaxhours` | `24` | Hours before a fulfilled key request is cleaned up. |
-| `pchatperuserpending` | `5` | Max pending key requests per user. |
-| `pchatperchannelpendingsoftcap` | `100` | Soft cap on pending key requests per channel. |
-
-## Push notifications
-
-| Key | Default | Description |
-|-----|---------|-------------|
-| `pushenabled` | `false` | Master toggle. |
-| `pushmodulepath` | (auto) | Override push library path. |
-| `pushcredentialspath` | `/data/fcm-credentials.json` | Firebase JSON key path. |
-| `pushprojectid` | empty | Firebase project ID. |
-| `pushtopicprefix` | `mumble` | FCM topic prefix. |
-| `pushnotifytextmessage` | `true` | Push on a chat message. |
-| `pushnotifyreaction` | `false` | Push on a reaction. |
-| `pushnotifyuserjoin` | `false` | Push on a user join. |
-
-## Screen-share relay
-
-| Key | Default | Description |
-|-----|---------|-------------|
-| `webrtcsfuenabled` | `false` | Master toggle. |
-| `webrtcsfuport` | `10000` | UDP listen port. |
-| `webrtcsfupublicip` | `127.0.0.1` | IP advertised to viewers. |
-| `webrtcsfumodulepath` | (auto) | Override relay library path. |
-
-## File server
-
-Dot and hyphen separators in plugin key names are stripped when matching
-environment variables, so `plugin.file-server.storagePath` maps to
-`MUMBLE_CONFIG_PLUGIN_FILE_SERVER_STORAGEPATH`.
-
-| Key | Env var suffix | Default | Description |
-|-----|----------------|---------|-------------|
-| `plugin.file-server.enabled` | `PLUGIN_FILE_SERVER_ENABLED` | `true` | Master toggle. |
-| `plugin.file-server.storagePath` | `PLUGIN_FILE_SERVER_STORAGEPATH` | unset | Absolute path to storage directory. Required for the plugin to start. |
-| `plugin.file-server.bindAddress` | `PLUGIN_FILE_SERVER_BINDADDRESS` | `127.0.0.1` | Listen address. Use `0.0.0.0` to expose the port directly. |
-| `plugin.file-server.port` | `PLUGIN_FILE_SERVER_PORT` | `64739` | TCP port. |
-| `plugin.file-server.tlsTerminatedByProxy` | `PLUGIN_FILE_SERVER_TLSTERMINATEDBYPROXY` | `false` | Set to `true` when a reverse proxy handles TLS. |
-| `plugin.file-server.baseUrl` | `PLUGIN_FILE_SERVER_BASEURL` | empty | Public URL clients use. Falls back to `http://host:port` if empty. |
-| `plugin.file-server.allowedOrigins` | `PLUGIN_FILE_SERVER_ALLOWEDORIGINS` | empty | Comma-separated CORS origins. Empty blocks browser usage. |
-
-## Live document editor
-
-The live-doc plugin is configured only via a mounted INI file. These keys
-are **not** mapped to `MUMBLE_CONFIG_*` environment variables.
-
-| Key | Default | Description |
-|-----|---------|-------------|
-| `plugin.live-doc.enabled` | `false` | Master toggle. |
-| `plugin.live-doc.state_path` | - | **Required.** Absolute path to a writable directory. Used to store the JWT signing secret and Yjs room state. |
-| `plugin.live-doc.host` | `0.0.0.0` | WebSocket bind address. |
-| `plugin.live-doc.port` | `64740` | WebSocket TCP port. |
-| `plugin.live-doc.public_url` | empty | Public URL clients use to connect (e.g. `wss://chat.example.com/live-doc`). Falls back to `ws://:` when empty. |
-| `plugin.live-doc.max_update_bytes` | `4194304` | Maximum bytes for a single CRDT update. |
-| `plugin.live-doc.snapshot_idle_secs` | `60` | Idle seconds before flushing a snapshot to the file server. |
-| `plugin.live-doc.teardown_grace_secs` | `30` | Grace seconds after the last viewer disconnects before tearing down the in-memory room. |
-| `plugin.live-doc.file_server_url` | empty | Base URL of the file-server admin endpoint. When unset, documents are never persisted. |
-| `plugin.live-doc.file_server_admin_token` | empty | Shared secret for the file-server admin API. |
-
-## Container-level (not server settings)
-
-These are read by the Docker entrypoint, not the server itself.
-
-| Variable | What |
-|----------|------|
-| `MUMBLE_SUPERUSER_PASSWORD` | SuperUser password. Random and logged on first start if unset. |
-| `MUMBLE_CUSTOM_CONFIG_FILE` | Path to your own INI. Disables `MUMBLE_CONFIG_*`. |
-| `MUMBLE_CHOWN_DATA` | Set to `false` to skip taking ownership of `/data` on boot. |
-| `MUMBLE_ACCEPT_UNKNOWN_SETTINGS` | Pass through unknown `MUMBLE_CONFIG_*` values without failing. |
-| `MUMBLE_VERBOSE` | Verbose server logging. |
-| `PUID` / `PGID` | UID and GID the server process runs as. |
-| `MUMBLE_FCM_CREDENTIALS_BASE64` | Base64-encoded Firebase JSON, decoded into a tmpfs path at boot. |
-
-## What is **not** here
-
-Reactions, polls, link previews, Watch Together, the whiteboard,
-and onboarding have **no public server config keys** today. They are
-either always-on (riding the plugin-data transport between clients)
-or controlled in the client UI. If you want a server-wide off
-switch for any of them, file a feature request on the server repo.
-
-The live-doc plugin does have config keys; they are listed in the
-[Live document editor](#live-document-editor) section above.
+For precedence, includes, reload behavior, and the operator API, read the [configuration guide](https://github.com/Fancy-Mumble/starling/blob/main/docs/CONFIGURATION.md). MUMBLE_CONFIG_*, mumble-server.ini, and plugin.* are legacy C++ server settings; use Starling's migrate-config command when moving an existing deployment.
diff --git a/src/content/docs/reference/ports.mdx b/src/content/docs/reference/ports.mdx
index 6c91776..6ece2a0 100644
--- a/src/content/docs/reference/ports.mdx
+++ b/src/content/docs/reference/ports.mdx
@@ -1,64 +1,15 @@
---
-title: Ports & protocols
-description: Quick reference for every port the client and server use.
-sidebar:
- order: 1
+title: Ports and protocols
+description: Listener reference for the maintained Starling Compose deployment.
---
-import { Aside } from '@astrojs/starlight/components';
+| Port | Protocol | Purpose |
+| --- | --- | --- |
+| 64738 | TCP | Mumble TLS control connection through the gateway; voice can fall back to TCP. |
+| 64738 | UDP | Mumble voice, handled by Starling's voice service. |
+| 8080 | TCP | HTTP uploads and downloads from the files service in the shipped Compose stack. |
+| 8081 | TCP | Optional operator API; the Compose admin profile binds it to localhost. |
-| Port | Protocol | Direction | Purpose | Configurable with |
-|------|----------|-----------|---------|---|
-| **64738** | TCP | client to server | TLS handshake, control messages, chat, TCP fallback for voice | `MUMBLE_CONFIG_PORT` |
-| **64738** | UDP | client to server | Voice and per-channel position data | same |
-| **64739** | TCP | client to server | File server (emotes, attachments) | `plugin.file-server.port` |
-| **64740** | TCP | client to server | Live document WebSocket (Yjs CRDT sync) | `plugin.live-doc.port` |
-| **10000** | UDP | client to server (in both directions) | Screen-share relay (WebRTC SFU) | `MUMBLE_CONFIG_WEBRTCSFUPORT` |
-| **6502** | TCP | localhost only by default | Admin RPC (Ice) | `Ice.Endpoint` in config |
+The first two are needed for a normal public server. The other ports and service listeners depend on the deployment and its TOML. A configured screen-share relay needs a separately reachable UDP media port. Internal gRPC endpoints should remain private. See [Ports and networking](/server/network/) and the [Starling Compose file](https://github.com/Fancy-Mumble/starling/blob/main/docker-compose.yml).
-## Client to server only
-
-The client always initiates the connection. The server never reaches
-back out, except for FCM push (server to Google) and link previews
-(server to the URL the user posted).
-
-## Outbound from the server
-
-For a complete picture:
-
-| Destination | Protocol | When |
-|-------------|----------|------|
-| Public DNS | UDP 53 | Resolving hostnames |
-| `mumble.info` directory | TCP 443 | Public server listing (`registerHostname` set) |
-| Firebase Cloud Messaging | TCP 443 | Push notifications, if enabled |
-| The URLs users paste | TCP 80/443 | Link preview fetches, if enabled |
-
-
-If you self-host on an isolated network, the public-server-directory
-ping fails silently. That is fine; just turn it off with
-`MUMBLE_CONFIG_REGISTERHOSTNAME=""`.
-
-
-## Firewall opening cheat sheet
-
-A self-hosted server typically needs:
-
-```text
-TCP 64738 inbound
-UDP 64738 inbound
-TCP 64739 inbound (if file server)
-TCP 64740 inbound (if live documents)
-UDP 10000 inbound (if screen-share relay)
-TCP 443 outbound (if push or link previews)
-```
-
-## Common pitfalls
-
-- **UDP 64738 is blocked, voice falls back to TCP** with a small
- latency hit. Force TCP under the client's audio settings to make
- this consistent.
-- **UDP 10000 is filtered**: viewers will see a black screen for
- shared streams. Open the port.
-- **Port collision** with another service: change the server's port
- with `MUMBLE_CONFIG_PORT=12345`. Clients then connect to
- `your-host:12345`.
+The older C++ server image uses different optional ports, including 64739 for its file plugin, 64740 for live documents, 10000/UDP for screen sharing, and 6502 for Ice. Those are not Starling defaults.
diff --git a/src/content/docs/server/build.mdx b/src/content/docs/server/build.mdx
index e2a1d45..cd47699 100644
--- a/src/content/docs/server/build.mdx
+++ b/src/content/docs/server/build.mdx
@@ -1,175 +1,21 @@
---
-title: Building from source
-description: Build your own server image, point at a fork, or change CMake flags.
-sidebar:
- order: 6
+title: Build Starling from source
+description: Build the current Rust server or its maintained container image.
---
-import { Steps, Aside, Tabs, TabItem, Code } from '@astrojs/starlight/components';
+Starling is a Rust workspace. Clone its repository and build the server binary:
-Most server owners use the pre-built image. You only need to build
-from source if you:
+~~~sh
+git clone https://github.com/Fancy-Mumble/starling.git
+cd starling
+cargo build --release --bin starling
+cargo run --bin starling -- --all-in-one
+~~~
-- Need a feature not yet shipped.
-- Want to change the compile-time flags (for example, enable extras
- that are off by default in the official image).
-- Are running on an architecture without a pre-built image.
+The repository's Dockerfile and docker-compose.yml build the same server for container deployment:
-## Quick build
+~~~sh
+docker compose up -d --wait --build
+~~~
-
-
-1. Clone the Docker repo:
-
- ```bash
- git clone https://github.com/Fancy-Mumble/mumble-docker
- cd mumble-docker
- ```
-
-2. Build the image:
-
- ```bash
- docker build .
- ```
-
- This pulls the server source from GitHub, compiles it, builds the
- bundled plugin libraries, and produces a runtime image. Takes
- about 10 minutes on a modern machine.
-
-3. Tag it and use it in your compose file:
-
- ```bash
- docker tag my-fancy-mumble:dev
- ```
-
- ```yaml
- services:
- mumble-server:
- image: my-fancy-mumble:dev
- ```
-
-
-
-## Build arguments
-
-| Argument | Default | Purpose |
-|----------|---------|---------|
-| `MUMBLE_GIT_REPO` | `https://github.com/Fancy-Mumble/mumble-server` | Source repository. |
-| `MUMBLE_GIT_BRANCH` | `1.6.x` | Branch to build. |
-| `MUMBLE_VERSION` | `latest` | Tag or commit hash to check out. |
-| `MUMBLE_CMAKE_ARGS` | `-Dwebrtc-sfu=OFF` | Extra CMake flags. |
-| `MUMBLE_BUILD_NUMBER` | empty | Build number embedded in the binary. |
-| `PUID` / `PGID` | `10000` | UID and GID of the `mumble` user in the image. |
-
-### Example, enable the screen-share relay at compile time
-
-The default image **builds the relay library** but does **not enable
-it via CMake** for upstream parity. The pre-built image already
-includes the library; rebuild with the flag if you want it linked in
-by default:
-
-```bash
-docker build \
- --build-arg MUMBLE_CMAKE_ARGS="-Dwebrtc-sfu=ON" \
- .
-```
-
-### Example, build a specific tag
-
-```bash
-docker build \
- --build-arg MUMBLE_VERSION=v1.6.0 \
- .
-```
-
-### Example, build from your own fork
-
-```bash
-docker build \
- --build-arg MUMBLE_GIT_REPO=https://github.com/youruser/mumble \
- --build-arg MUMBLE_GIT_BRANCH=my-feature \
- .
-```
-
-## Different image variants
-
-The repo ships several Dockerfiles for different use cases:
-
-| Dockerfile | Purpose |
-|------------|---------|
-| `Dockerfile` | The default. Produces a small runtime image. |
-| `Dockerfile.debug` | Same but with debug symbols and verbose logging. |
-| `Dockerfile.dev` | Mounts your local source tree for hot rebuilds. |
-| `Dockerfile.vanilla` | Builds the upstream Mumble server (no Fancy features). |
-
-Pick with `-f`:
-
-```bash
-docker build -f Dockerfile.debug .
-```
-
-## Running a different UID/GID
-
-The server runs as UID 10000 by default. To match your host user
-(useful for bind-mounts on a Linux desktop):
-
-```bash
-docker build --build-arg PUID=1000 --build-arg PGID=1000 .
-```
-
-Or pass at runtime (if the container starts as root):
-
-```yaml
-environment:
- PUID: 1000
- PGID: 1000
-```
-
-## Local development with hot rebuilds
-
-The repository has a helper:
-
-```bash
-python -m tools dev-build
-```
-
-This:
-
-1. Picks up your `.env`.
-2. Mounts your local source if `Dockerfile.dev` is used.
-3. Re-runs the build with the cached layers.
-4. Restarts the container.
-
-Useful when you are iterating on a patch you intend to upstream.
-
-## Build issues
-
-- **"Permission denied while trying to connect to the Docker daemon
- socket"**: you are not in the `docker` group.
-- **`apt-get` fails with "not valid yet"**: clock skew in BuildKit.
- The Dockerfiles already pass `-o Acquire::Check-Date=false` to work
- around this, but a manual run might miss it.
-- **CMake cannot find a dependency**: the build image lags upstream.
- Pull `latest` and retry, or pin to a known-good
- `MUMBLE_VERSION`.
-
-## Verifying the build
-
-The freshly built image should start the same way as the official
-one. Look for these log lines:
-
-```text
-mumble-server 1.6.x.
-plugin file-server: loaded
-plugin webrtc-sfu: loaded
-plugin push-fcm: loaded
-plugin link-previews: loaded
-```
-
-If any plugin is missing, the corresponding feature will be
-unavailable. Rebuild with the CMake flag for the missing one.
-
-## Next step
-
-Continue with [Upgrade & backup](/server/upgrade/) to keep your build
-fresh.
+Build again after updating source: Compose otherwise may reuse an older local starling:local image. The [Starling README](https://github.com/Fancy-Mumble/starling) covers the packaged releases, all-in-one mode, distributed services, and Helm deployment.
diff --git a/src/content/docs/server/config.mdx b/src/content/docs/server/config.mdx
index 8cfaf27..7d2b898 100644
--- a/src/content/docs/server/config.mdx
+++ b/src/content/docs/server/config.mdx
@@ -1,253 +1,29 @@
---
-title: Configuration reference
-description: Three ways to configure the server, with examples and gotchas.
-sidebar:
- order: 3
+title: Starling configuration
+description: Configure the current server with a small TOML overlay and live instance settings.
---
-import { Steps, Aside, Tabs, TabItem, Card, CardGrid, Code, FileTree } from '@astrojs/starlight/components';
+Starling reads starling.toml. A file overlays built-in defaults: omitted keys keep their defaults, while unknown keys cause startup to fail. The old MUMBLE_CONFIG_* variables and mumble-server.ini apply to the legacy C++ image, not Starling.
-A Fancy Mumble server can be configured three ways. Pick whichever
-fits your workflow.
+## A small server
-1. **Environment variables** (`MUMBLE_CONFIG_*`). Best for Docker
- compose, Kubernetes, and quick deployments.
-2. **A mounted INI file**. Best for fine-grained control and version-
- tracked configurations.
-3. **Docker secrets**. Best for production password and credential
- handling.
+~~~toml
+[[instances]]
+name = "Frog Pond"
+port = 64738
-## Where the config files live
+[instances.settings]
+max_users = 20
+password = ""
+welcome_text = "Welcome!"
+~~~
-A typical project directory looks like this:
+On a first local all-in-one run without a config argument, Starling writes a starter configuration in its platform configuration directory. In Docker Compose, edit deploy/starling.toml, which is mounted into every service. For a custom all-in-one deployment, copy [starling.example.toml](https://github.com/Fancy-Mumble/starling/blob/main/starling.example.toml).
-
-- my-mumble-server/
- - docker-compose.yml how to run the container; env-vars live here
- - .env optional: secrets pulled into docker-compose
- - mumble-server.ini optional: full INI mounted into the container
-
+Settings under the instances.settings table, such as max_users, password, and welcome_text, can also be changed from the admin UI. A value changed at runtime takes precedence over its starting value in TOML. Deployment settings such as endpoints and TLS paths stay in TOML.
-- `docker-compose.yml` is the **one file you always create**, on your
- host machine (anywhere you like, then `cd` into it to run
- `docker compose up`).
-- Inside the running container, the live config the server actually
- reads is generated at `/data/mumble_server_config.ini` on every
- boot. **Do not** edit that file in place. It is regenerated from
- the environment variables each restart.
-- `mumble-server.ini` is **only needed if you set `plugin.*` keys**
- (for example for the file server). Mount it into the container as
- shown in section 2 below.
+## Services and feature settings
-## 1. Environment variables
+Services use services.NAME tables. To turn a built-in service off, set enabled = false; leaving a table out keeps its default. The operator API is an exception: it is absent until explicitly configured. Files use the services.files table with an HTTP listen address and a client-reachable public_url. Screen-share relay needs a reachable media address. See the [configuration guide](https://github.com/Fancy-Mumble/starling/blob/main/docs/CONFIGURATION.md) and [reference TOML](https://github.com/Fancy-Mumble/starling/blob/main/examples/reference.toml) for the full schema.
-Every server option can be set with an environment variable named
-`MUMBLE_CONFIG_`. The option name is case insensitive and
-underscores are ignored, so all three of these set the database host:
-
-```text
-MUMBLE_CONFIG_dbhost
-MUMBLE_CONFIG_DBHOST
-MUMBLE_CONFIG_DB_HOST
-```
-
-Example, in `docker-compose.yml`:
-
-
-
-Or directly with docker:
-
-```bash
-docker run -e "MUMBLE_CONFIG_USERS=200" \
- -e "MUMBLE_CONFIG_SERVER_PASSWORD=secret" \
- ...
-```
-
-A full alphabetical list of every supported key is on the
-[Server config keys](/reference/config-keys/) page.
-
-## 2. Mounted INI file
-
-Mount your own `mumble-server.ini` when you prefer version-tracked
-configuration files over environment variables:
-
-
-
-
-When `MUMBLE_CUSTOM_CONFIG_FILE` is set, **all `MUMBLE_CONFIG_*`
-variables are ignored**. Pick one or the other, not both.
-
-
-A documented template ships in the repo at `mumble-server.ini.example`.
-Copy it to `mumble-server.ini` and edit to taste.
-
-## 3. Docker secrets
-
-For production, store passwords and credentials as **secrets**
-instead of environment variables (which are visible in `docker
-inspect`):
-
-```bash
-echo -n "supersecret" | docker secret create MUMBLE_CONFIG_SERVER_PASSWORD -
-echo -n "adminpass" | docker secret create MUMBLE_SUPERUSER_PASSWORD -
-```
-
-Then reference them in compose:
-
-
-
-The entrypoint reads `/run/secrets/MUMBLE_CONFIG_*` files at boot.
-
-## Common configurations
-
-
-
- ```yaml
- environment:
- MUMBLE_CONFIG_USERS: 100
- MUMBLE_CONFIG_WELCOMETEXT: "Public Fancy Mumble server. Be nice."
- MUMBLE_CONFIG_REGISTERNAME: "My Public Server"
- MUMBLE_CONFIG_REGISTERURL: "https://my-server.example.com"
- MUMBLE_CONFIG_REGISTERHOSTNAME: "my-server.example.com"
- MUMBLE_CONFIG_BANDWIDTH: 558000
- # Persistent chat
- MUMBLE_CONFIG_PCHATENABLED: true
- MUMBLE_CONFIG_PCHATDEFAULTMAXHISTORY: 5000
- MUMBLE_CONFIG_PCHATDEFAULTRETENTIONDAYS: 90
- # File server (emotes, avatars, attachments)
- MUMBLE_CONFIG_PLUGIN_FILE_SERVER_ENABLED: true
- MUMBLE_CONFIG_PLUGIN_FILE_SERVER_STORAGEPATH: /data/file-server-storage
- MUMBLE_CONFIG_PLUGIN_FILE_SERVER_BINDADDRESS: "0.0.0.0"
- MUMBLE_CONFIG_PLUGIN_FILE_SERVER_PORT: 64739
- MUMBLE_CONFIG_PLUGIN_FILE_SERVER_TLSTERMINATEDBYPROXY: true
- # Screen-share relay - set the public IP of your server
- MUMBLE_CONFIG_WEBRTCSFUENABLED: true
- MUMBLE_CONFIG_WEBRTCSFUPORT: 10000
- MUMBLE_CONFIG_WEBRTCSFUPUBLICIP: "1.2.3.4"
- ```
-
-
- ```yaml
- environment:
- MUMBLE_CONFIG_USERS: 20
- MUMBLE_CONFIG_SERVER_PASSWORD: "share-with-friends"
- MUMBLE_CONFIG_CERTREQUIRED: false
- MUMBLE_CONFIG_ALLOWPING: false
- # Persistent chat
- MUMBLE_CONFIG_PCHATENABLED: true
- MUMBLE_CONFIG_PCHATREQUIREREGISTRATION: false
- MUMBLE_CONFIG_PCHATDEFAULTMAXHISTORY: 2000
- MUMBLE_CONFIG_PCHATDEFAULTRETENTIONDAYS: 365
- # File server (emotes, avatars, attachments)
- MUMBLE_CONFIG_PLUGIN_FILE_SERVER_ENABLED: true
- MUMBLE_CONFIG_PLUGIN_FILE_SERVER_STORAGEPATH: /data/file-server-storage
- MUMBLE_CONFIG_PLUGIN_FILE_SERVER_BINDADDRESS: "0.0.0.0"
- MUMBLE_CONFIG_PLUGIN_FILE_SERVER_PORT: 64739
- MUMBLE_CONFIG_PLUGIN_FILE_SERVER_TLSTERMINATEDBYPROXY: true
- # Screen-share relay - set the public IP of your server
- MUMBLE_CONFIG_WEBRTCSFUENABLED: true
- MUMBLE_CONFIG_WEBRTCSFUPORT: 10000
- MUMBLE_CONFIG_WEBRTCSFUPUBLICIP: "1.2.3.4"
- ```
-
-
- ```yaml
- environment:
- MUMBLE_CONFIG_USERS: 50
- MUMBLE_CONFIG_CERTREQUIRED: true
- MUMBLE_CONFIG_AUTOBANATTEMPTS: 5
- MUMBLE_CONFIG_AUTOBANTIMEFRAME: 60
- MUMBLE_CONFIG_AUTOBANTIME: 3600
- MUMBLE_CONFIG_SENDVERSION: false
- MUMBLE_CONFIG_OBFUSCATE: true
- # Persistent chat - require registration to use it
- MUMBLE_CONFIG_PCHATENABLED: true
- MUMBLE_CONFIG_PCHATREQUIREREGISTRATION: true
- # File server - disabled; no binary uploads on a hardened server
- MUMBLE_CONFIG_PLUGIN_FILE_SERVER_ENABLED: false
- # Screen-share relay - disabled; direct P2P only
- MUMBLE_CONFIG_WEBRTCSFUENABLED: false
- # Push notifications - disabled
- MUMBLE_CONFIG_PUSHENABLED: false
- ```
-
-
-
-## Pitfalls
-
-- **Unknown setting**: by default the server refuses to start if a
- `MUMBLE_CONFIG_*` variable does not match a known option. Set
- `MUMBLE_ACCEPT_UNKNOWN_SETTINGS=true` to pass-through unknown
- values (useful for testing new options).
-- **String values with special characters**: must be quoted in YAML.
- See the regex example above.
-- **Booleans**: lowercase `true`/`false`. Not `True`, not `yes`.
-- **Numeric values**: bare numbers in YAML, quoted in `.env`.
-- **`plugin.*` env var names**: dots and hyphens are stripped when
- matching, so `plugin.file-server.storagePath` maps to
- `MUMBLE_CONFIG_PLUGIN_FILE_SERVER_STORAGEPATH`. See the
- [config keys reference](/reference/config-keys/) for the full table.
-
-## Other environment variables
-
-These are not server settings, they are container-level:
-
-| Variable | Description |
-|----------|-------------|
-| `MUMBLE_SUPERUSER_PASSWORD` | SuperUser password. A random one is logged on the first start if unset. |
-| `MUMBLE_CUSTOM_CONFIG_FILE` | Path to your own INI. Disables `MUMBLE_CONFIG_*`. |
-| `MUMBLE_CHOWN_DATA` | Set to `false` to skip taking ownership of `/data` on boot. |
-| `MUMBLE_ACCEPT_UNKNOWN_SETTINGS` | Pass through unknown options without failing. |
-| `MUMBLE_VERBOSE` | Verbose server logging. |
-| `PUID` / `PGID` | The UID and GID the server process runs as. |
-
-## Hot reload?
-
-Most settings only take effect on **server restart**. A few (welcome
-text, server password) reload when you save the config from the
-admin UI. To restart the container:
-
-```bash
-docker compose restart mumble-server
-```
-
-## Next steps
-
-
-
- See [Ports & networking](/server/network/) for what is exposed
- and why.
-
-
- See [Customize & disable features](/server/customize/) to slim
- the server down.
-
-
- Browse every supported `MUMBLE_CONFIG_*` key on the
- [Server config keys](/reference/config-keys/) page.
-
-
+Starling can reload supported settings on SIGHUP. Listener changes can require a restart; check the reload log for applied, next_connection, and pending_restart. For an existing C++ server, use the Starling migrate-config command to produce a starting TOML overlay, then review it before starting Starling.
diff --git a/src/content/docs/server/customize.mdx b/src/content/docs/server/customize.mdx
index 5deac91..83407e5 100644
--- a/src/content/docs/server/customize.mdx
+++ b/src/content/docs/server/customize.mdx
@@ -1,130 +1,24 @@
---
-title: Customize & disable features
-description: Trim the server to your community's needs. Turn off features you do not use, restrict who can use what.
-sidebar:
- order: 5
+title: Customize server features
+description: Control Starling services and per-instance settings.
---
-import { Steps, Aside, Tabs, TabItem, Card, CardGrid } from '@astrojs/starlight/components';
+Starling's starling.toml is an overlay on built-in defaults. Put ordinary server settings under instances.settings and service settings under services.NAME. For example:
-Fancy Mumble ships with everything on by default. That is friendly
-for first-time setups, but you may want to disable features for
-performance, privacy, or simplicity.
+~~~toml
+[[instances]]
+name = "My Community"
+port = 64738
-This page is the **master toggle reference**. Each row points to the
-detailed page.
+[instances.settings]
+max_users = 100
+password = ""
+allow_recording = true
-
-The `MUMBLE_CONFIG_*` block lives in the `environment:` section of
-your `docker-compose.yml` (next to where you started the server).
-The `plugin.*` block lives in a mounted INI file (typically
-`./mumble-server.ini` on your host). See
-[Configuration reference](/server/config/) for the file layout.
-
+[services.push]
+enabled = false
+~~~
-## Master toggles
+Omitting a service table keeps its built-in default. To switch a service off, set enabled = false. The operator API is disabled unless explicitly configured. Per-channel access is managed through ACLs in the client; for example, file sharing requires the corresponding share permission in that channel.
-In `docker-compose.yml`:
-
-```yaml
-environment:
- # Voice and registration
- MUMBLE_CONFIG_USERS: 100
- MUMBLE_CONFIG_CERTREQUIRED: false
- MUMBLE_CONFIG_REGISTERHOSTNAME: "my-server.example.com"
-
- # Persistent chat
- MUMBLE_CONFIG_PCHATENABLED: true
-
- # Push notifications
- MUMBLE_CONFIG_PUSHENABLED: false
-
- # Screen-share relay
- MUMBLE_CONFIG_WEBRTCSFUENABLED: true
- MUMBLE_CONFIG_WEBRTCSFUPUBLICIP: "203.0.113.5"
-```
-
-In your mounted INI file (only the file server has user-facing
-plugin keys today):
-
-```ini
-plugin.file-server.enabled=true
-plugin.file-server.storagePath=/data/file-server-storage
-plugin.file-server.port=64739
-```
-
-
-Link previews, reactions, polls, Watch Together, the whiteboard,
-and onboarding **do not have public `plugin.*` configuration keys**
-in the current server. They are either always on (and ride the
-existing plugin-data transport between clients) or controlled in
-the client UI. To disable any of them server-wide you would need to
-build a custom server image without the relevant plugin compiled
-in.
-
-
-## What you can actually toggle today
-
-The list of features that have a public server-side on/off switch is
-small. The bullets below are the keys that exist in
-`mumble-server.ini.example`:
-
-| Feature | Toggle | Default |
-|---------|--------|:-------:|
-| Persistent chat | `pchatenabled` | on |
-| Push notifications (FCM) | `pushenabled` | off |
-| Screen-share relay | `webrtcsfuenabled` | off |
-| File server | `plugin.file-server.enabled` | on |
-
-Everything else (reactions, polls, link previews, Watch Together,
-whiteboard, onboarding) is either hard-wired on in the server build
-or is a client-side feature. To disable any of those server-wide you
-would need to build a custom server image.
-
-## Restricting features per role and channel
-
-What you **can** control is **who is allowed to use** a given feature,
-via roles and channel ACLs. See:
-
-- [Roles & permissions](/admin/roles/) for server-wide bundles.
-- [Channel ACL](/admin/acl/) for per-channel overrides.
-
-The exact set of permission flags depends on your server version.
-Open **Admin, Roles**, click **New role**, then look at the
-**Permissions** tab to see the list your server actually exposes.
-
-## "Maintenance mode"
-
-If you need to take the server temporarily out of public use:
-
-```yaml
-environment:
- MUMBLE_CONFIG_SERVER_PASSWORD: "maintenance"
- MUMBLE_CONFIG_WELCOMETEXT: "Server in maintenance. Back at 18:00 UTC."
-```
-
-Existing users stay connected, new users need the password.
-
-## Pause incoming registrations
-
-```yaml
-environment:
- MUMBLE_CONFIG_ALLOWREGISTRATION: false
-```
-
-Existing registered users keep their accounts.
-
-## Read-only channels
-
-Per channel:
-
-1. Admin, Channels, **Edit**.
-2. ACL tab.
-3. Add a rule that denies `Speak` and `Write` to `@everyone` and
- allows it for a specific role.
-4. Save.
-
-## Next step
-
-Continue with [Building from source](/server/build/) if you want to
-customize the image itself.
+Check the [Starling configuration guide](https://github.com/Fancy-Mumble/starling/blob/main/docs/CONFIGURATION.md) and [reference TOML](https://github.com/Fancy-Mumble/starling/blob/main/examples/reference.toml) for exact keys and defaults. Old MUMBLE_CONFIG_* and plugin.* INI examples refer to the C++ server and cannot be copied into Starling TOML.
diff --git a/src/content/docs/server/docker.mdx b/src/content/docs/server/docker.mdx
index aed5da4..e7c75a0 100644
--- a/src/content/docs/server/docker.mdx
+++ b/src/content/docs/server/docker.mdx
@@ -1,323 +1,43 @@
---
-title: Docker quick start
-description: Spin up a fully featured Fancy Mumble server with Docker in under 5 minutes.
-sidebar:
- order: 1
+title: Run Starling with Docker
+description: Start the current Fancy Mumble server using Starling's maintained Compose deployment.
---
-import { Steps, Aside, Tabs, TabItem, Card, CardGrid } from '@astrojs/starlight/components';
-import { Icon } from 'astro-icon/components';
+Starling is the current Fancy Mumble server. Its repository contains the Compose file and the matching configuration file. The older mumble-docker image runs the C++ server fork and is retained for existing deployments.
-The fastest path to a working server is the official Docker image. It
-bundles the Fancy Mumble server plus all of the extras (persistent
-chat, file server, screen-share relay, push notifications) into one
-ready-to-run package.
+## Start a server
-You will need:
+~~~sh
+git clone https://github.com/Fancy-Mumble/starling.git
+cd starling
+STARLING_IMAGE=ghcr.io/fancy-mumble/starling:latest docker compose up -d --wait
+docker compose logs gateway
+~~~
-- Docker (or Podman) installed.
-- A machine with a public IP, or port forwarding on your home router.
-- About five minutes.
+On Windows PowerShell, set the image with `$env:STARLING_IMAGE='ghcr.io/fancy-mumble/starling:latest'` before running `docker compose up -d --wait`.
+Connect Fancy Mumble to localhost:64738. On first boot Starling creates a self-signed server certificate and a SuperUser password. In the distributed stack, find the password in `docker compose logs userdata`; in the all-in-one service, check `docker compose logs starling`. Save it. Keep the starling-data volume: it holds the certificate, accounts, channels, and service data.
-
+To build from source, use:
-## Option A: the interactive setup wizard (recommended)
+~~~sh
+docker compose up -d --wait --build
+~~~
-The setup wizard walks you through every option and writes a ready-to-use
-`.env` and `mumble-server.ini` for you. See [Setup wizard](/server/wizard/)
-to get started - it produces the same result as the manual steps below but
-explains each choice along the way.
+The Compose file also supports a single-container deployment with the starling service. Start that service by name; it replaces the distributed services.
-## Option B: docker compose with environment variables
+## Configure and operate
-The quickest manual option. The server derives its configuration from
-`MUMBLE_CONFIG_*` environment variables at startup, including all
-Fancy Mumble features. Use Option C instead if you prefer a
-version-tracked config file.
+Edit deploy/starling.toml before starting the distributed stack. The file is mounted into every service. Set an instance name and password under the instances tables. For a single process, start with starling.example.toml instead. See [Configuration](/server/config/).
-
+The Compose deployment publishes TCP and UDP port 64738 and HTTP port 8080 for files. Its sample public URL is localhost:8080; set a URL that other users can reach before sharing files outside your machine. See [Ports and networking](/server/network/).
-1. Create a new folder and put a `docker-compose.yml` inside it:
+~~~sh
+docker compose ps
+docker compose logs -f gateway
+docker compose down
+~~~
- ```yaml
- # docker-compose.yml
- services:
- mumble-server:
- image: ghcr.io/fancy-mumble/mumble-server:latest
- container_name: mumble-server
- hostname: mumble-server
- restart: on-failure
- ports:
- - "64738:64738/tcp" # voice and control
- - "64738:64738/udp"
- - "64739:64739/tcp" # file server (emotes, attachments)
- - "10000:10000/udp" # screen-share relay
- volumes:
- - mumble-data:/data
- environment:
- MUMBLE_SUPERUSER_PASSWORD: "changeme"
- MUMBLE_CONFIG_WELCOMETEXT: "Welcome to our server."
- MUMBLE_CONFIG_USERS: 100
- MUMBLE_CONFIG_REGISTERNAME: "My Fancy Server"
+Docker Compose down keeps the data volume. Adding -v deletes it, including the server certificate and database. See [Upgrade and backup](/server/upgrade/).
- volumes:
- mumble-data:
- ```
-
-2. Start the server:
-
- ```bash
- docker compose up -d
- ```
-
-3. Check the logs to confirm it booted:
-
- ```bash
- docker compose logs -f mumble-server
- ```
-
- You should see lines like `Server listening on :::64738`. Press
- `Ctrl+C` to exit the log tail (the container keeps running).
-
-4. Note the SuperUser password you set. If you left it as `changeme`, change it now:
-
- ```bash
- docker exec mumble-server mumble-server \
- --ini /data/mumble_server_config.ini \
- --set-su-pw "your-strong-password"
- ```
-
-5. Open Fancy Mumble on your client machine and connect to
- `your-host:64738`. See [Connect to a server](/getting-started/connect/).
-
-
-
-## Option C: docker compose with a custom config file
-
-Use this when you want to enable Fancy Mumble features like persistent
-chat, the file server, or the screen-share relay. A `mumble-server.ini`
-is mounted directly into the container; all `MUMBLE_CONFIG_*` environment
-variables are ignored once `MUMBLE_CUSTOM_CONFIG_FILE` is set.
-
-
-
-1. Create a new folder and put these two files inside it:
-
- ```yaml
- # docker-compose.yml
- services:
- mumble-server:
- image: ghcr.io/fancy-mumble/mumble-server:latest
- container_name: mumble-server
- hostname: mumble-server
- restart: on-failure
- ports:
- - "64738:64738/tcp" # voice and control
- - "64738:64738/udp"
- - "64739:64739/tcp" # file server (emotes, attachments)
- - "10000:10000/udp" # screen-share relay
- volumes:
- - ./mumble-server.ini:/data/mumble-server.ini:ro
- - mumble-data:/data
- environment:
- MUMBLE_SUPERUSER_PASSWORD: "changeme"
- MUMBLE_CUSTOM_CONFIG_FILE: /data/mumble-server.ini
-
- volumes:
- mumble-data:
- ```
-
- ```ini
- # mumble-server.ini
- database=/data/mumble-server.sqlite
- port=64738
- users=100
- bandwidth=558000
- textmessagelength=500000
- imagemessagelength=1048576
- allowhtml=true
-
- ; Persistent chat
- pchatenabled=true
-
- ; File server (emotes, avatars, attachments)
- plugin.file-server.enabled=true
- plugin.file-server.storagePath=/data/file-server-storage
- plugin.file-server.bindAddress=0.0.0.0
- plugin.file-server.port=64739
- ; Set to true only when a reverse proxy (nginx, Caddy, Traefik, etc.) terminates TLS
- ; in front of this port. Leave false (or remove) for direct HTTPS/plain connections.
- plugin.file-server.tlsTerminatedByProxy=true
-
- ; WebRTC SFU (screen-share relay)
- ; Change webrtcsfupublicip to your server's public IP before enabling.
- webrtcsfuenabled=false
- webrtcsfuport=10000
- webrtcsfupublicip=127.0.0.1
-
- ; Push notifications
- ; Requires a Firebase project and credentials file. Leave disabled unless
- ; you have completed the FCM setup (see Push notifications).
- pushenabled=false
- pushcredentialspath=/data/fcm-credentials.json
- pushtopicprefix=mumble
-
- [Ice]
- Ice.Warn.UnknownProperties=1
- Ice.MessageSizeMax=65536
- ```
-
- Edit `mumble-server.ini` to match your deployment. The file is
- mounted read-only; restart the container after any change.
-
-2. Start the server:
-
- ```bash
- docker compose up -d
- ```
-
-3. Check the logs to confirm it booted:
-
- ```bash
- docker compose logs -f mumble-server
- ```
-
- You should see lines like `Server listening on :::64738`. Press
- `Ctrl+C` to exit the log tail (the container keeps running).
-
-4. Note the SuperUser password you set. If you left it as `changeme`, change it now:
-
- ```bash
- docker exec mumble-server mumble-server \
- --ini /data/mumble-server.ini \
- --set-su-pw "your-strong-password"
- ```
-
-5. Open Fancy Mumble on your client machine and connect to
- `your-host:64738`. See [Connect to a server](/getting-started/connect/).
-
-
-
-## Option D: plain docker
-
-If you do not use compose:
-
-```bash
-docker run --detach \
- --name mumble-server \
- --publish 64738:64738/tcp \
- --publish 64738:64738/udp \
- --publish 64739:64739/tcp \
- --publish 10000:10000/udp \
- --volume mumble-data:/data \
- --restart on-failure \
- --env MUMBLE_SUPERUSER_PASSWORD=changeme \
- ghcr.io/fancy-mumble/mumble-server:latest
-```
-
-## Verify everything is working
-
-
-
- Connect with the app and join a channel. Speak. Your speaking
- indicator should light up.
-
-
- Send a message, disconnect, reconnect. The message should still
- be there.
-
-
- Try uploading your avatar from **Settings, Profile**. It should
- persist across reconnects.
-
-
- Only applicable if you enabled the WebRTC SFU (off by default - see
- [Screen sharing relay](/server/features/webrtc-sfu/)). Once enabled,
- start a screen share and a second person should see it without any extra setup.
-
-
-
-## What just happened?
-
-The image you ran bundles a few pieces:
-
-- The **Fancy Mumble server** binary.
-- A **file server** for emotes, avatars, and file uploads (port 64739).
-- A **screen-share relay** (port 10000, off by default).
-- A **push notification module** (off by default).
-- An entrypoint script that:
- - Translates your `MUMBLE_CONFIG_*` environment variables into a
- config file at boot (Options B and D), or reads a mounted
- `mumble-server.ini` directly (Option C).
- - Reads passwords from Docker secrets if mounted.
- - Sets file ownership for the data volume.
- - Runs the server in the foreground.
-
-## Common first-run problems
-
-- **`permission denied` connecting to `/var/run/docker.sock`**: your user
- is not in the `docker` group. Run `sudo usermod -aG docker $USER` then
- either log out and back in, or run `newgrp docker` to apply immediately.
- On Windows, make sure Docker Desktop is running before invoking any
- `docker` command.
-- **`error getting credentials … exec format error`**: the Docker credential
- helper configured in `~/.docker/config.json` is a Windows binary that
- cannot run inside WSL. The image is public, so no credentials are needed.
- Reset the config with `echo '{}' > ~/.docker/config.json` and retry.
-- **`Failed to set initial capabilities` and friends in the logs**: at first
- startup the entrypoint runs the server binary briefly as root to set the
- SuperUser password, which emits a cluster of warnings:
- ```text
- Failed to set initial capabilities
- WARNING: You are running murmurd as root, without setting a uname in the ini file.
- resource_limits {current: 0, max: 0}
- Failed to set priority limits.
- Failed to set final capabilities
- ```
- All of these come from `UnixMurmur::initialcap()` / `finalcap()` which
- expect Linux capabilities Docker drops by default. They are **harmless**
- and only appear during the password-setting step. The actual long-running
- server runs unprivileged as UID/GID 10000 via `su-exec` and does not emit
- them. Do **not** set `uname` / `MUMBLE_CONFIG_UNAME` in a Docker
- deployment - the named OS user does not exist in the image and the server
- will exit with `Cannot find username`.
-- **Cannot connect from outside the network**: forward port `64738/tcp`
- and `64738/udp` on your router. The screen-share relay also needs
- `10000/udp` to be reachable.
-- **Server starts then exits**: check the logs. The most common cause
- is a typo in a `MUMBLE_CONFIG_*` value. The strict mode rejects
- unknown keys.
-- **SuperUser cannot log in**: the password is set per-database. If
- you started the container before setting one, set it with the
- `--set-su-pw` command shown above, then restart.
-- **Voice connects but is one-way**: UDP `64738` is blocked. Voice
- falls back to TCP, but viewers may need to force TCP too. Better:
- open UDP.
-- **Logs show `plugin on_load failed` for `fancy-file-server`**: this is
- expected when using Option B (environment variables) without configuring
- a file server storage path. The server continues to run normally; voice,
- chat, and all other features are unaffected. To enable the file server,
- switch to Option C and set `plugin.file-server.storagePath` in your
- `mumble-server.ini`.
-
-## Next steps
-
-
-
- See [SuperUser & first login](/admin/superuser/) to take control
- of your fresh server.
-
-
- See [Configuration reference](/server/config/) for every available
- option.
-
-
- Persistent chat, push, screen-share relay, file server, emotes,
- onboarding. All under **Feature deep-dives** in the sidebar.
-
-
- `docker compose down -v` removes the container and its data
- volume. Without `-v` the data survives.
-
-
+For current Compose options, see the [Starling README](https://github.com/Fancy-Mumble/starling#install) and [Compose file](https://github.com/Fancy-Mumble/starling/blob/main/docker-compose.yml).
diff --git a/src/content/docs/server/features/file-server.mdx b/src/content/docs/server/features/file-server.mdx
index b63fbce..e4ca4a9 100644
--- a/src/content/docs/server/features/file-server.mdx
+++ b/src/content/docs/server/features/file-server.mdx
@@ -9,6 +9,10 @@ import { Steps, Aside, Tabs, TabItem, Card, CardGrid, FileTree } from '@astrojs/
import PlantUML from '../../../../components/PlantUML.astro';
import { MUMBLE_DOCKER_BRANCH } from '../../../../lib/github';
+:::caution[Legacy C++ server instructions]
+This page documents the older mumble-server fork. Its INI keys, plugin paths, and ports do not configure Starling. For a new deployment, start with [Starling feature availability](/server/features/) and the [Starling configuration guide](/server/config/).
+:::
+
The file server is the part of Fancy Mumble that handles:
- **Custom server emote** images.
diff --git a/src/content/docs/server/features/index.mdx b/src/content/docs/server/features/index.mdx
new file mode 100644
index 0000000..9ffd07c
--- /dev/null
+++ b/src/content/docs/server/features/index.mdx
@@ -0,0 +1,23 @@
+---
+title: Feature availability on Starling
+description: What runs as a Starling service, what needs configuration, and what depends on plugins.
+---
+
+Starling is the current server. Its gateway routes client control traffic to separate services; voice, files, and screen-share media use their own network paths. The [Starling services guide](https://github.com/Fancy-Mumble/starling/blob/main/docs/SERVICES.md) is the maintained service inventory.
+
+| Feature | Starling component | Additional setup |
+| --- | --- | --- |
+| Voice and channel administration | Gateway, voice, metadata, permissions, userdata | Open TCP and UDP on the Mumble port. |
+| Persistent chat | pchat | Configure channel policy and retention as needed. |
+| Reactions, polls, typing, read receipts, and watch-together signals | social | Included in the default stack; keep the service healthy for these live channel features. |
+| File sharing | files | Set a client-reachable HTTP public URL and grant channel share permissions. |
+| Screen sharing | screenshare | Set a reachable UDP relay address when using server relay. |
+| Push notifications | push | Configure provider credentials for the target platform. |
+| Link previews | link-preview | Check outbound network policy. |
+| Plugins and plugin-delivered features | plugins plus installed plugins | Check the plugin host and the particular plugin; availability is not implied by the service alone. |
+| Live documents and calendar | Plugin-dependent | The checked-out Starling porting plan still lists these plugins as pending migration. Do not assume they work in a fresh deployment. |
+| External administration | operator-api | Explicitly configure authentication and the admin profile. |
+
+Some client features also depend on a plugin, server capability, or a newer client build. If a control is absent after connecting, check the server's advertised capabilities and its logs. The older feature and plugin guides remain available for existing C++ deployments; their INI keys and ports are not Starling configuration recipes.
+
+For the current plugin-host implementation and remaining migration work, see the [Starling plugin-host plan](https://github.com/Fancy-Mumble/starling/blob/main/docs/PLUGIN-HOST-PLAN.md). For each feature's exact settings, use the [Starling TOML reference](https://github.com/Fancy-Mumble/starling/blob/main/examples/reference.toml).
diff --git a/src/content/docs/server/features/link-previews.mdx b/src/content/docs/server/features/link-previews.mdx
index 58208a8..99fb0f3 100644
--- a/src/content/docs/server/features/link-previews.mdx
+++ b/src/content/docs/server/features/link-previews.mdx
@@ -7,6 +7,10 @@ sidebar:
import { Aside, Card, CardGrid } from '@astrojs/starlight/components';
+:::caution[Legacy C++ server instructions]
+This page documents the older mumble-server fork. Its INI keys, plugin paths, and ports do not configure Starling. For a new deployment, start with [Starling feature availability](/server/features/) and the [Starling configuration guide](/server/config/).
+:::
+
When a user pastes a URL in chat, the server can fetch the page, pull
out the Open Graph tags, and send a preview card back. Other Fancy
Mumble clients render the card inline.
diff --git a/src/content/docs/server/features/live-doc.mdx b/src/content/docs/server/features/live-doc.mdx
index a052613..e61a526 100644
--- a/src/content/docs/server/features/live-doc.mdx
+++ b/src/content/docs/server/features/live-doc.mdx
@@ -8,6 +8,10 @@ sidebar:
import { Steps, Aside, Tabs, TabItem, Card, CardGrid, Code } from '@astrojs/starlight/components';
import PlantUML from '../../../../components/PlantUML.astro';
+:::caution[Legacy C++ server instructions]
+This page documents the older mumble-server fork. Its INI keys, plugin paths, and ports do not configure Starling. For a new deployment, start with [Starling feature availability](/server/features/) and the [Starling configuration guide](/server/config/).
+:::
+
The **live-doc plugin** lets every member of a channel co-edit a single
shared document in real time. Documents support rich formatting,
images with float modes, tables, math (LaTeX), code blocks, and
diff --git a/src/content/docs/server/features/persistent-chat.mdx b/src/content/docs/server/features/persistent-chat.mdx
index 4e35dbb..8ab1f23 100644
--- a/src/content/docs/server/features/persistent-chat.mdx
+++ b/src/content/docs/server/features/persistent-chat.mdx
@@ -7,6 +7,10 @@ sidebar:
import { Steps, Aside, Tabs, TabItem, Card, CardGrid, Badge } from '@astrojs/starlight/components';
+:::caution[Legacy C++ server instructions]
+This page documents the older mumble-server fork. Its INI keys, plugin paths, and ports do not configure Starling. For a new deployment, start with [Starling feature availability](/server/features/) and the [Starling configuration guide](/server/config/).
+:::
+
Persistent chat means **messages survive a disconnect**. Without it, a
Mumble server forgets everything as soon as a user leaves, just like
a phone call.
@@ -146,7 +150,7 @@ Until a full audit is completed, treat Full Archive as **transport encryption on
via [signalapp/libsignal](https://github.com/signalapp/libsignal).
- Because libsignal is **AGPL-3.0**, Fancy Mumble ships it as a
separate shared library - `signal-bridge` - built from
- [`crates/signal-bridge`](https://github.com/Fancy-Mumble/FancyMumbleNext/tree/master/crates/signal-bridge)
+ [`crates/signal-bridge`](https://github.com/Fancy-Mumble/FancyMumble/tree/master/crates/signal-bridge)
as a `cdylib` and loaded at runtime via `libloading`. The MIT-
licensed Fancy Mumble client links to it dynamically; the AGPL
obligations stay scoped to that one `.dll` / `.so` / `.dylib`.
diff --git a/src/content/docs/server/features/push.mdx b/src/content/docs/server/features/push.mdx
index 29e664c..b27099f 100644
--- a/src/content/docs/server/features/push.mdx
+++ b/src/content/docs/server/features/push.mdx
@@ -7,6 +7,10 @@ sidebar:
import { Steps, Aside, Tabs, TabItem, Card, CardGrid } from '@astrojs/starlight/components';
+:::caution[Legacy C++ server instructions]
+This page documents the older mumble-server fork. Its INI keys, plugin paths, and ports do not configure Starling. For a new deployment, start with [Starling feature availability](/server/features/) and the [Starling configuration guide](/server/config/).
+:::
+
Fancy Mumble delivers notifications through two separate paths:
- **Live delivery (desktop and Android app while connected)** - The
diff --git a/src/content/docs/server/features/reactions.mdx b/src/content/docs/server/features/reactions.mdx
index f72fc31..5b25128 100644
--- a/src/content/docs/server/features/reactions.mdx
+++ b/src/content/docs/server/features/reactions.mdx
@@ -7,28 +7,21 @@ sidebar:
import { Aside, Card, CardGrid } from '@astrojs/starlight/components';
-Reactions and polls are **client-side features** that ride on top of
-the server's plugin-data transport. They do not need a dedicated
-server configuration. As long as your server is the Fancy Mumble
-fork, both features work.
+Starling handles reactions and polls through its **social service**. The same service carries typing indicators, read receipts, watch-together state, and drawing events. It relays updates only to members of the relevant channel and records the sender from the authenticated connection.
+
+The service is included in the default Starling stack. For a custom deployment, check that `social` is running and healthy. See [feature availability](/server/features/) and the [Starling service inventory](https://github.com/Fancy-Mumble/starling/blob/main/docs/SERVICES.md).
## Reactions
-Any user who has post permission in a channel can attach an emoji
-reaction to a message. The reaction is broadcast through the plugin-
-data channel and replicated to every Fancy client in the room.
+Users who can enter a channel can react to its messages. Starling checks channel access and sends the reaction to members of that channel, including its sender so their client can display it.
- Standard Unicode emoji are supported.
-- Custom server emotes (see [Custom emotes](/admin/emotes/)) can be
- used as reactions as long as the server has the file-server plugin
- enabled.
+- Custom server emotes (see [Custom emotes](/admin/emotes/)) need the emote assets to be available to clients.
-There are no server-side `MUMBLE_CONFIG_*` or `plugin.*` keys to
-tune this behavior in the public configuration. The client enforces
-its own per-message limits.
+Starling accepts emoji strings up to 64 bytes. The client controls its own per-message presentation limits.
## Polls
@@ -38,10 +31,7 @@ A user can create a poll inside a channel:
- Single-choice or multiple-choice (the creator picks).
- Votes are visible to other users.
-Polls travel through the plugin-data channel the same way reactions
-do. There is no separate retention setting; once a poll's chat
-message ages out under your persistent-chat retention, the poll goes
-with it.
+Starling stores polls and ballots in the social service's database, so votes continue to work after a server restart. A poll and its ballots are retained for up to **90 days** after it closes, or after creation if it has no closing time. Chat history has its own retention policy; a poll card can disappear from chat while the social record remains, or remain visible after voting has expired.
## Compatibility
@@ -58,9 +48,8 @@ messages and ignore the plugin-data carrying the reaction or vote.
- **Reactions or polls do not appear**: confirm both users are on
Fancy Mumble. A mixed-client channel will display the original
message but skip the overlay.
-- **Cannot react**: the user does not have post permission in the
- channel, or the message is too old (under your persistent-chat
- retention).
+- **Cannot react**: check that the user can enter the channel and that `social` is healthy.
+- **Cannot vote on an older poll**: the poll may be closed or beyond Starling's 90-day social retention.
## Next step
diff --git a/src/content/docs/server/features/watch-together.mdx b/src/content/docs/server/features/watch-together.mdx
index 6d89d7f..ec9a269 100644
--- a/src/content/docs/server/features/watch-together.mdx
+++ b/src/content/docs/server/features/watch-together.mdx
@@ -7,6 +7,10 @@ sidebar:
import { Aside } from '@astrojs/starlight/components';
+:::caution[Legacy C++ server instructions]
+This page documents the older mumble-server fork. Its INI keys, plugin paths, and ports do not configure Starling. For a new deployment, start with [Starling feature availability](/server/features/) and the [Starling configuration guide](/server/config/).
+:::
+
Watch Together lets one user in a channel play a video that is
synchronized for everyone else. Play, pause, and seek events
propagate to the other viewers.
diff --git a/src/content/docs/server/features/webrtc-sfu.mdx b/src/content/docs/server/features/webrtc-sfu.mdx
index 679b07a..831a292 100644
--- a/src/content/docs/server/features/webrtc-sfu.mdx
+++ b/src/content/docs/server/features/webrtc-sfu.mdx
@@ -8,6 +8,10 @@ sidebar:
import { Steps, Aside, Card, CardGrid, Tabs, TabItem } from '@astrojs/starlight/components';
import PlantUML from '../../../../components/PlantUML.astro';
+:::caution[Legacy C++ server instructions]
+This page documents the older mumble-server fork. Its INI keys, plugin paths, and ports do not configure Starling. For a new deployment, start with [Starling feature availability](/server/features/) and the [Starling configuration guide](/server/config/).
+:::
+
The screen-share relay (technically a Selective Forwarding Unit, or
SFU) is a small service inside the server that takes **one screen-
share upload** from a broadcaster and **fans it out** to every viewer
diff --git a/src/content/docs/server/features/whiteboard.mdx b/src/content/docs/server/features/whiteboard.mdx
index ba38945..11e4c09 100644
--- a/src/content/docs/server/features/whiteboard.mdx
+++ b/src/content/docs/server/features/whiteboard.mdx
@@ -7,6 +7,10 @@ sidebar:
import { Aside } from '@astrojs/starlight/components';
+:::caution[Legacy C++ server instructions]
+This page documents the older mumble-server fork. Its INI keys, plugin paths, and ports do not configure Starling. For a new deployment, start with [Starling feature availability](/server/features/) and the [Starling configuration guide](/server/config/).
+:::
+
The whiteboard lets anyone watching a screen share **draw on top of
it**. Useful for "point at this", code reviews, or just decorating a
movie night.
diff --git a/src/content/docs/server/network.mdx b/src/content/docs/server/network.mdx
index 54e5755..8cf60a5 100644
--- a/src/content/docs/server/network.mdx
+++ b/src/content/docs/server/network.mdx
@@ -1,438 +1,14 @@
---
-title: Ports & networking
-description: Which ports the server uses, what they do, and how to expose them.
-sidebar:
- order: 4
+title: Ports and networking
+description: Expose Starling's client, file, screen share, and administration listeners.
---
-import { Steps, Aside, Tabs, TabItem, Card, CardGrid } from '@astrojs/starlight/components';
-import PlantUML from '../../../components/PlantUML.astro';
-import { Icon } from 'astro-icon/components';
+For the maintained Starling Compose deployment, expose **64738/TCP** for the Mumble control connection and **64738/UDP** for voice. A classic Mumble client sends UDP to the same host and port it used for TCP. The gateway handles the TCP socket and the voice service handles UDP.
-The Fancy Mumble server uses up to four ports. Only the first one is
-strictly required.
+The Compose file also publishes **8080/TCP** for HTTP file transfers. Its sample public_url points to localhost; replace that URL with an address your users can reach, normally HTTPS through a reverse proxy. File links cannot work for remote clients while they point at localhost.
-| Port | Protocol | Purpose | Required? |
-|------|----------|---------|-----------|
-| **64738** | TCP and UDP | Voice and control | yes |
-| **64739** | TCP | File server - plain HTTP (emotes, avatars, attachments) | for file features |
-| **64740** | TCP | Live document WebSocket (Yjs CRDT sync) | for live documents |
-| **10000** | UDP | Screen-share relay | for smooth screen sharing |
-| **6502** | TCP | Admin RPC (Ice) | rarely, internal |
+Screen-share media uses a separate UDP listener when the relay is configured. Set the screenshare service public_url to a reachable literal IP and port; open that UDP port in your firewall. The old C++ server's port 10000 is not a Starling default. The [example TOML](https://github.com/Fancy-Mumble/starling/blob/main/starling.example.toml) shows the relevant settings.
- P1 : always required
-Client --> P3 : screen sharing
-Client --> P4 : admin tools only
-Client --> RP : HTTPS 443
-Browser --> RP : HTTPS 443
-RP --> P2 : HTTP 64739
-RP --> P5 : WSS \u2192 WS 64740
-Client ..> P2 : HTTP 64739 (direct, LAN only)
-Client ..> P5 : WS 64740 (direct, LAN only)
-Browser ..> P2 : HTTP 64739 (direct, LAN only)
-Browser ..> P5 : WS 64740 (direct, LAN only)
-Push ..> FCM : HTTPS 443
-
-note right of RP
- Live-doc proxy requires:
- Upgrade + Connection headers
- Query string preserved
- (JWT in ?token=...)
-end note
-@enduml
-`} />
-
-## Port-by-port walk-through
-
-### 64738, voice and control
-
-The classic Mumble port. Used for:
-
-- The initial **TLS handshake** that authenticates the connection.
-- **Control messages** (channel updates, chat, user actions).
-- **Voice** (UDP preferred for low latency, TCP fallback).
-
-This is the only port you absolutely must expose. Without it nobody
-can connect.
-
-Open both TCP and UDP. Modern routers and firewalls treat them as
-two distinct rules.
-
-### 64739, file server
-
-Used for:
-
-- **Uploading and downloading files** that were shared in chat.
-- **Custom server emote** images.
-- **Avatar uploads** from the profile editor.
-- **Link preview images** rendered server-side.
-
-The file server speaks **plain HTTP** - there is no built-in TLS. Traffic
-on this port is unencrypted unless you put a TLS-terminating reverse proxy
-in front. For anything beyond a private LAN, a reverse proxy is strongly
-recommended.
-
-If you skip this port, the **paperclip button in chat is hidden** and
-avatars fall back to the older inline-only mode.
-
-You can put a **reverse proxy in front** (recommended for production)
-to terminate TLS, add caching, and so on. See [File server](/server/features/file-server/).
-
-### 64740, live document WebSocket
-
-Used for:
-
-- **Real-time CRDT synchronization** of shared channel documents via the Yjs protocol.
-- Transporting collaborative cursor positions and awareness updates.
-
-Like the file server, this port speaks **plain WebSocket (ws://)** with no
-built-in TLS. Put it behind a TLS-terminating reverse proxy in production
-so clients reach it as **wss://**. The live-doc plugin is **disabled by
-default** - see [Live Documents](/server/features/live-doc/) to enable it.
-
-If this port is unreachable, the "Open Live Doc" button will time out waiting
-for an invite reply from the server.
-
-### 10000, screen-share relay
-
-Used for:
-
-- **One incoming WebRTC stream** from each broadcaster.
-- **Many outgoing WebRTC streams** to viewers.
-
-Without this port (or without the relay enabled), screen sharing
-falls back to direct peer-to-peer, which is less reliable behind
-strict NATs.
-
-### 6502, admin RPC
-
-Used for:
-
-- The **legacy Ice administrative interface**.
-- Third-party authentication scripts.
-
-By default this port is **only bound to localhost inside the
-container**. Expose it (and set up authentication) only if you have
-a specific tool that needs it.
-
-## Exposing the ports
-
-
-
- ```yaml
- ports:
- - "64738:64738/tcp"
- - "64738:64738/udp"
- - "64739:64739/tcp"
- - "64740:64740/tcp" # live documents (optional)
- - "10000:10000/udp"
- # Only if you need admin RPC from outside the host:
- # - "127.0.0.1:6502:6502/tcp"
- ```
-
-
- ```bash
- docker run \
- -p 64738:64738/tcp \
- -p 64738:64738/udp \
- -p 64739:64739/tcp \
- -p 64740:64740/tcp \
- -p 10000:10000/udp \
- ...
- ```
-
-
-
-## Public IP for screen sharing
-
-The screen-share relay needs to **advertise a reachable IP address**
-to viewers. Set it with:
-
-```yaml
-environment:
- MUMBLE_CONFIG_WEBRTCSFUENABLED: true
- MUMBLE_CONFIG_WEBRTCSFUPORT: 10000
- MUMBLE_CONFIG_WEBRTCSFUPUBLICIP: "203.0.113.5"
-```
-
-- For a **public server**, use the public IP.
-- For a **home server with a public DNS**, use the IP that DNS
- resolves to.
-- For **local testing**, use `127.0.0.1`.
-- Do **not** use `0.0.0.0`, it is not a valid candidate and viewers
- will fail to connect.
-
-## Behind a reverse proxy
-
-You can put the **file server** (64739) and the **live-doc WebSocket** (64740)
-behind nginx, Caddy, or Traefik.
-
-For the file server:
-
-```ini
-plugin.file-server.tlsTerminatedByProxy=true
-plugin.file-server.baseUrl=https://files.example.com
-plugin.file-server.allowedOrigins=https://files.example.com
-```
-
-### Live-doc WebSocket behind a proxy
-
-The live-doc plugin is a standard **axum HTTP server** - the WebSocket
-connection is a normal HTTP Upgrade. Three things are required for the proxy
-to work correctly:
-
-| Requirement | Why |
-|-------------|-----|
-| Strip the `/live-doc` path prefix | The axum backend serves routes at `/ws/…` — without stripping, the backend returns 404 |
-| Forward `Upgrade` + `Connection` headers | Without them the proxy returns HTTP 400 on connect |
-| Preserve the query string | The handshake JWT is passed as `?token=...` and must reach the backend |
-| Set `plugin.live-doc.public_url` | Tells clients the `wss://` URL to connect to instead of `ws://bind-address:64740` |
-
-
-With `public_url=wss://chat.example.com/live-doc` the client connects to
-`wss://chat.example.com/live-doc/ws/{server}/{channel}/{slug}`. The proxy
-must strip `/live-doc` before forwarding so the backend receives `/ws/…`.
-
-
-
-
- `handle_path` strips the prefix automatically:
- ```text
- chat.example.com {
- handle_path /live-doc/* {
- reverse_proxy localhost:64740
- }
- }
- ```
- Then in your `mumble-server.ini`:
- ```ini
- plugin.live-doc.public_url=wss://chat.example.com/live-doc
- ```
-
-
- The trailing slash on both `location` and `proxy_pass` strips the prefix:
- ```nginx
- location /live-doc/ {
- proxy_pass http://127.0.0.1:64740/;
- proxy_http_version 1.1;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "Upgrade";
- proxy_set_header Host $host;
- }
- ```
- Then in your `mumble-server.ini`:
- ```ini
- plugin.live-doc.public_url=wss://chat.example.com/live-doc
- ```
-
-
- Traefik needs an explicit `StripPrefix` middleware:
- ```yaml
- http:
- middlewares:
- live-doc-strip:
- stripPrefix:
- prefixes:
- - /live-doc
- routers:
- live-doc:
- rule: "Host(`chat.example.com`) && PathPrefix(`/live-doc`)"
- service: live-doc
- entryPoints: [websecure]
- middlewares:
- - live-doc-strip
- services:
- live-doc:
- loadBalancer:
- servers:
- - url: "http://127.0.0.1:64740"
- ```
- Then in your `mumble-server.ini`:
- ```ini
- plugin.live-doc.public_url=wss://chat.example.com/live-doc
- ```
-
-
-
-
-Caddy and Traefik forward `Upgrade` headers automatically. nginx requires the
-explicit `proxy_set_header Upgrade` and `proxy_set_header Connection` lines -
-omitting them causes a **400 Bad Request** on the WebSocket handshake.
-
-
-The voice port (64738) cannot easily go behind a generic HTTP proxy
-since it is a custom binary protocol. Use TCP-level passthrough or a
-dedicated TLS-terminating load balancer if needed.
-
-
-Modifying UDP voice through a TCP-only proxy adds latency and ruins
-quality. Either expose UDP directly or rely on the client's
-**Force TCP** fallback.
-
-
-## Firewall and NAT
-
-If the server is on a home network, forward each port from your
-router:
-
-- TCP 64738 to the server.
-- UDP 64738 to the server.
-- TCP 64739 to the server (optional, file server).
-- TCP 64740 to the server (optional, live documents).
-- UDP 10000 to the server (optional, screen-share relay).
-
-For IPv6, open the same ports in the AAAA firewall rules.
-
-For UFW (Ubuntu firewall):
-
-```bash
-sudo ufw allow 64738/tcp
-sudo ufw allow 64738/udp
-sudo ufw allow 64739/tcp
-sudo ufw allow 64740/tcp
-sudo ufw allow 10000/udp
-```
-
-For firewalld (Fedora and friends):
-
-```bash
-sudo firewall-cmd --add-port=64738/tcp --permanent
-sudo firewall-cmd --add-port=64738/udp --permanent
-sudo firewall-cmd --add-port=64739/tcp --permanent
-sudo firewall-cmd --add-port=64740/tcp --permanent
-sudo firewall-cmd --add-port=10000/udp --permanent
-sudo firewall-cmd --reload
-```
-
-## Quick health-check
-
-From another host:
-
-```bash
-# Voice port (TCP)
-nc -zv your-host 64738
-
-# File server (HTTP)
-curl -sI https://your-host:64739/healthz | head -1
-```
-
-A `Connected to ...` (TCP) and a `200 OK` (HTTP) mean you are good.
-
-## Bandwidth planning
-
-Mumble's voice bandwidth depends on the audio quality setting chosen by
-each client. The server sets a cap via [`bandwidth`](/reference/config-keys/#server-identity-and-limits).
-
-**Per-user rules of thumb:**
-
-| Scenario | Bandwidth |
-|----------|-----------|
-| Minimum (any packet loss below this) | **15.8 kbit/s** per user |
-| Typical (20 ms packets, ~50 kbit/s quality) | **65 kbit/s** per user |
-| Maximum (10 ms packets, 96 kbit/s quality) | **134 kbit/s** per user |
-
-**Server-side formula** (all speakers in one channel, everyone talking at once - the theoretical worst case):
-
-$$
-\text{incoming} = \text{quality} \times \text{users}
-$$
-$$
-\text{outgoing} = \text{quality} \times (\text{users} - 1) \times \text{users}
-$$
-$$
-\text{total} = \text{incoming} + \text{outgoing}
-$$
-
-**Example:** 16 users at 128 kbit/s each, all talking simultaneously:
-
-- incoming = 128 × 16 = 2 048 kbit/s
-- outgoing = 128 × 15 × 16 = 30 720 kbit/s
-- total = **32 768 kbit/s ≈ 4 MiB/s**
-
-In practice, not everyone speaks at once. A realistic 30-user server
-with a few active channels is usually well under 1 MiB/s.
-
-
-Set `bandwidth` (bits per second) in your `.env` to cap how much
-each client may send. The client auto-adjusts its quality to stay
-within the cap.
-
-
-## SRV DNS record
-
-An SRV record lets users connect with just a domain name - no port
-required. Fancy Mumble resolves the record automatically when a user
-types a bare domain into the server address field.
-
-Add this to your DNS zone:
-
-```dns-zone
-_mumble._tcp.yourdomain.com. 3600 IN SRV 10 0 64738 mumble.yourdomain.com.
-```
-
-The four fields after `SRV` are: **priority** (10), **weight** (0),
-**port** (64738), **target hostname**.
-
-With the record in place, users can type `yourdomain.com` and the
-client picks up the correct host and port automatically. Without it
-they must type `mumble.yourdomain.com:64738` explicitly.
-
-
-The service label is `_mumble._tcp` - the upstream Mumble protocol
-standard. No other variant is needed.
-
-
-## Next step
-
-Continue with the **Feature deep-dives** to pick what to enable:
-
-
-
- Encrypted, server-stored chat history.
- [Learn more](/server/features/persistent-chat/).
-
-
- Notify mobile users when the app is closed.
- [Learn more](/server/features/push/).
-
-
- One upload, many downloads.
- [Learn more](/server/features/webrtc-sfu/).
-
-
- Emotes, avatars, file uploads.
- [Learn more](/server/features/file-server/).
-
-
+Internal gRPC service endpoints are for Starling components, not public client ports. See [Ports and protocols](/reference/ports/) for a compact list.
diff --git a/src/content/docs/server/plugins/developing.mdx b/src/content/docs/server/plugins/developing.mdx
index d521a9d..81b1e77 100644
--- a/src/content/docs/server/plugins/developing.mdx
+++ b/src/content/docs/server/plugins/developing.mdx
@@ -7,6 +7,10 @@ sidebar:
import { Steps, Aside, Tabs, TabItem, Code } from '@astrojs/starlight/components';
+:::caution[Legacy C++ server instructions]
+This page documents the older mumble-server fork. Its INI keys, plugin paths, and ports do not configure Starling. For a new deployment, start with [Starling feature availability](/server/features/) and the [Starling configuration guide](/server/config/).
+:::
+
This guide walks through writing a Fancy Mumble server plugin from
scratch. Plugins are Rust `cdylib` crates that depend on the
[`mumble-plugin-api`] crate and are loaded at runtime by the plugin
diff --git a/src/content/docs/server/plugins/overview.mdx b/src/content/docs/server/plugins/overview.mdx
index b1e8ad7..5ba2156 100644
--- a/src/content/docs/server/plugins/overview.mdx
+++ b/src/content/docs/server/plugins/overview.mdx
@@ -8,6 +8,10 @@ sidebar:
import { Aside, Card, CardGrid } from '@astrojs/starlight/components';
import PlantUML from '../../../../components/PlantUML.astro';
+:::caution[Legacy C++ server instructions]
+This page documents the older mumble-server fork. Its INI keys, plugin paths, and ports do not configure Starling. For a new deployment, start with [Starling feature availability](/server/features/) and the [Starling configuration guide](/server/config/).
+:::
+
Fancy Mumble extends the classic Mumble server with a **Rust plugin
host**. Features like the persistence-backed file store, the
collaborative live-doc editor, screen-share signalling glue, and the
diff --git a/src/content/docs/server/plugins/using.mdx b/src/content/docs/server/plugins/using.mdx
index 7ca4377..0196889 100644
--- a/src/content/docs/server/plugins/using.mdx
+++ b/src/content/docs/server/plugins/using.mdx
@@ -7,6 +7,10 @@ sidebar:
import { Steps, Aside, Tabs, TabItem } from '@astrojs/starlight/components';
+:::caution[Legacy C++ server instructions]
+This page documents the older mumble-server fork. Its INI keys, plugin paths, and ports do not configure Starling. For a new deployment, start with [Starling feature availability](/server/features/) and the [Starling configuration guide](/server/config/).
+:::
+
This page covers operating plugins on a running server: where the host
looks for them, how configuration keys are namespaced, how to verify
that a plugin loaded correctly, and a tour of the plugins that ship
diff --git a/src/content/docs/server/upgrade.mdx b/src/content/docs/server/upgrade.mdx
index b9a6328..69b2274 100644
--- a/src/content/docs/server/upgrade.mdx
+++ b/src/content/docs/server/upgrade.mdx
@@ -1,220 +1,33 @@
---
-title: Upgrade & backup
-description: Keep your server up to date, back up your data, restore from a backup.
-sidebar:
- order: 7
+title: Upgrade and backup
+description: Preserve Starling's data and certificate when updating or migrating a server.
---
-import { Steps, Aside, Tabs, TabItem, Card, CardGrid } from '@astrojs/starlight/components';
+## What to keep
-Two things you should do regularly. Both take minutes.
+Keep the complete Starling data directory or the Compose starling-data volume, including the generated TLS certificate. Clients remember the certificate fingerprint as the server's identity. Also back up your starling.toml, any included TOML files, and secrets kept outside the data volume. A distributed deployment may use external databases or object storage; back those up using their own consistent snapshot tools.
-## What to back up
-
-Three things matter:
-
-| Item | Where | Why |
-|------|-------|-----|
-| The **server database** | `/data/mumble-server.sqlite` (in the volume) | Channels, users, ACLs, chat history. |
-| The **file storage** | `/data/file-server-storage/` (in the volume) | Avatars, emotes, attachments. |
-| Your **`.env` file** | on the host | Server settings, secrets. |
-
-The whole `/data` volume covers items 1 and 2. Back up the host-side
-config separately.
-
-## Back up
-
-The simplest approach is to stop the server, copy the volume, and
-restart:
-
-
-1. Stop the server:
-
- ```bash
- docker compose stop mumble-server
- ```
-
-2. Copy the volume:
-
- ```bash
- docker run --rm \
- -v mumble-data:/source:ro \
- -v "$(pwd)":/dest \
- alpine \
- tar -czf /dest/mumble-backup-$(date +%F).tar.gz -C /source .
- ```
-
-3. Restart the server:
-
- ```bash
- docker compose start mumble-server
- ```
-
-4. Also back up your `.env`:
-
- ```bash
- cp .env "/secure/place/.env-mumble-$(date +%F)"
- ```
-
-
-You can also back up **without stopping** if you accept the small risk
-of an inconsistent SQLite snapshot. For production it is safer to
-stop briefly.
-
-## Schedule it
-
-A cron job that runs the steps above weekly is enough for most
-servers. Adjust the retention to your taste:
-
-```bash
-# /etc/cron.weekly/mumble-backup
-#!/bin/bash
-set -e
-cd /srv/mumble
-docker compose stop mumble-server
-docker run --rm \
- -v mumble-data:/source:ro \
- -v /backups/mumble:/dest \
- alpine \
- tar -czf /dest/mumble-$(date +%F).tar.gz -C /source .
-docker compose start mumble-server
-find /backups/mumble -mtime +60 -delete
-```
-
-Make it executable and you are done.
-
-## Restore from a backup
-
-
-1. Stop the server:
-
- ```bash
- docker compose stop mumble-server
- ```
-
-2. Remove the existing volume:
-
- ```bash
- docker volume rm mumble-data
- docker volume create mumble-data
- ```
-
-3. Restore:
-
- ```bash
- docker run --rm \
- -v mumble-data:/dest \
- -v "$(pwd)":/source \
- alpine \
- tar -xzf /source/mumble-backup-2026-05-01.tar.gz -C /dest
- ```
-
-4. Start the server:
-
- ```bash
- docker compose start mumble-server
- ```
-
-5. Reset the SuperUser password if needed:
-
- ```bash
- docker exec mumble-server mumble-server \
- --ini /data/mumble_server_config.ini \
- --set-su-pw "new-password"
- ```
-
+Stop the stack before copying its local data volume so SQLite files form a consistent snapshot. Docker Compose down keeps the volume; adding -v deletes it. Record the actual volume name with docker volume ls, since Compose normally prefixes it with the project name.
## Upgrade
-The official image is published to `ghcr.io/fancy-mumble/mumble-server:latest`.
-
-
-1. Take a backup (see above).
-2. Pull the new image:
-
- ```bash
- docker compose pull mumble-server
- ```
-
-3. Recreate the container:
-
- ```bash
- docker compose up -d mumble-server
- ```
-
-4. Watch the logs for migration messages:
-
- ```bash
- docker compose logs -f mumble-server
- ```
-
-5. Connect with a client and sanity-check that channels, chat history,
- and avatars are all there.
-
-
-
-For production, pin to a specific tag instead of `latest`:
-
-```yaml
-image: ghcr.io/fancy-mumble/mumble-server:1.6.1
-```
-
-That way you control when you upgrade.
-
-
-## Rollback
-
-If an upgrade goes wrong:
-
-
-1. Stop the server.
-2. Restore the previous backup (see "Restore" above).
-3. Set the image back to the previous tag.
-4. Start the server.
-
-
-The database schema is **only ever** added to in minor versions, never
-removed, so rolling back the binary is safe as long as you also
-restore the database.
-
-## Migrating to a new host
-
-
-1. On the old host: stop the server, take a backup.
-2. Copy the backup file and `.env` to the new host.
-3. On the new host: install Docker, copy your `docker-compose.yml`,
- restore from the backup, start the server.
-4. Update DNS to point at the new host.
-5. Once you have confirmed it works, retire the old server.
-
-
-If you also change the public IP, update `webrtcsfupublicip` in your
-config or screen sharing will be broken until you do.
-
-## Database growth
-
-The two big spenders are persistent chat and link previews:
-
-- Lower `pchatdefaultretentiondays` to clear out old messages.
-- Lower `plugin.file-server.retentionDays` to clear out old files.
-
-Then run `VACUUM` once to reclaim space:
+Read the [Starling release notes](https://github.com/Fancy-Mumble/starling/releases), take a backup, then pull the new image and restart:
-```bash
-docker exec mumble-server sqlite3 /data/mumble-server.sqlite "VACUUM;"
-```
+~~~sh
+docker compose pull
+docker compose up -d --wait
+docker compose logs gateway
+~~~
-## What if the database is corrupted?
+If you use a local build, update the source and run Docker Compose with --build instead. Keep the data volume mounted across restarts.
-Restore from the most recent backup. Mumble's SQLite database is
-normally robust, but a disk failure or a sudden power-cut can
-truncate it. Backups are your friend.
+## Move from the C++ server
-## Next step
+Starling includes migration commands for the old mumble-server.ini and murmur database. Preview the database import before writing:
-You are done with the server section. Continue with the admin pages
-to learn how to manage users, channels, and permissions:
+~~~sh
+starling migrate-config /path/to/mumble-server.ini > starling.toml
+starling migrate-db --from sqlite:/path/to/murmur.sqlite --dry-run
+~~~
-- [SuperUser & first login](/admin/superuser/)
-- [Channels](/admin/channels/)
-- [Roles & permissions](/admin/roles/)
+Review the reported differences, then follow the [Starling migration guide](https://github.com/Fancy-Mumble/starling/blob/main/docs/PROTOCOL-MIGRATION.md) for the target instance, import, and verification steps. Keep the old database and configuration backup until you have tested client login, channels, ACLs, and files on Starling.
diff --git a/src/content/docs/server/wizard.mdx b/src/content/docs/server/wizard.mdx
index 7379eac..28a1845 100644
--- a/src/content/docs/server/wizard.mdx
+++ b/src/content/docs/server/wizard.mdx
@@ -1,189 +1,10 @@
---
-title: Setup wizard
-description: Walk through every server setting with an interactive wizard, in your terminal or a graphical window.
-sidebar:
- order: 2
+title: First-run setup
+description: Start Starling and find its generated administrator credentials.
---
-import { Steps, Aside, Tabs, TabItem, Code, Card, CardGrid } from '@astrojs/starlight/components';
+Starling starts with working defaults. On its first run it writes a starter config, creates the server certificate and SuperUser account, and prints the generated password. Save that password and keep the data directory or Docker volume.
-If you prefer "click Next a few times" over "edit YAML", the **setup
-wizard** walks you through every value in your `.env` file. It comes
-in two flavours:
+For a local binary, run Starling in all-in-one mode and connect to localhost:64738. For Docker, follow [Run Starling with Docker](/server/docker/). Then adjust starling.toml using [Configuration](/server/config/).
-- **Terminal**: pure Python standard library, no extra installs.
-- **Graphical**: a multi-step window with form validation.
-
-
-
-
-## Prerequisites
-
-- Python 3.8 or newer on the machine running the wizard.
-- The Fancy Mumble Docker repository checked out locally:
-
- ```bash
- git clone https://github.com/Fancy-Mumble/mumble-docker
- cd mumble-docker
- ```
-
-## Run the wizard
-
-
-
- ```bash
- python -m setup_wizard
- ```
-
-
- Install the GUI dependency once:
-
- ```bash
- python -m pip install -r setup_wizard/requirements.txt
- ```
-
- Then launch:
-
- ```bash
- python -m setup_wizard --gui
- ```
-
-
-
-You can also invoke through the tools entry point:
-
-```bash
-python -m tools setup # terminal
-python -m tools setup --gui # graphical
-```
-
-## What the wizard asks
-
-The wizard is a multi-step form. Each step is validated before you
-can move on.
-
-
-
-1. **Source tree**. Point the wizard at your local server source
- checkout, or click **Clone** to let the wizard download it for you.
-
-2. **Image and container names**. Pick the Docker image tag and the
- container name. Defaults are fine for most.
-
-3. **Ports**. Confirm the ports for voice (64738), the file server
- (64739), the live-doc WebSocket (64740), and the screen-share
- relay (10000). Change them if you need to run two servers on the
- same machine.
-
-4. **Runtime user**. The UID and GID the server runs as inside the
- container. Default is 10000:10000. Change to match the owner of
- your data volume if you bind-mount a host folder.
-
-5. **SuperUser password**. Either type one, click **Generate** for a
- strong random one, or leave blank. If you leave it blank, the
- server will print a random password to the log on the first start.
-
-6. **Optional file mounts**. Bind-mount a custom config file, a
- Firebase credentials JSON, or extra plugin libraries.
-
-7. **Firebase push credentials**. If you want push notifications,
- point the wizard at your service-account JSON. It will base64
- encode the file into the `.env` so credentials never live on a
- bind-mounted host path.
-
-
-
-When you click **Save .env** on the last step, the wizard writes
-`.env` next to your `docker-compose.yml`. You can review the file by
-hand if you want.
-
-## Re-running the wizard
-
-You can re-run the wizard later to change one value without redoing
-all the others. The wizard reads the existing `.env` and pre-fills
-every prompt with the current value.
-
-```bash
-python -m setup_wizard
-```
-
-
-The wizard is non-destructive. It will not overwrite a config you set
-by hand outside the wizard, as long as you keep the file format
-intact.
-
-
-## Starting the server
-
-With the `.env` written, start the container:
-
-```bash
-docker compose up -d
-```
-
-Or, if you want to rebuild the image locally first (for example
-because you changed the source tree):
-
-```bash
-python -m tools dev-build
-```
-
-## Setting the SuperUser password later
-
-If you left the password blank, find the auto-generated one with:
-
-```bash
-docker logs mumble-server 2>&1 | grep -i superuser
-```
-
-Or set a new one at any time:
-
-```bash
-docker exec mumble-server mumble-server \
- --ini /data/mumble_server_config.ini \
- --set-su-pw "your-strong-password"
-```
-
-## What is in the .env
-
-A typical `.env` looks like this:
-
-```ini
-# Image
-MUMBLE_IMAGE=ghcr.io/fancy-mumble/mumble-server:latest
-CONTAINER_NAME=mumble-server
-
-# Ports
-MUMBLE_PORT=64738
-MUMBLE_FILE_PORT=64739
-MUMBLE_SFU_PORT=10000
-
-# Runtime
-PUID=10000
-PGID=10000
-
-# Server identity
-MUMBLE_SUPERUSER_PASSWORD=...
-
-# Push (optional, set to enable)
-MUMBLE_FCM_CREDENTIALS_BASE64=...
-```
-
-Every other server option can be added as a `MUMBLE_CONFIG_*` entry,
-see the [Configuration reference](/server/config/).
-
-## Next steps
-
-
-
- Browse the [Configuration reference](/server/config/) to set
- welcome message, user limits, retention, and more.
-
-
- Walk through the **Feature deep-dives** to turn on push, the
- screen-share relay, and link previews.
-
-
- Take ownership with [SuperUser & first login](/admin/superuser/).
-
-
+The Python terminal and graphical setup wizard in mumble-docker configures the older C++ server image. It does not generate Starling's TOML configuration. If you are maintaining that deployment, see the [legacy Docker repository](https://github.com/Fancy-Mumble/mumble-docker).
diff --git a/src/content/docs/troubleshooting/common-issues.mdx b/src/content/docs/troubleshooting/common-issues.mdx
index 0df72ce..7236e07 100644
--- a/src/content/docs/troubleshooting/common-issues.mdx
+++ b/src/content/docs/troubleshooting/common-issues.mdx
@@ -39,14 +39,14 @@ Before diving into a specific page, try these:
- **Restart the app**. Many transient bugs go away.
- **Update the app** to the latest version. Get it from
[fancy-mumble.com](https://fancy-mumble.com/) or the
- [GitHub releases page](https://github.com/Fancy-Mumble/FancyMumbleNext/releases).
+ [GitHub releases page](https://github.com/Fancy-Mumble/FancyMumble/releases).
- **Try a different network**. Tether to your phone for a quick A/B.
### The server
- **Check the server is up**: `ping your-host` or
`nc -zv your-host 64738`.
-- **Check the server logs**: `docker compose logs -f mumble-server`.
+- **Check the Starling logs**: `docker compose logs -f gateway`.
- **Restart the server** if you can afford a moment of downtime.
### Your account
@@ -59,9 +59,9 @@ Before diving into a specific page, try these:
## When you cannot find a solution
- **Search existing issues** in the
- [client repo](https://github.com/Fancy-Mumble/FancyMumbleNext/issues)
+ [client repo](https://github.com/Fancy-Mumble/FancyMumble/issues)
or
- [server repo](https://github.com/Fancy-Mumble/mumble-server/issues).
+ [Starling repo](https://github.com/Fancy-Mumble/starling/issues).
- **Open a new issue** with the information from
[Reporting bugs](/troubleshooting/reporting-bugs/).
diff --git a/src/content/docs/troubleshooting/connection.mdx b/src/content/docs/troubleshooting/connection.mdx
index f72c685..86b1901 100644
--- a/src/content/docs/troubleshooting/connection.mdx
+++ b/src/content/docs/troubleshooting/connection.mdx
@@ -1,138 +1,39 @@
---
title: Connection problems
-description: Refused, timed out, drops, password asks. A symptom-driven checklist.
-sidebar:
- order: 3
+description: Check the client address, Starling listener, credentials, and certificate.
---
-import { Steps, Aside, Card, CardGrid } from '@astrojs/starlight/components';
+## Connection refused or timed out
-Walk through the section that matches your symptom.
+Check the server address and port. Starling's default Mumble port is **64738**. On the server, check the gateway and both TCP and UDP firewall rules:
-## "Connection refused"
+~~~sh
+docker compose ps
+docker compose logs gateway
+~~~
-The server is not running, or the port is wrong.
+A TCP port probe can show whether the control listener is reachable:
-
-1. Verify the address is correct. Default port is **64738**.
-2. Ping the host:
- ```bash
- ping your-host
- ```
-3. Test the port:
- ```bash
- nc -zv your-host 64738
- ```
- If this fails, the firewall is in the way.
-4. (Server side) Confirm the container is running:
- ```bash
- docker compose ps
- ```
-
+~~~sh
+nc -zv your-server.example.org 64738
+~~~
-## "Connection timed out"
+If TCP works but voice does not, check **64738/UDP**. Force TCP in the client's voice network settings as a diagnostic fallback.
-The packet is being dropped somewhere between you and the server.
+## Password or identity rejected
-
-1. Verify with another network (phone tether) to rule out your
- local ISP.
-2. (Server side) Check the firewall lets in `64738/tcp` and
- `64738/udp`.
-3. (Server side) Check the cloud provider's security group allows the
- same ports.
-4. **Force TCP** in audio settings, sometimes only UDP is blocked.
-
+Check the username and password with the server owner. A registered account may also be tied to a certificate, so verify the selected client identity. For a fresh Starling server, the SuperUser password was printed once at first boot; see [SuperUser and first login](/admin/superuser/).
-## "TLS handshake failed"
+## Certificate changed
-The server's certificate is rejected by your client.
+Starling keeps its self-signed TLS certificate in the data directory. If that directory or Docker volume was replaced, clients see a changed certificate fingerprint. Confirm the new fingerprint with the server owner before accepting it. Preserve the data directory during upgrades.
-- The server's certificate may have changed. The app asks you to
- accept the new identity. **Read the new hash carefully** before
- accepting.
-- If you used to connect and the server has been reinstalled, the
- hash is expected to change. Accept it.
+## Public listing is missing
-## "Wrong username or password"
+Public directory registration is off until the registry fields are configured in Starling's instances.settings. A password-protected server is not listed. See the [Starling example TOML](https://github.com/Fancy-Mumble/starling/blob/main/starling.example.toml).
-- Server has a password set. Get it from the admin.
-- The username does not match the case (Mumble is case-insensitive
- for registered users, but case-sensitive for the initial login).
-- Your certificate is wrong for the registered name. Open
- Identities and confirm you are using the right one.
+## The server exits at startup
-## "Server rejected the username regex"
+Read the gateway or affected service logs. Starling rejects unknown TOML keys. Compare your file with its [configuration reference](https://github.com/Fancy-Mumble/starling/blob/main/examples/reference.toml). The C++ server's MUMBLE_CONFIG_* variables are not Starling settings.
-The server requires usernames to match a pattern.
-
-- Use 3 to 15 characters of letters, digits, dashes, underscores by
- default.
-- The admin can change `MUMBLE_CONFIG_USERNAME` to a different
- regex.
-
-## "Disconnects randomly after a few minutes"
-
-Often a NAT timeout or a packet-loss spike.
-
-- Turn on **Auto-reconnect** in Advanced settings.
-- **Force TCP** to keep one connection alive.
-- (Server side) Check for `keepalive` settings in the server INI.
-- (Server side) Confirm the cloud provider does not have an idle
- timeout on the load balancer below 60 seconds.
-
-## "Connects but cannot hear anyone or be heard"
-
-Voice (UDP) is broken even though the control channel (TCP) works.
-
-- Turn on **Force TCP** in audio settings. This is the universal
- fix; you trade a little latency for reliability.
-- (Server side) Open UDP 64738 in the firewall and forwarder.
-
-## "The app shows me as connecting forever"
-
-Stuck in the bootstrap phase. The first connect after start fetches
-channels, users, and own session info.
-
-- Restart the app.
-- Look at the **Activity log** for an error.
-- If you self-hosted, look at the server logs.
-
-## "Public server list is empty"
-
-- Your internet route to `mumble.info`'s directory is blocked. Try
- again later.
-- Some corporate networks block the directory.
-
-## "Cannot find my self-hosted server in the public list"
-
-- You did not set `registerName`, `registerHostname`, and
- `registerPassword` in the server config.
-- The directory has not yet picked up your server. Can take up to
- an hour.
-
-## "App says certificate cannot be verified"
-
-This is the trust-on-first-use warning. The first time you connect
-the app pins the server's certificate hash. If it ever changes, you
-get this warning.
-
-- If you trust the change, accept.
-- If you did not expect a change, **stop**. The connection might be
- intercepted.
-
-## Server-side: connection refused with no logs
-
-- Check `docker compose logs mumble-server` for a panic at startup.
-- The most common cause is a typo in `MUMBLE_CONFIG_*`. The server
- refuses to start with an unknown key by default.
-- Set `MUMBLE_ACCEPT_UNKNOWN_SETTINGS=true` to pass through unknown
- values (use sparingly, you might hide a real typo).
-
-## Still broken?
-
-[Open a bug report](/troubleshooting/reporting-bugs/) with:
-
-- Whether you can `nc -zv` the port.
-- Whether the issue happens from a different network.
-- Debug logs from both the client and the server.
+If the problem persists, include the client and server versions and relevant logs in a [bug report](/troubleshooting/reporting-bugs/).
diff --git a/src/content/docs/troubleshooting/debug-logging.mdx b/src/content/docs/troubleshooting/debug-logging.mdx
index 1613127..fe696af 100644
--- a/src/content/docs/troubleshooting/debug-logging.mdx
+++ b/src/content/docs/troubleshooting/debug-logging.mdx
@@ -145,16 +145,16 @@ The folder also contains rotated archives:
```bash
# Live:
-docker compose logs -f mumble-server
+docker compose logs -f gateway
# Last 1000 lines:
-docker compose logs --tail=1000 mumble-server > server.log
+docker compose logs --tail=1000 gateway > server.log
```
For long-running diagnostics, redirect to a file:
```bash
-docker compose logs -f mumble-server > server.log 2>&1 &
+docker compose logs -f gateway > server.log 2>&1 &
# ... reproduce the issue ...
kill %1
```
diff --git a/src/content/docs/troubleshooting/reporting-bugs.mdx b/src/content/docs/troubleshooting/reporting-bugs.mdx
index f3e4251..1d30a8c 100644
--- a/src/content/docs/troubleshooting/reporting-bugs.mdx
+++ b/src/content/docs/troubleshooting/reporting-bugs.mdx
@@ -14,9 +14,9 @@ hitting **Submit**.
| You are reporting | Where to file |
|-------------------|---------------|
-| The app crashes, misrenders, or behaves wrong | [FancyMumbleNext, app](https://github.com/Fancy-Mumble/FancyMumbleNext/issues) |
-| The server crashes, accepts a bad config, fails to start | [Fancy-Mumble/mumble-server](https://github.com/Fancy-Mumble/mumble-server/issues) |
-| The Docker image misbehaves, build issues, entrypoint issues | [Fancy-Mumble/mumble-docker](https://github.com/Fancy-Mumble/mumble-docker/issues) |
+| The app crashes, misrenders, or behaves wrong | [FancyMumble, app](https://github.com/Fancy-Mumble/FancyMumble/issues) |
+| Starling crashes, rejects a valid config, or its Compose deployment fails | [Fancy-Mumble/starling](https://github.com/Fancy-Mumble/starling/issues) |
+| The older C++ server or its Docker image fails | [Fancy-Mumble/mumble-server](https://github.com/Fancy-Mumble/mumble-server/issues) or [mumble-docker](https://github.com/Fancy-Mumble/mumble-docker/issues) |
| The docs (this site) | [Fancy-Mumble/docs](https://github.com/Fancy-Mumble/docs/issues) |
When in doubt, file on the app repo. A maintainer will move it.
diff --git a/src/content/docs/troubleshooting/screen-share.mdx b/src/content/docs/troubleshooting/screen-share.mdx
index c810706..c6bbffd 100644
--- a/src/content/docs/troubleshooting/screen-share.mdx
+++ b/src/content/docs/troubleshooting/screen-share.mdx
@@ -1,170 +1,12 @@
---
title: Screen-share problems
-description: Black thumbnails, never appears, one-way streams, choppy video. A checklist.
-sidebar:
- order: 4
+description: Check client capture permissions and Starling's media relay address.
---
-import { Steps, Aside, Card, CardGrid } from '@astrojs/starlight/components';
+If the share does not start, first check the sender's operating-system capture permission and whether another app can capture the same window. On Linux, confirm the desktop portal is available for your session. Try sharing a different window to separate a capture failure from a transport failure.
-Screen sharing involves three moving parts. When something goes
-wrong, identify which one.
+If the sender sees a preview but viewers see a black frame or no stream, check the Starling screenshare service logs. The relay needs a public_url with a literal IP and UDP port reachable by viewers; the corresponding UDP listener must be open in the host and cloud firewalls. The [Starling example TOML](https://github.com/Fancy-Mumble/starling/blob/main/starling.example.toml) shows the setting. A private address or localhost will fail for remote viewers.
-1. **You** the broadcaster: your operating system has to grant
- screen-capture permission.
-2. **The server**: has to relay the stream to viewers (if the relay
- is enabled), or pass through the signaling for peer-to-peer.
-3. **The viewer**: has to reach the server's relay UDP port.
+The legacy C++ server's WEBRTCSFUPUBLICIP setting and fixed UDP port 10000 are not Starling settings. The active port comes from your Starling configuration.
-## "I cannot start a screen share"
-
-You picked a window or screen but the stream never starts.
-
-
-
-1. **Permission**. On macOS, screen capture requires explicit
- permission per app:
- - System Settings, Privacy & Security, Screen Recording, tick
- Fancy Mumble.
- - Quit and restart the app after granting.
-
-2. On Windows 10/11, no permission is required, but ensure
- **Background apps** are allowed to capture.
-
-3. On Linux (Wayland), the screen-share picker uses the portal API.
- Some Wayland compositors (Sway, KDE, GNOME) need a portal
- helper installed. Try `xdg-desktop-portal-wlr` on Sway.
-
-4. Your antivirus may block screen capture. Add the app to the
- allow list.
-
-
-
-## "Viewers see a black thumbnail"
-
-The most common screen-share problem. It means data is not
-reaching the viewer.
-
-
-
-1. (Server owner) Confirm the relay is **enabled**:
- ```yaml
- MUMBLE_CONFIG_WEBRTCSFUENABLED: true
- ```
-
-2. (Server owner) Confirm the **public IP** is right and reachable:
- ```yaml
- MUMBLE_CONFIG_WEBRTCSFUPUBLICIP: "203.0.113.5"
- ```
- It must be the address that **viewers** can reach. Not
- `0.0.0.0`, not the LAN IP of the server.
-
-3. (Server owner) Confirm **UDP 10000** is open in both the
- firewall and the router forwarder.
-
-4. (Viewer) Confirm UDP 10000 is not blocked by the viewer's
- firewall.
-
-
-
-If the relay is disabled, the app falls back to peer-to-peer, which
-fails behind strict NAT.
-
-## "Viewer sees the stream but it is choppy"
-
-Bandwidth is the limit. Each stream is ~1 to 2 Mbps for 720p.
-
-- The broadcaster's upload is too slow. Test with
- [fast.com](https://fast.com).
-- Many viewers are pulling from the relay on a slow link. Upgrade
- the relay host.
-- Try sharing **a single window** instead of the full desktop, the
- encoder gets a simpler frame.
-
-## "Stream works for some viewers but not others"
-
-Different viewer networks:
-
-- One viewer is behind a strict NAT, the others are not.
-- One viewer's ISP blocks UDP 10000. They can connect to the
- server but not to the relay.
-
-Workaround: on the affected viewer's side, ask them to test the
-relay port:
-
-```bash
-nc -uvz your-server 10000
-```
-
-If that fails, they need to talk to their ISP or use a different
-network.
-
-## "I cannot hear the streamed audio"
-
-The system-audio toggle was not checked when starting the share.
-
-- (Broadcaster) Stop the stream, re-start it, **tick "Also share
- system audio"** in the system picker.
-- On Linux, audio sharing only works with PipeWire. PulseAudio
- alone cannot route system audio to a tab.
-
-## "Whiteboard strokes do not show up"
-
-- The broadcaster has the **Whiteboard, draw** permission denied
- for their role. Check roles.
-
-## "Cannot pop the stream into its own window"
-
-- On some platforms (older Linux versions) the pop-out window may
- fail to start because of a graphics driver issue. Update graphics
- drivers and retry.
-
-## Server-side diagnosis
-
-(For server owners)
-
-Check the server logs for the relay:
-
-```bash
-docker compose logs -f mumble-server | grep webrtc-sfu
-```
-
-Look for:
-
-```text
-webrtc-sfu: listening on 0.0.0.0:10000/udp (public 203.0.113.5)
-```
-
-When a broadcaster connects:
-
-```text
-webrtc-sfu: new broadcaster session=42 channel=3
-```
-
-And per viewer:
-
-```text
-webrtc-sfu: new viewer session=43 broadcaster=42 ice-state=connected
-```
-
-If you see `ice-state=failed`, the viewer cannot reach the relay
-over UDP. That is the firewall problem above.
-
-## "The library is missing"
-
-Server log says `webrtc-sfu: library not found`. The relay was not
-compiled into your build. Either:
-
-- Use the official image (`ghcr.io/fancy-mumble/mumble-server:latest`),
- which includes the relay.
-- Rebuild your custom image with
- `--build-arg MUMBLE_CMAKE_ARGS="-Dwebrtc-sfu=ON"`.
-
-## Still broken?
-
-[Open a bug report](/troubleshooting/reporting-bugs/) with:
-
-- Whether the relay is enabled.
-- The public IP setting (redact the actual IP).
-- Server logs filtered to `webrtc-sfu`.
-- Whether the issue is for all viewers or only some.
+For diagnosis, record the client and server versions, whether the sender's local preview works, whether all viewers fail, and the relevant logs. See [Reporting bugs](/troubleshooting/reporting-bugs/).
diff --git a/src/content/docs/users/audio.mdx b/src/content/docs/users/audio.mdx
index d60e05e..d24f072 100644
--- a/src/content/docs/users/audio.mdx
+++ b/src/content/docs/users/audio.mdx
@@ -12,6 +12,10 @@ Audio is the number one thing people fiddle with in voice chat. This
page walks every control under **Settings, Voice**, what it does, when
to change it, and the trade-off.
+
+The screenshots and control positions below show Standard. Nebula is the default for new profiles and groups some settings differently; the underlying audio options are shared.
+
+
diff --git a/src/content/docs/users/chat.mdx b/src/content/docs/users/chat.mdx
index f7ab0b7..957aa66 100644
--- a/src/content/docs/users/chat.mdx
+++ b/src/content/docs/users/chat.mdx
@@ -11,15 +11,22 @@ import { Icon } from 'astro-icon/components';
The chat in Fancy Mumble is more than a plain text box. This page
walks every feature you will use day to day.
+## Example community conversation
-
- Screenshot placeholder: chat composer with formatting toolbar.
-
+This illustrative Nebula-style scene shows five sample members with different avatars, names, statuses, and interests. Rin's open profile also shows a banner, role, and bio.
+
+
+
+The [sample profiles](/users/profile/#try-a-sample-profile) include downloadable avatars and a distinct banner for each person. [Open the illustration at full size](/screenshot-users-chat-community.png), or [try the interactive community scene](/examples/community-scene.html) to select members and see their profiles.
## Formatting
Use the toolbar above the composer or markdown shortcuts:
+
+ Screenshot placeholder: chat composer with formatting toolbar.
+
+
| Effect | Markdown | Shortcut |
|--------|----------|----------|
| **Bold** | `**bold**` | `Ctrl+B` |
diff --git a/src/content/docs/users/live-doc.mdx b/src/content/docs/users/live-doc.mdx
index ac69ae2..afebcef 100644
--- a/src/content/docs/users/live-doc.mdx
+++ b/src/content/docs/users/live-doc.mdx
@@ -12,11 +12,8 @@ Mumble. Every member of a channel can open the same document and
see each other's edits as they happen, with colored cursors showing
who is where.
-
-Your server must be running the **live-doc plugin** (port 64740) and
-a **file-server plugin** (port 64739) for documents to open and
-persist. Ask your admin to check [Live Documents](/server/features/live-doc/)
-if the "Open Document" button does nothing after a few seconds.
+
+This client feature needs a compatible live-document server plugin. The checked-out Starling plugin-host porting plan still lists live-doc among the heavier plugins awaiting migration, so a new Starling deployment should not assume it is available. Ports 64740 and 64739 below describe the older C++ server deployment. Ask your admin which server and plugin versions are installed. See [Feature availability](/server/features/).
@@ -171,8 +168,9 @@ current channel.
## Pitfalls
- **"Open Document" does nothing after a few seconds**: the
- `FancyLiveDocInvite` reply never arrived. The live-doc plugin is
- probably not running or port 64740 is not reachable. Ask your admin.
+ `FancyLiveDocInvite` reply never arrived. Ask your admin whether a
+ compatible plugin is installed. On the older C++ server, also check
+ whether its live-doc listener is reachable.
- **Document resets on every open**: the file server or its persistence
bridge is not configured. Documents are kept in memory only; they
survive as long as at least one viewer is connected.
diff --git a/src/content/docs/users/personalization.mdx b/src/content/docs/users/personalization.mdx
index 37483b2..fd016db 100644
--- a/src/content/docs/users/personalization.mdx
+++ b/src/content/docs/users/personalization.mdx
@@ -7,10 +7,15 @@ sidebar:
import { Steps, Aside, Tabs, TabItem, Card, CardGrid } from '@astrojs/starlight/components';
import { Icon } from 'astro-icon/components';
+import ChatBackgroundExample from '../../../components/ChatBackgroundExample.astro';
Open **Settings, Personalize** to change how the app looks. None of
these settings touch what other people see, they are purely your own.
+
+Nebula is the default for new profiles and has its own skins and layout settings. Standard remains available and keeps the classic glass look; existing profiles retain it. Aurora is deprecated. Switch designs under Settings, Personalization, Interface design. The theme and channel-viewer options below describe Standard and can differ in Nebula.
+
+
@@ -61,13 +66,16 @@ Three looks for individual chat messages:
## Chat background
-Drop an image or pick a color to set the background of the chat
-column.
+Use an image behind the chat column. The sample below shows how a dark
+overlay keeps messages readable over an illustrated wallpaper.
+
+
+
+[Download the sample chat background](/examples/sample-chat-background.png) to try it yourself. In Nebula, open **Settings, Personalize, Chat Background** and choose the image file. You can select it again from the recent-background tiles. Drag the focus point to control which part stays visible when the chat pane crops the image.
+
+Nebula has **Blur**, **Opacity**, and **Dim** controls. Start with a low opacity or a stronger dim setting, then adjust until messages remain easy to read. Standard also offers these controls and a **Cover** or **Tile** fit choice.
-- **Fit**: pick **Cover** (fills, may crop) or **Tile** (repeats).
-- **Dim**: darken the image so text stays readable. 0 to 100%.
-- **Blur**: blur the image. The blur is calculated in the backend,
- so very large values may take a moment to re-process.
+**Dim** darkens the image; **Opacity** controls how strongly it shows through. **Blur** softens detail and can take a moment to process at high values.
The original image is stored locally and re-processed when you
diff --git a/src/content/docs/users/profile.mdx b/src/content/docs/users/profile.mdx
index 7d63090..124ad2f 100644
--- a/src/content/docs/users/profile.mdx
+++ b/src/content/docs/users/profile.mdx
@@ -7,12 +7,27 @@ sidebar:
import { Steps, Aside, Tabs, TabItem, Card, CardGrid, Badge } from '@astrojs/starlight/components';
import { Icon } from 'astro-icon/components';
+import ProfileExample from '../../../components/ProfileExample.astro';
Your **profile** is what others see when they click your name in the
sidebar. Fancy Mumble lets you make it look the way you want.
Open it from **Settings, Profile**.
+
+The older settings screenshots below show Standard. Nebula, the default for new profiles, places **Edit** under Avatar and **Image** under Banner. Both open a crop editor and update the live profile preview.
+
+
+## Try a sample profile
+
+Pick from eight original sample themes—cats, dogs, cars, anime, manga, K-pop, comics, and flowers—to see an avatar and matching banner together. Anime has three distinct looks: vivid pop, clean visual novel, and flat cartoon demon.
+
+
+
+Use the **Avatar** and **Banner** download links under any profile to try a matching pair in your own profile. In Nebula, open **Settings, Profile**, choose **Edit** under Avatar and **Image** under Banner, then adjust each crop in the editor. These files are examples; you can replace them with your own images.
+
+The [example community conversation](/users/chat/#example-community-conversation) shows several members using different avatars, names, statuses, and bios together.
+
@@ -58,6 +73,8 @@ Open it from **Settings, Profile**.
## Step by step: change your avatar
+The following steps use Standard's labels. In Nebula, choose **Edit** under Avatar and confirm the crop in the image editor.
+
1. Open **Settings, Profile**.
@@ -83,6 +100,8 @@ Open it from **Settings, Profile**.
The banner sits **above** your profile card.
+In Nebula, choose **Image** under Banner to upload and crop a picture. You can also choose a solid banner color. Standard uses the following flow:
+
1. **Settings, Profile, Edit banner**.
2. Drop an image, or pick a **preset gradient**.
@@ -169,9 +188,9 @@ profile is copied into each. You can then edit each one independently.
| Field | Limit |
|-------|-------|
| Bio | 2000 characters |
-| Avatar | 256x256, around 80 KB after compression |
+| Avatar crop in Nebula | 128x128, up to 100 KB after compression |
| Inline bio image | 400x400, around 80 KB |
-| Banner | up to about 1 MB |
+| Banner crop in Nebula | 400x150, up to 80 KB after compression |
## Troubleshooting
diff --git a/src/content/docs/welcome/glossary.mdx b/src/content/docs/welcome/glossary.mdx
index 88d99aa..494dcbc 100644
--- a/src/content/docs/welcome/glossary.mdx
+++ b/src/content/docs/welcome/glossary.mdx
@@ -16,15 +16,16 @@ import { Aside } from '@astrojs/starlight/components';
**Channel** A folder-like room for users and chat history. Channels can nest.
**Custom emote** An image uploaded by a server admin that everyone in the server can use in chat as a shortcode, like `:partyparrot:`.
**Deafened** You can neither send nor hear audio. Implies muted.
-**File server** The part of a Fancy Mumble server that stores avatar uploads, custom emotes, and shared files. Runs on port 64739 by default.
+**Files service** Starling's upload and download service. The shipped Compose deployment publishes its HTTP listener on port 8080.
**Frame** Decorative ring around your avatar. See [Profile customization](/users/profile/).
**Group** A named bundle of users used inside ACLs. Groups can be inherited across channels.
**Identity** A combination of your default username and a saved certificate. You can have separate identities for separate servers or communities.
-**Mumble server** also called Murmur The program that everyone connects to. Fancy Mumble adds extra features on top.
+**Mumble server** The server a Mumble client connects to. Murmur is the classic server; Starling is Fancy Mumble's current server.
+**Starling** Fancy Mumble's current Rust server, made of a gateway and separate feature services. See [Run a server](/server/docker/).
**Nameplate** A gradient background behind your name in user lists.
**Onboarding** A few questions the server asks new members at join time. Their answers decide which channels they end up in and which roles they get. See [Onboarding workflow](/admin/onboarding/).
**Opus** The audio format Mumble uses. Open, low-latency, excellent quality.
-**Persistent chat** Chat that stays on the server (encrypted), so you see the conversation history when you reconnect.
+**Persistent chat** Chat history that remains available after a reconnect. Storage and encryption depend on the channel policy and server configuration.
**PTT** Push-to-Talk Voice transmits only while a key is held.
**Reaction** An emoji attached to a chat message.
**Register** Tell the server "this certificate belongs to this username", so the same name always maps to the same person.
@@ -38,6 +39,6 @@ import { Aside } from '@astrojs/starlight/components';
-Do not see a term? [Open an issue](https://github.com/Fancy-Mumble/FancyMumbleNext/issues)
+Do not see a term? [Open an issue](https://github.com/Fancy-Mumble/FancyMumble/issues)
and we will add it.
diff --git a/src/content/docs/welcome/intro.mdx b/src/content/docs/welcome/intro.mdx
index 9d3d00d..8a3e0de 100644
--- a/src/content/docs/welcome/intro.mdx
+++ b/src/content/docs/welcome/intro.mdx
@@ -1,136 +1,20 @@
---
title: What is Fancy Mumble?
-description: An overview of Fancy Mumble, what makes it different, and who it is for.
-sidebar:
- order: 1
+description: The client, Starling server, compatibility, and feature availability.
---
-import { Aside, Steps, Badge, Tabs, TabItem } from '@astrojs/starlight/components';
-import PlantUML from '../../../components/PlantUML.astro';
+Fancy Mumble is a voice chat app for Windows, Linux, and Android. It uses the Mumble protocol for voice and control, with chat, profiles, screen sharing, and other features in the client.
-Fancy Mumble is a **voice chat program** for gaming, podcasts, study
-groups, and online communities. You install the app, connect to a
-server, and talk. Chat, screen sharing, file sharing, and much more is
-built in.
+The current server is [Starling](https://github.com/Fancy-Mumble/starling), a Rust implementation with a gateway and separate services for voice, chat, files, and more. The earlier [C++ server fork](https://github.com/Fancy-Mumble/mumble-server) and its Docker image remain relevant to existing deployments.
-It is based on Mumble, an open-source voice chat program that has been
-around for over a decade, so the call quality and reliability are
-already excellent. Fancy Mumble adds a modern look, a smoother first-run
-experience, and a handful of features you would expect from a 2026 app.
+The client can connect to a standard Mumble server for voice and basic text chat. Fancy features depend on what the server advertises and on its configuration. Some also need a plugin or a reachable media service. See [Feature availability](/server/features/) before planning a deployment around a particular feature.
-
-Fancy Mumble is an independent project and is not affiliated with, endorsed by, or in any way connected to the official [Mumble project](https://www.mumble.info/) or its developers. "Mumble" is used solely to describe protocol and server compatibility.
-
+A new client profile opens in **Nebula**. Standard remains available, and existing profiles that used Standard keep it. Aurora is deprecated. Screens and menu names in this site may differ slightly between designs.
-
-The Fancy Mumble app can connect to any standard Mumble server. You
-just will not see the extra features (saved chat history, smooth screen
-sharing, file uploads, custom server emotes, push notifications) unless
-the server runs Fancy Mumble too.
-
+## Start here
-## What is new compared to classic Mumble
+- [Install the app](/getting-started/install/) and [connect to a server](/getting-started/connect/).
+- [Run Starling with Docker](/server/docker/) or use a [release package](https://github.com/Fancy-Mumble/starling/releases/latest).
+- [Configure Starling](/server/config/) and check [ports](/server/network/).
-
-
-- **Chat that survives disconnects.** Open the app the next day and
- the conversation is still there (encrypted on the server).
-- **Smooth screen sharing.** One person streams, the server fans it
- out to everyone, no peer-to-peer headaches.
-- **A whiteboard on top of any stream.** Point, draw, annotate.
-- **Watch a video together** in sync.
-- **Reactions and polls** on chat messages.
-- **Custom server emotes.** Admins can upload images and use them as
- emoji.
-- **Live collaborative documents.** Any channel can have a shared rich-text
- document that multiple people edit at the same time, with real-time cursors.
-- **File sharing** with control over who can download, for how long.
-- **Server-rendered link previews** so links look like links.
-- **Push notifications** on Android.
-- **Join-time onboarding** so new members are dropped into the right
- channels with the right roles.
-- **Profile customization** including avatars, banners, name styles,
- glow effects, and animated frames.
-
-## Who it is for
-
-
-
- Someone gave you a server address. Install the app and connect.
- Start at [Install Fancy Mumble](/getting-started/install/).
-
-
- You want to host your own server for your community. Start at the
- [Docker quick start](/server/docker/).
-
-
- A server already exists and you are the admin. Start at
- [SuperUser & first login](/admin/superuser/) and then
- [Roles & permissions](/admin/roles/).
-
-
-
-## How the pieces talk to each other
-
-You do not need to memorize this, but if you ever need to ask your
-network admin to open a port, this is what the traffic looks like:
-
- Voice : TCP/UDP 64738 direct
-App --> RP : HTTPS 443 HTTP traffic
-RP --> FS : HTTP 64739
-RP --> LiveDoc : WS 64740
-App ..> SFU : UDP 10000 screen share\\n//(direct, bypasses proxy)//
-App ..> LiveDoc : WS 64740 live doc\\n//(direct, LAN only)//
-Push ..> FCM : push event
-@enduml
-`} />
-
-
-Default ports: **64738** for voice and control, **64739** for the
-file server, **64740** for live documents, **10000** for screen
-sharing. Full reference on the [Ports & protocols](/reference/ports/) page.
-
-
-## Where to go next
-
-
-
-1. Take the [60-second UI tour](/welcome/tour/), see what every panel does.
-2. [Install the app](/getting-started/install/) for your platform.
-3. If you do not yet have a server to connect to, follow the
- [Docker quick start](/server/docker/) to spin up your own.
-4. Tune your mic with [Audio configuration](/users/audio/), the most
- common cause of "I cannot hear you" complaints.
-
-
+Fancy Mumble is independent of the official [Mumble project](https://www.mumble.info/). Mumble names here refer to protocol compatibility.
diff --git a/src/content/docs/welcome/tour.mdx b/src/content/docs/welcome/tour.mdx
index 121199d..ab59e79 100644
--- a/src/content/docs/welcome/tour.mdx
+++ b/src/content/docs/welcome/tour.mdx
@@ -7,6 +7,10 @@ sidebar:
import { Aside, Steps } from '@astrojs/starlight/components';
+
+New profiles open in Nebula. This tour and its screenshots follow the Standard design; some controls have different names or positions in Nebula. Existing Standard profiles keep their choice. Aurora is deprecated.
+
+
This is the **main chat view** once you are connected. Three columns,
each doing one job.