Julia Evans had a blogpost a handful of years ago about orchestrating firecracker payloads.
The problem is that running firecracker requires virtualization and that can be expensive or impossible on the normal public clouds. Without virtualization you are left with intolerably slow emulation which is totally unusable for production. Julia mentioned using both nested virtualization on Digital Ocean and metal instances on AWS. However, metal instances on AWS are expensive. It costs $3.80/hr for the cheapest x86 instance.
However, NanoVMs Inception changes that.
NanoVMs now supports running unikernel instances on top of existing ec2 instances vs as ec2 instances without using expensive metal instances or nested virtualization. Amongst other things this means you can now build your very own firecracker based PAAS on top. A lot of PAAS platforms need the capability to oversubscribe their workloads. If they are external facing - say you want to do a serverless postgres offering you're probably going to be offering quite a few workloads for free users. If those users aren't paying you, you probably don't want to let them just spin them up for months at a time. You also might be in a situation where you have ephemeral workloads and you just want the instance to spin up, do the work and spin down. You don't want to be spending minutes trying to provision a new instance if you have thousands of tenants doing this.
If you are going to invest in creating a free-tier serverless platform or some other paas you should seriously consider provisioning your payloads as unikernels as well. This immediately eliminates a large chunk of malware that affects folks in the PAAS/serverless industry. They then throw around the self-deprecating affectionality labeled term "RCE-as-a-service".
Running Unikernel Firecracker Payloads on AWS
We've had great support for running firecracker unikernels for a long time now but it was predicated on the notion that you'd be on physical hardware.
Ever since we announced the ability to run firecracker on ordinary aws instances I wanted to revisit Julia's blogpost and subsequently the gist that has a small go webserver that instantiates firecracker payloads by tying into the the firecracker sdk. The other reason why I thought it was worth showing this vs just using firecracker itself is that the cli tool itself doesn't have great DX so you might as well go the API route instead, especially if you're going to build something on top of it.
We made very light modifications to it that you can get here, so you can have an out-of-the-box experience and see for yourself.
To get started you'll want to first spin up an Inception instance. From there go ahead and download firecracker from the releases page. At the time of this writing that would be https://github.com/firecracker-microvm/firecracker/releases/download/v1.12.0/firecracker-v1.12.0-x86_64.tgz.
Then we'll go ahead and install some helper utilities. We don't bundle any of this in the normal vm as we initially made this for people who were using ops, however if you'd like to see it bundled let us know and we can make it happen. Also, since this is just a simple demo, production code would probably not exec.Command for these commands but use native bindings or stdlib instead.
sudo apt-get install bridge-utils net-tool
I'm not going to paste all the code since it's linked inside the github already. We bundled a small hello world inside the github repo so you can test so let's make our hello world a unikernel first via 'ops run':
eyberg@venus:~/fc-ex/test$ ops run -n test
running local instance
booting /home/eyberg/.ops/images/test ...
[0.055887] en1: assigned 10.0.2.15
vim-go
(OPS builds and runs unikernels on demand with 'ops run' but you can also skip the run step by simply doing an 'image create' instead.)
Then we can try hitting our api server to have firecracker instantiate it instead using this curl request:
#!/bin/sh
curl --header "Content-Type: application/json" \
--request POST \
--data '{"root_image_path":"/home/ubuntu/.ops/images/test"}' \
http://localhost:8080/create
The root_image_path here would be pointing at the unikernel image we made just now but perhaps if you take this example further it might download from s3 or a minio instance if it doesn't exist on the instance you are trying to spawn from first.
ubuntu@ip-172-31-20-248:~/fc-ex$ sudo ./fc
INFO[0001] Called startVMM(), setting up a VMM on /tmp/firecracker-4.sock
2025-06-22T19:26:04.335157380 [anonymous-instance:main] Running Firecracker v1.12.0
2025-06-22T19:26:04.335321544 [anonymous-instance:main] Listening on API socket ("/tmp/firecracker-4.sock").
2025-06-22T19:26:04.336484828 [anonymous-instance:fc_api] API server started.
2025-06-22T19:26:04.350655856 [anonymous-instance:fc_api] The API server received a Get request on "/machine-config".
2025-06-22T19:26:04.350859654 [anonymous-instance:fc_api] The request was executed successfully. Status code: 200 OK.
INFO[0001] VMM logging disabled.
INFO[0001] VMM metrics disabled.
2025-06-22T19:26:04.352869698 [anonymous-instance:fc_api] The API server received a Put request on "/machine-config" with body "{\"mem_size_mib\":512,\"vcpu_count\":1}\n".
2025-06-22T19:26:04.352989422 [anonymous-instance:fc_api] The request was executed successfully. Status code: 204 No Content.
2025-06-22T19:26:04.353201147 [anonymous-instance:fc_api] The API server received a Get request on "/machine-config".
2025-06-22T19:26:04.353282108 [anonymous-instance:fc_api] The request was executed successfully. Status code: 200 OK.
INFO[0001] refreshMachineConfiguration: [GET /machine-config][200] getMachineConfigurationOK &{CPUTemplate: MemSizeMib:0xc000287938 Smt:0xc000287940 TrackDirtyPages:false VcpuCount:0xc000287930}
2025-06-22T19:26:04.353664793 [anonymous-instance:fc_api] The API server received a Put request on "/boot-source" with body "{\"boot_args\":\"ro noapic reboot=k console=ttyS0 panic=1 pci=off nomodules random.trust_cpu=on ip=172.17.0.4::172.17.0.1:255.255.255.0::eth0:off\",\"kernel_image_path\":\"/home/ubuntu/.ops/nightly/kernel.img\"}\n".
2025-06-22T19:26:04.353761323 [anonymous-instance:fc_api] The request was executed successfully. Status code: 204 No Content.
INFO[0001] PutGuestBootSource: [PUT /boot-source][204] putGuestBootSourceNoContent
INFO[0001] Attaching drive /home/ubuntu/.ops/images/test, slot 1, root true.
2025-06-22T19:26:04.354083829 [anonymous-instance:fc_api] The API server received a Put request on "/drives/1" with body
"{\"drive_id\":\"1\",\"is_read_only\":false,\"is_root_device\":true,\"path_on_host\":\"/home/ubuntu/.ops/images/test\"}\n".
2025-06-22T19:26:04.354175770 [anonymous-instance:fc_api] The request was executed successfully. Status code: 204 No Content.
INFO[0001] Attached drive /home/ubuntu/.ops/images/test: [PUT /drives/{drive_id}][204] putGuestDriveByIdNoContent
INFO[0001] Attaching NIC fc-tap-4 (hwaddr 02:FC:00:00:00:04) at index 1
2025-06-22T19:26:04.354423626 [anonymous-instance:fc_api] The API server
received a Put request on "/network-interfaces/1" with body "{\"guest_mac\":\"02:FC:00:00:00:04\",\"host_dev_name\":\"fc-tap-4\",\"iface_id\":\"1\"}\n".
2025-06-22T19:26:04.354832132 [anonymous-instance:fc_api] The request
was executed successfully. Status code: 204 No Content.
INFO[0001] No interfaces are allowed to access MMDS, skipping MMDS config
2025-06-22T19:26:04.355023393 [anonymous-instance:fc_api] The API server received a Put request on "/actions" with body
"{\"action_type\":\"InstanceStart\"}\n".
2025-06-22T19:26:04.362746613 [anonymous-instance:main] Artificially kick devices.
2025-06-22T19:26:04.362843017 [anonymous-instance:fc_vcpu 0] Received a
VcpuEvent::Resume message with immediate_exit enabled. immediate_exit was disabled before proceeding
2025-06-22T19:26:04.362875518 [anonymous-instance:fc_api] The request was executed successfully. Status code: 204 No Content.
INFO[0001] startInstance successful: [PUT /actions][204]
createSyncActionNoContent
hello from a go unikernel inside firecracker
2025-06-22T19:26:04.490162070 [anonymous-instance:main] Vmm is stopping.
2025-06-22T19:26:04.490505840 [anonymous-instance:main] Vmm is stopping.
2025-06-22T19:26:04.503844411 [anonymous-instance:main] Firecracker
exiting successfully. exit_code=0
INFO[0001] firecracker exited: status=0
and it pops up and spins right back down! Very fast I might add.
{"ip_address":"172.17.0.4","id":"EE039106-9469-4856-A94F-0C15CAF5321E"}
You now have the beginnings of your very own firecracker based PAAS that runs on AWS and runs unikernels. See how incredibly easy that was?
If you haven't tried it out yet - Try it out now! I'm excited to see what you build.