Security Features Home Extensions Ecosystem

Mölla (often written moella, pronounced /mœla/ (œ as in bird with a British accent)) is a binary that reads config file(s) and spinns up a Kvarn web server. It supports all the major Kvarn extensions and presents most options Kvarn supports.

Mölla can serve multiple hosts on a single server (with automatic certificates!), extending to serving multiple sets of hosts on different ports / NICs—all within 1 process. When you run kvarnctl reload, Mölla will restart and load any changes made to the config (or run a new version of the binary), with 0 milliseconds of downtime.

Getting started

cargo install

Moella is available at crates.io. You can install it using cargo install moella. Alternatively, you can download pre-built binaries:

Download binary

Download the binary for your platform from this page.

Now, create a Mölla config in a file named host.ron:

// My Moella config
(
    extensions: {
        "website": [ AllDefaults ]
    },
    hosts: [
        Http (
            name: "mywebsite.org",
            path: "./",
            extensions: ["website"],
            options: (
                disable_client_cache: true,
                disable_server_cache: true,
            )
        )
    ],
    ports: Standard(Host("mywebsite.org")),
)

Next, run the web server using ./<downloaded binary> --config host.ron --high-ports and go to http://localhost:8080. The contents of ./public/index.html will be loaded in your browser (refresh page to update content). The --high-ports tells Mölla to use port 8080 instead of 80 (the default for the unencrypted web), because you have to run sudo to get access to port 80 on Linux.

Config schema

Here, all the options of the config are documented.

// optional to specify `KvarnConfig`
// all paths in the config will always be relative to the config's location
KvarnConfig (
    // Import other config files to add to the set of `extensions` and `hosts`.
    //
    // Note that only one config file can define `ports` (see at the end of the config)
    //
    // So say you have a common extension set for all you hosts,
    // then all those configs can load `extensions.ron` and this (main) config
    // in turn import those. Any one of the configs can define the `ports` parameter.
    //
    // This prints a warning if loading a config failed, but it isn't considered critical.
    //
    // When you define a host collection twice with the same name,
    // imported hosts are appended to the host collection
    // Or, you can simply use `All` when binding to a port.
    import: ["other-host.ron"],

    // all options are optional unless labled `required`
    // Please note that globbing (usage of "*") generally only works as the first or last character
    extensions: {
        // define sets of extensions, and then add one or more sets of extensions to hosts
        // several of the same extension can be used (if they don't override the previous)
        "icelk": [
            // don't add the default extensions: https://doc.kvarn.org/kvarn/extensions/struct.Extensions.html#method.new
            NoDefaults,

            // the following are excluded when using `NoDefaults`, but present by default
            // Redirect `/kvarn/` to `/kvarn/index.html`, very important
            RedirectIndexHtml,
            Referrer(None),
            CorsSafe,
            CspSafe,
            // https://kvarn.org/nonce.html
            Nonce,
            // If HTTPS is available, redirect all users to it
            RedirectHttpToHttps,

            // Add all quality of life extensions: https://doc.kvarn.org/kvarn_extensions/fn.mount_all.html
            //
            // adds the present internal extensions
            // [ "download", "cache", "hide", "private" (same as hide),
            //  "allow-ips", "tmpl" (templates), and "push" (HTTP/2 push) ]
            AllDefaults,
            // Adds template support: https://kvarn.org/templat