Pre-built binaries (linux x86_64/aarch64, macOS):
# Download latest release
curl -fsSL https://github.com/sl4ppleware/bedstage/releases/latest/download/bedstage-x86_64-unknown-linux-musl.tar.gz | tar xz
sudo mv bedstage /usr/local/bin/From source (requires Rust 1.84+, a C compiler, and Perl for OpenSSL):
cargo install bedstageOn Debian/Ubuntu: apt install build-essential perl pkg-config
On Fedora: dnf install gcc perl-FindBin perl-IPC-Cmd
On macOS: Xcode command line tools are sufficient.
- Virtual hosting — exact domain, wildcard (
*.example.com), aliases, fallback - TLS with HTTP/2 and HTTP→HTTPS redirect
- Static files — ETag/304, Range/206, pre-compressed
.br/.gz - Auth — cookie sessions, bcrypt, built-in login page, user/group ACLs, rate limiting
- Caching — in-memory LRU, Cache-Control aware, per-path bypass
- Compression — gzip/brotli on the fly
- Load balancing — round-robin/random, health checks, retry, canary routing
- Hot reload —
SIGHUPswaps config without dropping connections
bedstage run # auto-detect config
bedstage run -c /path/to/config.toml
bedstage test # validate and exit
bedstage user add alice # interactive password prompt
bedstage user rm alice
bedstage user ls
kill -HUP $(pidof bedstage) # reload config
kill -USR1 $(pidof bedstage) # reopen access logConfig is found automatically: /etc/bedstage/bedstage.toml → ~/.config/bedstage/bedstage.toml → ./config.toml
[server]
listen = "0.0.0.0:443"
listen_http = "0.0.0.0:80"
redirect = true
replace_xff = true
max_body_bytes = 10485760
users_file = "users.toml"
auth_secret = "$ENV:BEDSTAGE_SECRET"
access_log = "/var/log/bedstage/access.log"
log_format = "json" # or "combined"
[tls]
cert = "/etc/ssl/cert.pem"
key = "/etc/ssl/key.pem"
[site."example.com"]
upstream = ["10.0.0.1:8080", "10.0.0.2:8080"]
balance = "round-robin"
aliases = ["www.example.com"]
[site."example.com".headers]
hsts = true
nosniff = true
frame_options = "DENY"
referrer_policy = "strict-origin-when-cross-origin"
[site."example.com".static_files]
root = "/var/www/example"
precompressed = true
[site."example.com".compress]
min_size = 256
[site."example.com".cache]
max_bytes = "64m"
default_ttl = 300
bypass = ["/api/"]
[site."example.com".auth]
enabled = true
allowed_groups = ["editors"]
[site."example.com".canary]
upstream = "10.0.0.3:8080"
weight = 10
[[site."example.com".location]]
path = "/api"
upstream = "10.0.0.4:3000"MIT