The CLI has three subcommands:
eval evaluates a handlebars template from STDIN.
get renders content from a content directory.
serve starts an HTTP server.
serve is where the real action is, but the other two come in handy at times.
These commands all require a content directory, which is just the folder where your website lives. There
are a bunch of sample content directories
in the repository.
To learn more, run
operator --help or
operator <SUBCOMMAND> --help.
Let's run this website:
- git clone https://github.com/mkantor/operator-website.git
- operator -vv serve \
Then open http://localhost:8080 in your browser of choice.
Try making a change to the site (in
operator-website/content) and restart the server to see the
When Operator starts up it crawls through your content directory to build a representation of your website. The
site's routes and configuration are derived from this directory.
Operator needs to know what
media type will be emitted by each content file. This is
specified via file extensions (
There are three different kinds of content files:
Static files are served directly. For example, you can drop an image or html file into your
content directory and it'll be served as is.
Static files only have one extension (
Executables are run at request time, with standard output piped out as the response body. Any
program that you can run from the command line will work (scripts, compiled programs, etc). The executable is
invoked with no CLI arguments and with its working directory set to its own parent folder.
An environment variable named
OPERATOR_RENDER_DATA is provided to executables. Its value is
encoded as JSON. This is the same data provided to handlebars templates.
Executables have two extensions, with the first one indicating the media type of the executable's output
dankmeme.jpg.exe, etc). Operator
requires execute permissions on these files, and scripts will typically need a
so your OS knows how to interpret them.
Operator doesn't care what the second extension is for executables, but you can use it to indicate the file
contact.html.py would be a Python script which outputs HTML. In
executables the file type is usually not the same as its output type, although if you're
feeling feisty then things like
are certainly possible.
Handlebars templates are compiled during server startup and rendered at request time. The
heavy lifting is done by
handlebars Rust library
which is largely compatible with
and a custom
get helper to make your content composable.
Like executables, handlebars templates also have two extensions. The first one indicates the media type, and
the second one must be
.hbs to tell Operator that it's a template (
Operator is only as secure as your content directory, so be careful! Here are some best practices:
Always create a dedicated user with limited privileges to run the server and/or run it inside a locked-down
container or chroot jail.
Make sure that nobody except you has write permissions on the content directory and everything in it (and,
again, don't run Operator as yourself in production).
Any executables you put in the content directory must be trusted. You should think carefully about what effects
they can have and how they handle request data. An executable that could
rm -rf /, leak sensitive
information, or fork bomb your system would be a bad idea.