Virtual Hosts
Virtual hosts let you serve different content based on the Host header in the request. Each [[vhost]] block defines one site.
Basic Vhost
[[vhost]]
hostnames = ["mysite.com"]
root = "/static"Catch-All Vhost
Use _ as the hostname to match any request that doesn't match another vhost:
[[vhost]]
hostnames = ["_"]
root = "/static"This is the recommended setup for single-site containers.
Multiple Vhosts
Serve several sites from one container:
[[vhost]]
hostnames = ["blog.example.com"]
root = "/static/blog"
spa = true
[[vhost]]
hostnames = ["docs.example.com"]
root = "/static/docs"
[[vhost]]
hostnames = ["_"]
root = "/static/default"Requests are matched in this order:
- Exact hostname match
- Wildcard match
- Catch-all
_
Wildcard Hostnames
Match all subdomains of a domain:
[[vhost]]
hostnames = ["*.example.com"]
root = "/static"Rules:
*.example.commatchesblog.example.com,app.example.com, etc.- It does not match the apex
example.com— add it as a separate exact hostname if needed - Wildcards must have at least two labels:
*.example.comis valid,*.comis rejected
Multiple Hostnames Per Vhost
One vhost can respond to several hostnames:
[[vhost]]
hostnames = ["example.com", "www.example.com"]
root = "/static"Vhost Settings
Each vhost supports these options:
[[vhost]]
hostnames = ["mysite.com"]
root = "/static" # Directory to serve files from
index = "index.html" # Default file for directories
spa = false # SPA fallback mode
spa_ignore = ["/assets"] # Paths that skip SPA fallback
block_dot_paths = true # Block .env, .git, etc.
etag = true # ETag caching headers
allowed_methods = ["GET", "HEAD"] # Allowed HTTP methods
deny_all = false # Block all static file access
custom_404 = "404.html" # Custom 404 error page
redirects_file = "/etc/rustinx/redirects/mysite.toml"All settings except hostnames and root are optional and inherit from [defaults].
Routes
Routes serve a specific file for a specific URL path. They are checked before normal static file serving:
[[vhost]]
hostnames = ["mysite.com"]
root = "/static"
deny_all = true
[[vhost.routes]]
path = "/landing"
serve = "landing.html"
[[vhost.routes]]
path = "/about"
serve = "about.html"Routes use prefix matching. /landing matches both /landing and /landing/anything. Routes are sorted longest-first, so /app/admin is checked before /app.
deny_all Mode
When deny_all = true, normal static file serving is disabled. Only configured routes and redirects work:
[[vhost]]
hostnames = ["restricted.example.com"]
root = "/static"
deny_all = true
# Only this specific path serves content
[[vhost.routes]]
path = "/public"
serve = "public.html"
# Redirects still work
[[vhost.redirects]]
path = "/go"
url = "https://example.com"GET /returns403 ForbiddenGET /publicreturns the fileGET /goreturns a redirect
