DEV Community


OPS - Rethinking Cloud Infrastructure

eyberg profile image Ian Eyberg ・4 min read

Unikernels have been a technology that have been predicted for the past few years to be the future of software infrastructure.

Wait - hold up - what's a unikernel!? One way to think of a unikernel is what would happen if you converted your application into it's own operating system. It is a single purpose operating system versus a general purpose one like Linux. Another really large difference is that a unikernel is meant to only run one application per server. Since practically everything that is deployed to day is deployed onto virtual machines (eg: all of public cloud) unikernels propose that you don't need a full blown operating system for each application you want to deploy. This makes them run faster, more secure and they become way tinier.

However, unikernels have not been without their problems. One of these problems that unikernels have traditionally suffered from is that to truly utilize them in the past you had to have been a systems developer or a low level c programmer.

Not anymore.

OPS is a tool to help anyone build and run unikernels in whatever language or as whatever application they want. OPS simply loads ELF binaries just like Linux does but with unikernel benefits. Before 'unikernels' we had what were known as 'library operating systems'. OPS and the kernel that it uses 'Nanos' embraces that concept. They are both under heavy active development and have a full time team of paid kernel engineers working on it. (This has also been historically a big problem for the ecosystem.)

For local development OPS works on linux or mac currently.

To get started you'll want to install the cli tool - if you aren't a Go user you can just download the binary from the site but if you are a Go user than you can build it yourself as well once you obtain the source .


$ curl -sSfL | sh

Let's try out a quick Node.js hello world.

Put this into a file:

  console.log("Hello World!");

Then you can run it.

  $ ops load node_v11.15.0 -a ex.js

Easy huh? Want to try something a bit more complicated? Let's try a Go webserver.

Put this into main.go:

  package main

  import (

  func main() {
      fs := http.FileServer(http.Dir("static"))
      http.Handle("/", fs)

      log.Println("Listening...on 8080")
      http.ListenAndServe(":8080", nil)

If you are on a mac specify the os as 'linux'. It's important to note that it's not running linux underneath - at all. Unikernels aren't containers. The only reason we specify GOOS as linux is that Nanos implements the POSIX standard (to some degree) and loads our programs as ELFs.

  $ GOOS=linux go build main.go

You can verify this by looking at the filetype:

➜  twe  file main
main: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped

Note that I built this on a mac whose native file type is a Mach-O. We mainly support ELF since that is what is deployed to production.

➜  twe  file main
main: Mach-O 64-bit executable x86_64

Now let's create a folder to put our static assets in:

  $ mkdir static
  $ cd static
  <!doctype html>
  <meta charset="utf-8">
      <title>A static page</title>
      <h1>Hello from a static page</h1>

Then let's specify a config.json for this:

      "Dirs" : ["static"]

This simply states that we wish to put the directory 'static' into /static as a folder in our filesystem. There are many advanced options that you can explore with OPS config.json but please be aware that it is under active development and a lot of it can and will change.

Now we are going to run it. OPS implements a very small wrapper around QEMU. Qemu allows us to run the resulting built image as a virtual machine. The virtual machine is the output of ops building your app as it's own unique little operating system. Have you ever wondered to build your own operating system? Well you just did.

By default OPS will run your unikernel in what's known as 'user-mode' networking without KVM acceleration. Usermode networking is a bit slower than a proper bridged network (what you'd get on AWS or GCE) but we are playing around on your laptop so this is easy to get started with. Also, keep in mind that we run this as a non-root user by default and by default KVM will want root privileges. As a more advanced lesson later we'll show you how to configure that properly. Also keep in mind that on mac we don't have access to KVM, however, there is an equivalent - Intel HAX which we can use if we want.

  $ ops run -p 8080 -c config.json server

Now that it is running you should be able to run curl against your server and wah-lah!

  curl http://localhost:8080/hello.html

You've just built and ran your first Go webserver as a unikernel! How cool is that?

Check out the github repo, star it and let's see what else can be created!

GitHub logo nanovms / ops

ops - build and run nanos unikernels


CircleCI Go Report

Ops is a tool for creating and running a Nanos unikernel. It is used to package, create and run your application as a nanos unikernel instance.

Check out the DOCS


Most users should just download the binary from the website:

Binary install

curl -sSfL | sh

Build and Install from source

Building from source is easy if you have used Go before.

This program requires GO Version 1.13.x or greater.

Installing from source follows these general steps:

Install dependencies:

- `make deps`


- `make build`

osx notes:

GO111MODULE=on go build -ldflags "-w"

For detailed instructions please consult the documentation.

Basic usage examples

Before learning more about ops it is a good idea to see some basic usage examples. Below are links to simple examples using various programming platforms:

Let's run your first unikernel right now.


Throw this into hi.js:

var http = require('http')

Discussion (0)

Editor guide