Skip to content

Configuration

HoloMUSH is configured through a two-layer system: a YAML config file for persistent settings and CLI flags for per-run overrides. This page is the complete reference for both layers — flags, environment variables, file locations, and a full annotated config example. For plugin-specific configuration, see Plugin metrics and the plugin’s own plugin.yaml.

CommandDescription
holomush coreStart the core process
holomush gatewayStart the gateway process
holomush migrate <cmd>Database migration management (up, down, status, version, force)
holomush statusCheck health of core and gateway
holomush --helpShow available commands

The core process runs the game engine and plugin runtime.

Terminal window
holomush core [flags]
FlagDefaultDescription
--grpc-addrlocalhost:9000gRPC listen address for gateway
--control-addr127.0.0.1:9001Control plane gRPC address (mTLS)
--metrics-addr127.0.0.1:9100Metrics and health HTTP endpoint
--data-dirXDG_DATA_HOMEDirectory for runtime data
--game-idAuto-generatedUnique game instance identifier
--log-formatjsonLog format: json or text
--skip-seed-migrationsfalseDisable automatic seed policy upgrades
--configXDG defaultPath to YAML config file

Example:

Terminal window
holomush core \
--grpc-addr=0.0.0.0:9000 \
--control-addr=0.0.0.0:9001 \
--metrics-addr=0.0.0.0:9100 \
--log-format=text

The gateway process handles telnet and web client connections.

Terminal window
holomush gateway [flags]
FlagDefaultDescription
--telnet-addr:4201Telnet server listen address
--web-addr:8080Web client HTTP server listen address
--web-dir(embedded)Override embedded static files with a directory
--cors-origins(none)Allowed CORS origins for cross-origin requests
--core-addrlocalhost:9000Core gRPC server address
--control-addr127.0.0.1:9002Control plane gRPC address (mTLS)
--metrics-addr127.0.0.1:9101Metrics and health HTTP endpoint
--log-formatjsonLog format: json or text
--configXDG defaultPath to YAML config file

Example:

Terminal window
holomush gateway \
--telnet-addr=:4201 \
--core-addr=core.internal:9000 \
--metrics-addr=0.0.0.0:9101 \
--log-format=json

The migrate commands manage database schema migrations.

Terminal window
# Apply all pending migrations
holomush migrate up
# Apply migrations in dry-run mode (shows what would be applied)
holomush migrate up --dry-run
# Rollback one migration
holomush migrate down
# Rollback all migrations
holomush migrate down --all
# Show current migration status
holomush migrate status
# Show current version only
holomush migrate version
# Force set version (for dirty state recovery)
holomush migrate force <version>

All migrate commands require DATABASE_URL environment variable.

VariableRequiredDescription
DATABASE_URLCore, MigratePostgreSQL connection string
XDG_CONFIG_HOMENoConfiguration directory (default: ~/.config)
XDG_DATA_HOMENoData directory (default: ~/.local/share)
XDG_STATE_HOMENoState directory (default: ~/.local/state)

PostgreSQL connection string format:

postgres://user:password@host:port/database?sslmode=mode

SSL Modes:

ModeDescription
disableNo SSL (development only)
requireSSL required, no certificate check
verify-caSSL with CA certificate verification
verify-fullSSL with full hostname verification

Examples:

Terminal window
# Local development
DATABASE_URL="postgres://holomush:secret@localhost:5432/holomush?sslmode=disable"
# Production with SSL
DATABASE_URL="postgres://holomush:${DB_PASSWORD}@db.example.com:5432/holomush?sslmode=verify-full"

HoloMUSH follows the XDG Base Directory Specification.

DirectoryPurpose
~/.config/holomush/Configuration files, TLS certs
~/.local/share/holomush/Persistent data
~/.local/state/holomush/Runtime state, logs, PID files

On first startup, core automatically creates:

FileDescription
~/.config/holomush/certs/ca.pemCertificate authority
~/.config/holomush/certs/core.pemCore server certificate
~/.config/holomush/certs/core-key.pemCore server private key
~/.config/holomush/config.yamlServer configuration

HoloMUSH generates a self-signed CA on first startup for mTLS between core and gateway. If you’d prefer to use your own CA (for example, an internal PKI or a CA managed by your infrastructure tooling), replace the generated files before starting the server:

  1. Place your CA certificate at ~/.config/holomush/certs/ca.pem
  2. Issue a server certificate signed by your CA and place it at ~/.config/holomush/certs/core.pem with its key at core-key.pem
  3. The certificate’s Subject Alternative Name (SAN) must include the game_id value — gateway validates this on connection

If the cert files already exist at startup, core will use them instead of generating new ones.

Pass configuration via environment variables:

services:
core:
image: ghcr.io/holomush/holomush:latest
command: ["core", "--grpc-addr=0.0.0.0:9000"]
environment:
DATABASE_URL: postgres://holomush:${POSTGRES_PASSWORD}@postgres:5432/holomush?sslmode=disable
HOME: /home/holomush
PortServiceProtocol
4201TelnetTCP
8080WebSocketHTTP/WS
9000Core gRPCgRPC
9100Core metricsHTTP
9101Gateway metricsHTTP

Persist configuration and certificates:

volumes:
- holomush_config:/home/holomush/.config/holomush
- postgres_data:/var/lib/postgresql/data
FormatUse Case
jsonProduction, log aggregation
textDevelopment, human readability

JSON output example:

{
"time": "2026-01-24T10:00:00Z",
"level": "INFO",
"msg": "server started",
"component": "core",
"addr": "localhost:9000"
}

Text output example:

2026-01-24T10:00:00Z INFO server started component=core addr=localhost:9000

HoloMUSH uses standard slog levels:

LevelDescription
DEBUGVerbose debugging information
INFONormal operational messages
WARNWarning conditions
ERRORError conditions

Addresses support various formats:

FormatDescription
:4201All interfaces, port 4201
localhost:4201Loopback only
0.0.0.0:4201All IPv4 interfaces
[::]:4201All IPv6 interfaces
192.168.1.1:4201Specific interface
SettingDevelopmentProduction
gRPC addresslocalhost:9000Internal network only
Control address127.0.0.1:9001127.0.0.1:9001 (never expose)
Metrics address127.0.0.1:9100Internal network only
Telnet address:4201Behind load balancer
SSL modedisableverify-full

HoloMUSH looks for a config file at:

~/.config/holomush/config.yaml

This path respects XDG_CONFIG_HOME. If XDG_CONFIG_HOME is set, the file is at $XDG_CONFIG_HOME/holomush/config.yaml.

To use a different file, pass --config to any command:

Terminal window
holomush core --config /etc/holomush/prod.yaml
holomush gateway --config /etc/holomush/prod.yaml
SourcePrecedenceNotes
CLI flagsHighestAlways win over config file and defaults
Config fileMiddleOverrides built-in defaults only
DATABASE_URLEnv-onlyNo config file equivalent; set in environment
DefaultsLowestUsed when no flag or config file value exists

DATABASE_URL is intentionally env-only to avoid storing credentials in config files that may be checked into version control.

A config file is never required. On first run, all defaults apply and every option is available as a CLI flag. You can adopt a config file incrementally — start with nothing and add keys only when you want to override a default persistently.

# Core process configuration.
# Equivalent to flags on: holomush core
core:
# gRPC listen address — gateway connects here.
# Flag: --grpc-addr
# Default: "localhost:9000"
grpc_addr: "localhost:9000"
# Control plane mTLS address for admin operations.
# Flag: --control-addr
# Default: "127.0.0.1:9001"
control_addr: "127.0.0.1:9001"
# Metrics and health HTTP endpoint.
# Set to empty string to disable.
# Flag: --metrics-addr
# Default: "127.0.0.1:9100"
metrics_addr: "127.0.0.1:9100"
# Data directory for persistent runtime files.
# Empty string uses XDG_DATA_HOME/holomush (~/.local/share/holomush).
# Flag: --data-dir
# Default: "" (XDG_DATA_HOME/holomush)
data_dir: ""
# Unique identifier for this game instance.
# Empty string triggers auto-generation on first start.
# Flag: --game-id
# Default: "" (auto-generated)
game_id: ""
# Log output format.
# "json" for production/log aggregation, "text" for human-readable output.
# Flag: --log-format
# Default: "json"
log_format: "json"
# Disable automatic seed policy upgrades on startup.
# Flag: --skip-seed-migrations
# Default: false
skip_seed_migrations: false
# Gateway process configuration.
# Equivalent to flags on: holomush gateway
gateway:
# Telnet server listen address.
# Flag: --telnet-addr
# Default: ":4201"
telnet_addr: ":4201"
# Core gRPC server address to connect to.
# Flag: --core-addr
# Default: "localhost:9000"
core_addr: "localhost:9000"
# Control plane mTLS address for admin operations.
# Flag: --control-addr
# Default: "127.0.0.1:9002"
control_addr: "127.0.0.1:9002"
# Metrics and health HTTP endpoint.
# Set to empty string to disable.
# Flag: --metrics-addr
# Default: "127.0.0.1:9101"
metrics_addr: "127.0.0.1:9101"
# Log output format.
# "json" for production/log aggregation, "text" for human-readable output.
# Flag: --log-format
# Default: "json"
log_format: "json"
# Web client HTTP server listen address.
# Serves the ConnectRPC API and embedded SvelteKit static files.
# Flag: --web-addr
# Default: ":8080"
web_addr: ":8080"
# Override embedded static files with a filesystem directory.
# When set, serves files from this directory instead of the embedded
# SvelteKit build. Useful for deploying custom builds without
# recompiling the binary.
# Flag: --web-dir
# Default: "" (use embedded files)
web_dir: ""
# Allowed CORS origins for cross-origin requests.
# Required for development when the Vite dev server (localhost:5173)
# makes requests to the gateway (localhost:8080).
# Default: [] (same-origin only — no CORS headers added)
# Flag: --cors-origins
cors_origins: []
# Example for development:
# cors_origins:
# - "http://localhost:5173"
# Game world configuration.
game:
# ULID of the starting location assigned to guest connections.
# Config file only — no CLI flag equivalent.
# Default: "01HK153X0006AFVGQT61FPQX3S" (The Nexus seed location)
guest_start_location: "01JMHZ5H3ZSBVTGARX4MSS1MBH"
# Status command configuration.
# Equivalent to flags on: holomush status
status:
# Core control address to query for health information.
# Flag: --core-addr
# Default: "127.0.0.1:9001"
core_addr: "127.0.0.1:9001"
# Gateway control address to query for health information.
# Flag: --gateway-addr
# Default: "127.0.0.1:9002"
gateway_addr: "127.0.0.1:9002"
# Output status as JSON instead of human-readable text.
# Flag: --json
# Default: false
json: false

The --config flag lets each process load a different file. This is useful when running multiple game instances on the same host, or when separating core and gateway configs:

Terminal window
# Instance A
holomush core --config /etc/holomush/game-a.yaml
holomush gateway --config /etc/holomush/game-a.yaml
# Instance B — different ports, different game-id
holomush core --config /etc/holomush/game-b.yaml
holomush gateway --config /etc/holomush/game-b.yaml

Each config file contains only the sections relevant to the process reading it. A gateway process ignores core: keys; a core process ignores gateway: keys.

CLI flags still override the selected config file, so you can share a base config and override individual values at startup:

Terminal window
holomush core --config /etc/holomush/base.yaml --log-format=text