Skip to content

funwithcthulhu/vitrine

Repository files navigation

Vitrine

Compile a site directory into a MirageOS web appliance.

Vitrine serves static files from a deterministic store and keeps the HTTP details in one place: path normalization, MIME types, ETags, cache headers, custom 404 pages, precompressed assets, and a small dynamic route hook.

It is currently aimed at small static sites embedded into MirageOS unikernel images. It does not manage deployment, provision Albatross, or choose a store backend for large sites.

Quickstart

Install development dependencies for this checkout:

opam install . --deps-only --with-test --with-doc

Development

dune build @all
dune runtest
dune fmt

Serve the example site locally:

dune exec -- vitrine dev examples/basic-site/site --port 8080

Print the site manifest:

dune exec -- vitrine manifest examples/basic-site/site

Create a small project:

dune exec -- vitrine init my_site

Layout

  • lib/ contains the runtime-independent static-serving logic.
  • lib_mirage/ adapts Vitrine responses to Cohttp/Lwt.
  • bin/ contains the vitrine command.
  • examples/basic-site/ contains a small site and Mirage entrypoint.
  • test/ covers the core serving behavior.

Static Store

vitrine embed site/ emits an OCaml module containing a Vitrine.store.

dune exec -- vitrine embed examples/basic-site/site > site_store.ml

The generated store is immutable OCaml data. It is intended for embedding into a unikernel image. Large sites may need a different store backend later; the current slice is aimed at small static sites.

Mirage Build

The example uses Mirage's Cohttp server device:

cd examples/basic-site
mirage configure -t unix
make

For Solo5:

mirage configure -t hvt
make

This checkout does not vendor Mirage packages. Install Mirage, a Solo5 target, and the Cohttp Mirage stack in the switch used for unikernel builds.

HTTP Behavior

Requests are normalized before lookup. Traversal attempts are rejected. / and directory paths resolve through index.html; unresolved paths use /404.html when present.

HTML uses Cache-Control: no-cache. Filenames with a hex hash segment use public, max-age=31536000, immutable. Other static assets use a short public cache lifetime.

If file.br or file.gz exists and the client advertises support, Vitrine serves the compressed file with the original file's MIME type. Brotli is preferred over gzip.

Dynamic Routes

Static content is the default path. Tiny endpoints can be added at the adapter layer:

let routes =
  [
    {
      Vitrine_mirage.meth = `GET;
      path = "/health";
      handler =
        (fun _request _body ->
          Vitrine.text "ok\n" |> Vitrine_mirage.response |> Lwt.return);
    };
  ]

Maintainer

Contact: funwithcthulhu29@gmail.com

License

MIT. See LICENSE.

About

Compile a site directory into a MirageOS web appliance.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors