nanovms/ops
{ "createdAt": "2018-09-10T17:57:47Z", "defaultBranch": "master", "description": "ops - build and run nanos unikernels", "fullName": "nanovms/ops", "homepage": "https://ops.city", "language": "Go", "name": "ops", "pushedAt": "2025-11-20T11:21:51Z", "stargazersCount": 1433, "topics": [ "devops", "edge-computing", "imagebuilder", "microservice", "minimalist", "operating-systems", "orchestrator", "sandbox", "serverless", "unikernel", "unikernels", "virtualization" ], "updatedAt": "2025-11-24T17:01:45Z", "url": "https://github.com/nanovms/ops"}
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.
- [Installation]!(#installation)
- [Hello World]!(#hello-world)
- [Cloud]!(#cloud)
- [Support]!(#support)
Check out the DOCS.
Installation
Section titled “Installation”Most users should just download the binary from the website:
Binary install
Section titled “Binary install”curl https://ops.city/get.sh -sSfL | shIf you don’t like this option you can also download pre-made packages for various systems here and you can also build from source.
Desktop applications
Section titled “Desktop applications”| Operating System | Download |
|---|---|
| macOS | |
| Windows |
MacOS via Homebrew
Section titled “MacOS via Homebrew”Add the repo & install:
brew tap nanovms/homebrew-opsbrew install nanovms/ops/opsSee the formula file for details.
Debian / Redhat:
Section titled “Debian / Redhat:”Add a deb src:
sudo vi /etc/apt/sources.list.d/fury.listdeb [trusted=yes] https://apt.fury.io/nanovms/ /Update your sources && install:
sudo apt-get update && sudo apt-get install opsBuild and Install from source
Section titled “Build and Install from source”Building from source is easy if you have used Go before.
This program requires GO Version 1.25.x or greater.
Installing from source follows these general steps:
Install dependencies:
make depsBuild:
make buildmacOS notes:
GO111MODULE=on go build -ldflags "-w"For protobufs/grpc we use https://buf.build/ .
To generate protobufs (but do not check in to vcs):
make generateFor detailed instructions, please consult the documentation.
Hello World
Section titled “Hello World”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:
const http = require('http');http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('Hello World\n');}).listen(8083, "0.0.0.0");console.log('Server running at http://127.0.0.1:8083/');Then you can run it like so:
ops pkg load eyberg/node:v16.5.0 -p 8083 -n -a hi.jsNote: Since the node package is inside the unikernel you do not need to install node locally to use it.
Want to push your app out to the cloud? No complex orchestration like K8S is necessary. OPS pushes all the orchestration onto the cloud provider of choice so you don’t need to manage anything. Be sure to try this out as the next step after running a hello world locally as it will answer many questions you might have.
You can find many more pre-made packages at the public repo:
Or via the shell:
ops pkg listYou can also upload your own with a free account.
Languages:
Various langauge examples can be found at https://github.com/nanovms/ops-examples. In general [https://nanos.org]!(Nanos) supports any languages and is not language specific.
You can find more examples and tutorial on youtube as well:
https://www.youtube.com/channel/UC3mqDqCVu3moVKzmP2YNmlg
Daemon
Section titled “Daemon”OPS started out as a daemon-less cli tool to build and run unikernels locally and to also interact with the various clouds. We will keep that functionality as-is, however, ops can also run as a daemon locally for software that is a composition of multiple services. The daemon expects to have elevated privileges (currently via suid bit) in order to place the various programs on their class c network (vs relying on user-mode). This is not necessary for ‘ops run’, ‘ops pkg load’ or ‘ops instance create’ but only for multipl services ran locally that expect to communicate to each other vs just the host.
For now the daemon and ‘ops instance create’ share metadata but that is expected to change in the future.
Apple M1/M2 Users
Section titled “Apple M1/M2 Users”The Apple M1 and M2 are ARM based. OPS is built for users primarily deploying to x86 based servers. We now have full support for running native ARM applications (ELFs) on M1 and M2s natively. That means without relying on Rosetta and with full hardware acceleration.
Be aware that if you wish to deploy your applications to x86 servers you’ll need to re-build your images as x86 versus the default of arm64.
Build a bootable image
Section titled “Build a bootable image”ops build <app>
Package and run
Section titled “Package and run”ops run <app># orops run -p <port> <app>Using a config file
Section titled “Using a config file”ops run -p <port> -c <file> <app>Use golang string interoplation in config files
Section titled “Use golang string interoplation in config files”To enable set ops_render_config to true. Both ${ENV_VAR} and $ENV_VAR are supported.
Example Command
Section titled “Example Command”ops_render_config=true ops run -p <port> -c <file> <app># orexport ops_render_config=trueops run -p <port> -c <file> <app>Example config
Section titled “Example config”{ "Args":[ "--user", "${USER}", "--password", "$PASSWORD" ], "Dirs":["myapp/static"]}Example config file
Section titled “Example config file”OPS config files are plain JSON, below is an example.
{ "Args":["one","two"], "Dirs":["myapp/static"]}Setup networking
Section titled “Setup networking”New users wishing to play around in a dev environment are encouraged to use the default user-mode networking. Other production users are encouraged to utilize native cloud builds such as Google Cloud which handle networking for you.
Only advanced/power users should use the bridge networking option.
Useful Ops Environment Variables
Section titled “Useful Ops Environment Variables”The following environment variables are available to you
ops_render_config- Set totrueto use Golang ENV var interpolation to render your JSON configs.
Reporting Bugs
Section titled “Reporting Bugs”Feel free to open up a pull request. It’s helpful to have your OPS version and the release channel you are using.
Also, if it doesn’t work on the main release, then you can try the nightly. The main release can tail the nightly by many weeks sometimes.
ops versionIf you are using a package, get the package hash:
jq '."gnatsd_1.4.1"' ~/.ops/packages/manifest.jsonPull Requests
Section titled “Pull Requests”If you have an idea for a new feature and it might take longer than a few hours or days to complete, then it’s worth opening a feature request ticket to ideate it first before jumping into code. There might be someone already working on the feature or plans to do something entirely different.
Security
Section titled “Security”Feel free to email security[at]nanovms[dot]com.
Support
Section titled “Support”If you are having trouble running a particular application please feel free to open an issue and we can take a look. In general we’ll only want to support the latest release from a given application/project, however, if you really want/need support for something older there are paid support plans available - contact the folks at https://nanovms.com.
If you need email support you will need to sign up for a support plan.