xenia

A single-binary web server and reverse proxy, configured in JavaScript. Version 0.15.1.

// xenia.conf.js
export default {
  routes: [
    { path: '/', body: 'hello\n' },
    { prefix: '/static/', root: 'public' },
    { prefix: '/api/', proxy: 'api' },
  ],
  upstreams: { api: { servers: ['127.0.0.1:3000'] } },
};

Installing

The Docker image, for amd64 and arm64:

docker run -d -p 80:8080 -v "$PWD:/etc/xenia:ro" ofkindness/xenia:0.15.1

Or an archive from the releases, with the binary, the license, an example project and a systemd unit:

Archive Runs on
xenia-0.15.1-linux-x86_64.tar.gz, xenia-0.15.1-linux-arm64.tar.gz any Linux on that architecture: a static binary, no C library or package needed
xenia-0.15.1-macos-arm64.tar.gz macOS 13 or later on Apple silicon
sha256sum -c --ignore-missing SHA256SUMS    # shasum -a 256 -c on macOS
tar -xzf xenia-0.15.1-linux-x86_64.tar.gz
./xenia-0.15.1-linux-x86_64/xenia --version

The macOS binary is signed ad hoc, so a copy downloaded with a browser is quarantined: xattr -d com.apple.quarantine xenia lets it run.

Verifying a release

The image and each release’s SHA256SUMS are signed with Sigstore by the workflow that publishes them, and each release has an SPDX SBOM of xenia and the libraries in it. With cosign:

cosign verify ofkindness/xenia:0.15.1 \
  --certificate-identity https://github.com/xenia-platform/xenia/.github/workflows/publish.yml@refs/heads/main \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com

cosign verify-blob SHA256SUMS --bundle SHA256SUMS.sigstore.json \
  --certificate-identity https://github.com/xenia-platform/xenia/.github/workflows/publish.yml@refs/heads/main \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com
sha256sum -c --ignore-missing SHA256SUMS

Documentation

   
Configuration the config file and every option: routes, files, compression, upstreams and proxying, names, health checks, WebSockets, virtual hosts, feature flags, rate limits, caching, TLS, client certificates, HTTP/2
Running the command line, running as a user and under systemd, shutdown, signals, the admin interface, access logs, metrics, request IDs
Docker the image: ports, mounting a config, HTTPS, reloads, stopping, health, compose and Kubernetes
Deployment putting xenia on a host: users, ports below 1024, file permissions, the systemd unit, log rotation, behind a load balancer
Design the model behind xenia: snapshots, the data and control planes, memory and concurrency
Changelog what changed in each release

Questions and bugs go to the issues; vulnerabilities, privately, as the security policy says.

License

Xenia is free to use, commercially or not, under the Xenia License: run it anywhere, and pass on unmodified copies of the binaries and images. Its source is not published.

Third-Party Code

Xenia contains these libraries, each an unmodified upstream release under its own license. Their license texts are in THIRD_PARTY_LICENSES, in each archive and under /licenses in the image.

Library Version License For
libuv 1.53.0 MIT event loops and I/O
mbedtls 4.1.1 Apache-2.0 OR GPL-2.0-or-later TLS and cryptography (used under Apache-2.0)
mimalloc 3.5.3 MIT the allocator, in the static Linux binaries only
quickjs-ng 0.17.0 MIT the JavaScript engine that compiles configs
zlib 1.3.2 Zlib gzip compression