-
Notifications
You must be signed in to change notification settings - Fork 84
configuration
Muximux is configured via a single YAML file. By default, this is data/config.yaml (inside the data directory). The data directory defaults to data/ relative to the binary's location and can be changed with --data or MUXIMUX_DATA. You can also override the config path directly:
# Change the data directory (config will be at /opt/muximux/data/config.yaml)
muximux --data /opt/muximux/data
# Or override the config path explicitly
muximux --config /path/to/config.yaml# ─── Server ─────────────────────────────────────
server:
listen: ":8080" # Listen address (default: ":8080")
title: "Muximux" # Page title shown in browser tab
log_level: info # Log verbosity: debug, info, warn, error
log_format: text # Log output format: text or json
proxy_timeout: 30s # Global timeout for proxied requests
base_path: "" # Subpath for reverse proxy (e.g. "/muximux")
# Optional: TLS / HTTPS
tls:
domain: "" # Auto-HTTPS domain (requires email)
email: "" # Let's Encrypt registration email
cert: "" # Path to TLS certificate PEM
key: "" # Path to TLS private key PEM
# Replaced by `gateway_sites:` below. If you're upgrading from
# 3.0.x and still have this set, Muximux converts it to
# `gateway_sites:` on first boot and saves backups of both the
# original `config.yaml` and your Caddyfile alongside them.
gateway: "" # legacy
# Optional: Override the bind address for the embedded Caddy that
# serves gateway sites. Useful when (a) you don't want to grant
# CAP_NET_BIND_SERVICE / run as root, or (b) an upstream proxy
# terminates TLS and you want Caddy on a high port behind it.
# When set, gateway sites are emitted with http://<domain>:<port>
# and auto-https is disabled. Empty = legacy behaviour (:80/:443).
gateway_listen: "" # e.g. ":8443"
# Optional: cookie scope for cross-subdomain session sharing.
# Required when any entry in gateway_sites has require_auth=true,
# otherwise the session cookie won't reach the gated subdomain.
# Leading dot is optional (browsers normalise).
session_cookie_domain: "" # e.g. ".example.com"
# Optional: declarative gateway sites served by the embedded Caddy.
# See the Gateway Examples and Gateway Auth Gate wiki pages for the
# full reference. Each entry can optionally gate access behind the
# Muximux session via require_auth + min_role + allowed_groups.
gateway_sites:
- domain: sonarr.example.com # required
backend_url: http://192.168.1.5:8989 # required
tls: auto # auto | none | custom
tls_cert: "" # required when tls=custom
tls_key: "" # required when tls=custom
streaming: false # disable Caddy response buffering for live data
strip_frame_blockers: true # strip X-Frame-Options for iframe embedding
forwarded_headers: true # forward X-Forwarded-Proto/Host/Real-IP
proxy_headers: {} # extra headers injected on upstream requests
# Optional: also surface this site in the dashboard menu
app_name: "" # link to an existing app by name
# Gateway auth gate (3.1.0+) -- gate this subdomain behind Muximux login
require_auth: false # 302 anonymous visitors to /login first
min_role: "" # "user" / "power-user" / "admin"; empty = any signed-in user
allowed_groups: [] # case-insensitive; admins bypass
# Auto-populated by Docker discovery on import; do not hand-edit.
# Presence of docker_key locks backend_url to the refresh poller.
docker_key: ""
docker_endpoint: ""
docker_strategy: ""
# ─── Authentication ─────────────────────────────
auth:
method: none # none, builtin, forward_auth, oidc
setup_complete: false # Set automatically after onboarding wizard completes
session_max_age: 24h # Session duration (default: 24h)
secure_cookies: false # Require HTTPS for session cookies
api_key_hash: "" # Optional bcrypt hash of API key for X-Api-Key auth
# Builtin auth users
users:
- username: ""
password_hash: "" # bcrypt hash (see Authentication page)
role: admin # admin, power-user, or user
email: "" # Optional
display_name: "" # Optional
# Forward auth settings
trusted_proxies: [] # CIDR ranges, e.g., ["192.168.0.0/16"]
headers:
user: Remote-User
email: Remote-Email
groups: Remote-Groups
name: Remote-Name # Note: key is "name" not "display_name"
logout_url: "" # Auth provider logout URL (e.g., https://auth.example.com/logout)
# OIDC settings
oidc:
enabled: false
issuer_url: ""
client_id: ""
client_secret: "" # Supports ${ENV_VAR} syntax
redirect_url: "" # Must match provider callback URL
scopes: [openid, profile, email]
username_claim: preferred_username
email_claim: email
groups_claim: groups
display_name_claim: name
admin_groups: [] # Groups that grant admin role
# ─── Theme ─────────────────────────────────────
theme:
family: default # Theme family: default, nord, dracula, etc.
variant: system # dark, light, system (follow OS preference)
# ─── Navigation ─────────────────────────────────
navigation:
position: top # top, left, right, bottom, floating
width: 220px # Sidebar width
auto_hide: false
auto_hide_delay: 0.5s
show_on_hover: true
show_labels: true
show_logo: true
show_app_colors: true
show_icon_background: false
show_splash_on_startup: false
show_shadow: true
icon_scale: 1.0 # Icon zoom multiplier
bar_style: grouped # grouped or flat (top/bottom bars only)
floating_position: bottom-right # bottom-right, bottom-left, top-right, top-left
hide_sidebar_footer: false # Hide the footer section in sidebars
max_open_tabs: 0 # Max app tabs kept alive in memory (0 = unlimited)
# ─── Icons ──────────────────────────────────────
icons:
dashboard_icons:
cache_dir: icons/dashboard # Where fetched dashboard icons are cached
cache_ttl: 7d # How long a cached icon is reused before refetch
# ─── Health Monitoring ──────────────────────────
health:
enabled: true
interval: 30s
timeout: 5s
# ─── Docker Discovery (optional, opt-in) ───────
# Connect to a Docker daemon to discover running
# containers and keep their URLs current. See the
# Docker Discovery wiki page for the full guide.
discovery:
docker:
enabled: false # opt-in; requires socket access
endpoint: unix:///var/run/docker.sock # or tcp://host:2376
network_strategy: container_ip # container_ip | container_dns | host_port | host_docker_internal
network_filter: "" # scope scans to one docker network when set
host_ip: "" # required by host_port strategy
refresh_interval: 60s # poller cadence
auto_import: off # off (default) | add | update | sync; auto-import muximux.*-labeled containers
lifecycle_enabled: false # allow start/stop/restart of tracked containers (requires :rw socket mount)
lifecycle_min_role: admin # min role for lifecycle controls
lifecycle_allowed_groups: [] # additionally require group membership
health_badge_placement: overview # overview | overview_and_nav | off
tls: # only needed for tcp:// with mTLS
enabled: false
ca_cert: "" # CA bundle that signed the daemon cert
client_cert: "" # client certificate (PEM)
client_key: "" # client key (PEM, chmod 600)
# ─── Keyboard Shortcuts ────────────────────────
keybindings:
bindings: {} # Custom overrides only; defaults managed client-side
# ─── Groups ─────────────────────────────────────
groups:
- name: Media
icon:
type: lucide
name: play
color: "#e5a00d"
order: 1
expanded: true
# ─── Apps ───────────────────────────────────────
apps:
- name: Plex
url: http://plex:32400
# health_url: http://plex:32400/web # Optional custom health endpoint
icon:
type: dashboard
name: plex
# variant: light # Icon variant (dashboard icons only)
# file: healarr # Filename in data/icons/ (type: custom only)
# url: https://example.com/icon.png # Remote image URL (type: url only)
# color: "#ff0000" # Tint color (Lucide only)
# background: "#1a1a2e" # Icon background override
# invert: false # Invert icon colors (dark ↔ light)
color: "#e5a00d"
group: Media
order: 1
enabled: true
default: true
open_mode: iframe # iframe, new_tab, new_window, redirect, http_action
proxy: false
proxy_skip_tls_verify: true # Skip TLS certificate verification (default: true)
proxy_headers: # Custom headers sent to the backend
X-Custom-Header: value
scale: 1.0
health_check: true # Opt-in: set true to enable health monitoring for this app
shortcut: null # Assign a number key (1-9) for quick switching
min_role: "" # Minimum role to see this app (user, power-user, admin)
force_icon_background: false # Show icon background even when global setting is off
auth_bypass: []
access:
roles: []
users: []muximux [flags]
--data PATH Base data directory (default: data/ beside binary, env: MUXIMUX_DATA)
--config PATH Override config file path (default: <data>/config.yaml, env: MUXIMUX_CONFIG)
--listen ADDR Override listen address (env: MUXIMUX_LISTEN)
--base-path PATH Subpath for reverse proxy (e.g. /muximux, env: MUXIMUX_BASE_PATH)
--version Show version and exit
Precedence: CLI flag > environment variable > config file value > default.
Use ${VARIABLE_NAME} in any string value to reference environment variables. This is useful for keeping secrets out of config files:
auth:
oidc:
client_secret: ${OIDC_CLIENT_SECRET}
api_key_hash: ${MUXIMUX_API_KEY_HASH}
apps:
- name: Plex
url: ${PLEX_URL}If the referenced environment variable is not set, the ${VAR} reference is left as-is (the literal string is preserved). This avoids silently deleting values when an env var is missing.
These override the corresponding config file values without needing ${VAR} syntax in config.yaml:
| Variable | Description | Default |
|---|---|---|
MUXIMUX_DATA |
Base data directory |
data/ beside binary |
MUXIMUX_CONFIG |
Override config file path | <data>/config.yaml |
MUXIMUX_LISTEN |
Listen address (e.g., :9090) |
From config file |
MUXIMUX_BASE_PATH |
Subpath for reverse proxy (e.g., /muximux) |
Empty (root) |
MUXIMUX_LOG_LEVEL |
Log verbosity (debug, info, warn, error) | From config file |
MUXIMUX_LOG_FORMAT |
Log format (text or json) |
text |
Muximux validates the configuration on startup and will refuse to start if the configuration is invalid. The following rules are enforced:
- If
tls.domainis set,tls.emailis required (for Let's Encrypt registration). -
tls.certandtls.keymust both be set or both empty. You cannot provide only one. -
tls.domainandtls.certare mutually exclusive. Use either auto-HTTPS or manual certificates, not both. - Legacy
gateway:(Caddyfile path) configs from 3.0.x are auto-migrated togateway_sites:on first boot under 3.1.0 (clean conversions only; lossy ones surface a hard error pointing atmuximux migrate-gateway). - If any
gateway_sites[]entry hasrequire_auth: true,server.session_cookie_domainis required and every gated site must be a subdomain of it (real host-suffix check:evilexample.comis not a subdomain ofexample.com). -
gateway_sites[].min_rolemust be one ofuser,power-user,adminwhen set (empty means "any authenticated user"). -
server.gateway_listenmust be a valid bind address (e.g.,:8443or127.0.0.1:8443).
Most settings can be changed through the Settings panel while Muximux is running. Changes are saved to data/config.yaml immediately and take effect without restarting.
The following settings require a restart to take effect:
-
server.listen(listen address/port) -
server.base_path(subpath prefix) -
server.tls.*(all TLS settings) -
server.gateway_listen(overrides the bind port for the embedded Caddy) -
server.session_cookie_domain(cookie scope; takes effect on next login) -
server.gateway_sites:schema changes (the auth gate; backend swaps and TLS-mode flips reload Caddy in place)
Everything else -- navigation, themes, apps, groups, icons, keybindings, health monitoring, log level, log format -- is applied immediately.
You can export your configuration as a downloadable YAML file and import it on another instance:
- Export strips sensitive data (password hashes, OIDC secrets, API key hashes) before download.
- Import parses the uploaded YAML, validates it, and shows a preview so you can review before applying.
This is available in the Settings panel under the General tab, or via the API (see API Reference).
The configuration can also be read and updated via the API:
-
GET /api/config-- Retrieve the current configuration (any authenticated user). -
PUT /api/config-- Update the full configuration (admin role required). -
GET /api/appearance-- Read-only snapshot of language, theme id, and theme colors, for embedded apps that want to sync their own appearance (see Apps > Appearance API).
See the API Reference for details.
Getting Started
Features
- Apps
- HTTP Actions
- Reverse Proxy
- Docker Discovery
- Navigation
- Split View
- Themes
- Keyboard Shortcuts
- Health Monitoring
- Icons
- Translations
Security
Identity provider guides
Operations