A modern web-based administration interface for Mumble (Murmur) voice servers
Manage your Mumble servers, channels, and users from any browser β no command-line access required.
Features β’ Tech Stack β’ Quick Start β’ Configuration β’ Development β’ Security β’ License
| Feature | Description |
|---|---|
| π₯οΈ Virtual Server Admin | View, start, stop, and configure Murmur virtual servers |
| π² Channel Tree Editor | Browse, create, rename, move, and delete channels live |
| π Channel Templates | Save channel layouts and apply them to any server in one click |
| π SSH Host Management | Reach remote Mumble servers safely through SSH tunnels |
| π₯ User Management | Create, promote, demote, reset passwords, and delete app accounts |
| π‘ Real-Time Status | SignalR-powered live connection state β no polling |
| π§ Email Notifications | HTML email on account events and fatal errors (optional) |
| π JWT Authentication | Stateless token auth with 8-hour expiry and per-browser session isolation |
| π Swagger UI | Full OpenAPI docs available in Development mode |
|
Backend
|
Frontend
Infrastructure
|
Browser (HTTPS / WSS)
β
βΌ
ββββββββββββββββββββββββ
β Nginx :443 β β TLS termination, HTTPβHTTPS redirect
ββββββββββββ¬ββββββββββββ
β HTTP :5000
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ASP.NET Core β MumbleManager.Api β
β β
β REST endpoints ββ JWT middleware β
β SignalR hub (/hubs/status) β
β Static files (compiled React SPA) β
β β
β βββββββββββββββ ββββββββββββββββββββββββββββββββ β
β β SQLite DB β β SSH Tunnel β Murmur ICE β β
β β (EF Core) β β (ZeroC ICE 3.7, port 6502) β β
β βββββββββββββββ ββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
The React SPA is compiled at Docker build time and served as static files by the .NET process β there is no separate Node server in production.
- Linux VPS running Ubuntu 22.04+
- A domain name pointed at your server's IP
- Ports 80 and 443 open in your firewall
- A running Murmur server with ZeroC ICE enabled (see Enabling ICE)
git clone https://github.com/YOUR_USERNAME/mumblemanager.git
cd mumblemanagersudo apt install certbot
# Stop anything on port 80 first, then:
sudo certbot certonly --standalone -d your.domain.com
# Place certificates where Nginx expects them:
cp /etc/letsencrypt/live/your.domain.com/fullchain.pem nginx/certs/fullchain.pem
cp /etc/letsencrypt/live/your.domain.com/privkey.pem nginx/certs/privkey.pem
chmod 600 nginx/certs/privkey.pemcp .env.example .env
nano .env # Fill in your domain, JWT secret, and email settingsEdit nginx/nginx.conf β replace both occurrences of YOUR_DOMAIN.com with your actual domain.
Edit docker-compose.yml and replace all YOUR_* placeholders.
chmod +x deploy.sh
sudo ./deploy.shdeploy.sh will install Docker (if needed), build the image, start the stack, and confirm a healthy start. Your app will be live at https://your.domain.com. π
docker compose build
docker compose up -d
docker compose logs -fAll configuration is passed as environment variables to the app container.
| Variable | Required | Description |
|---|---|---|
Jwt__Secret |
β | JWT signing key β minimum 32 random characters. Generate: openssl rand -base64 48 |
AllowedOrigins |
β | Comma-separated CORS origins, e.g. https://your.domain.com |
ConnectionStrings__Default |
β | SQLite path. Default: Data Source=/data/mumblemanager.db |
Email__SmtpHost |
β | SMTP server. Default: smtp.gmail.com |
Email__SmtpPort |
β | SMTP port (STARTTLS). Default: 587 |
Email__From |
β | Sender email address |
Email__FromName |
β | Sender display name. Default: MumbleManager |
Email__AppPassword |
β | Gmail App Password. Email is silently disabled when empty. |
Email__AdminAddress |
β | Address for admin notifications |
ASPNETCORE_ENVIRONMENT |
β | Set to Development to enable Swagger at /swagger |
π‘ Gmail App Password: Enable 2-Factor Authentication on your Google account, then generate an App Password at myaccount.google.com/apppasswords.
On first start, MumbleManager seeds an admin account automatically.
Default credentials β change these immediately:
Field Value Username adminPassword (value set in DbSeeder.csbefore building)
After logging in, use User Management to create additional users and change the admin password via Change Password.
- Click Add Host in the Hosts panel
- Enter your SSH host details and the ICE Secret from your
murmur.ini - Click Connect β MumbleManager opens an SSH tunnel and connects via ICE
In murmur.ini (or mumble-server.ini):
ice=tcp -h 127.0.0.1 -p 6502
icesecretread=YOUR_ICE_SECRET
icesecretwrite=YOUR_ICE_SECRETRestart Murmur after saving. MumbleManager connects through the SSH tunnel, so Murmur's ICE port never needs to be exposed publicly.
cd backend
dotnet restore
ASPNETCORE_ENVIRONMENT=Development \
Jwt__Secret="dev-secret-key-at-least-32-characters!!" \
dotnet run
# API + Swagger at http://localhost:5000cd frontend
npm install
npm run dev
# Vite dev server at http://localhost:5173
# Proxies /api and /hubs β http://localhost:5000 automaticallycd backend
dotnet tool install --global dotnet-ef # first time only
dotnet ef migrations add YourMigrationNameSchema is applied automatically on startup via DbSeeder.SeedAsync().
mumblemanager/
βββ backend/
β βββ Data/ # EF Core DbContext + migrations
β βββ Endpoints/ # Minimal API route handlers
β β βββ AuthEndpoints.cs
β β βββ ChannelEndpoints.cs
β β βββ ConnectionEndpoints.cs
β β βββ HostEndpoints.cs
β β βββ ServerEndpoints.cs
β β βββ TemplateEndpoints.cs
β β βββ UserEndpoints.cs
β βββ Generated/ # Auto-generated ZeroC ICE bindings
β βββ Hubs/StatusHub.cs # SignalR real-time hub
β βββ Models/ # EF entities + DTOs
β βββ Services/
β β βββ AuthService.cs # PBKDF2 hashing + JWT generation
β β βββ DbSeeder.cs # Seeds initial admin account
β β βββ EmailService.cs # SMTP via MailKit
β β βββ HostSession.cs # Per-user ICE session registry
β β βββ MumbleServerIceService.cs
β β βββ MurmurLegacyIceService.cs
β β βββ SshTunnelService.cs # SSH port forwarding
β β βββ MurmurVersion.cs # Auto version detection
β βββ appsettings.json
β βββ Program.cs
β
βββ frontend/src/
β βββ api/index.ts # Typed API client
β βββ components/ # React UI components
β βββ hooks/useSignalR.ts # SignalR connection hook
β βββ store/ # Zustand global state
β βββ types/index.ts # Shared TypeScript types
β
βββ nginx/
β βββ nginx.conf # Reverse proxy + TLS config
β βββ certs/ # TLS certificates (gitignored)
β
βββ .env.example # Environment variable template
βββ Dockerfile # Multi-stage build
βββ docker-compose.yml
βββ deploy.sh # One-shot Ubuntu deployment
βββ README.md
β οΈ Please read before deploying to production.
- Change the default admin password immediately after first login
- Generate a strong JWT secret β at minimum 48 random bytes:
openssl rand -base64 48 - Never commit
nginx/certs/or your.envfile β both are gitignored - SSH credentials are stored in the SQLite database; protect
/data/mumblemanager.dbwith appropriate filesystem permissions - Passwords are hashed with PBKDF2 / SHA-256, 100,000 iterations, random 16-byte salt
- The .NET container is not exposed directly to the internet β all traffic passes through Nginx
Pull requests are welcome! For major changes, please open an issue first to discuss what you'd like to change.
- Fork the repository
- Create a feature branch:
git checkout -b feature/your-feature - Commit your changes:
git commit -m 'Add some feature' - Push to the branch:
git push origin feature/your-feature - Open a Pull Request
Copyright Β© 2026 Gerald Hull, W1VE
Released under the MIT License β see the LICENSE file for details.


