Build Java Application Server Unikernel images using
GitHub Actions, NanoVMs (Nanos) and GitOps principles.
No containers.
No general-purpose OS.
No Kubernetes required.
This repository provides a GitHub Actions CI pipeline that builds immutable Nanos Unikernel images containing:
- ☕ a Java Application Server
(Payara, GlassFish, TomEE, …) - 🧩 a selectable Java Runtime
(Azul, Temurin, Semeru, …) - 🔐 a minimal and secure runtime environment
The result is a single bootable image that runs directly on a hypervisor.
Most Java workloads today rely on:
- containers
- full Linux distributions
- large orchestration stacks
This project demonstrates an alternative deployment model:
Build once → boot directly as a Unikernel.
- ⚡ very fast boot times
- 🔒 minimal attack surface
- 📦 fully immutable runtime
- 🧠 simpler operational model
- ☁️ cloud & on-prem friendly
Git is the source of truth.
CI reconciles it into a bootable Unikernel image.
Runtime becomes trivial.
The workflow is triggered via workflow_dispatch and performs:
The repository defines the desired state and contains:
config.json→ Nanos configurationworkflow.yml→ CI definition- documentation and diagrams
The GitHub Actions runner installs:
- 🖥️ QEMU (for image build / local boot)
- ⚙️ ops (NanoVMs build tool)
No Docker daemon required.
No privileged containers.
Based on user inputs, the pipeline:
- downloads an Application Server archive (
.zip/.tar.gz) - extracts it dynamically
- copies only runtime files into the Nanos filesystem
The build does not depend on archive directory names.
Example layout:
nanos-root/
├── bin/
├── lib/
├── <application-server>/
├── etc/
│ └── hosts
Example /etc/hosts:
127.0.0.1 localhost
10.0.2.15 10-0-2-15
No shell.
No package manager.
No OS services.
The Java Runtime is selected via workflow inputs, e.g.:
AngeloRubens/AzulJREx64Linux:25.0.1
Any Java runtime compatible with ops pkg can be used.
Core build step:
ops image create \
--imagename <image-name> \
--package <java-runtime> \
-c config.jsonThis produces:
- 🧱 a single immutable Nanos image
- ☕ Java + Application Server
- ☁️ ready for hypervisor boot
The pipeline:
- discovers the generated image in
~/.ops/images/ - fails if no image is produced
- uploads the image as a GitHub Actions artifact
The artifact can be:
- downloaded locally
- uploaded to a cloud provider
- used in downstream deployment pipelines
Security is provided by design, not by hardening:
- ❌ no shell access
- ❌ no SSH
- ❌ no package manager
- ❌ no mutable system state
- ✅ hardware isolation via hypervisor
The resulting image is secure by construction.
This project applies GitOps principles to Unikernels:
- Git defines the desired state
- CI builds immutable artifacts
- environments are disposable
- rollback = boot a previous image
- Fork this repository
- Go to Actions → Build Nanos Image
- Run the workflow manually
- Choose:
- Application Server
- Java Runtime + version
- Download the resulting Unikernel image
- ✅ Payara 7
- ✅ Azul JRE
- ✅ GitHub Actions
- 🔜 GlassFish
- 🔜 TomEE
- 🔜 Multiple Java runtimes
- 🔜 OCI / AWS / GCP image export
- 🔜 Automated deployment examples
Contributions are welcome! 🙌
Ideas:
- add support for more application servers
- improve filesystem minimization
- add deployment examples
- improve documentation
Open an issue or submit a PR 🚀
- 🧠 NanoVMs / Nanos — https://nanovms.com
- ⚙️ ops tool — https://ops.city
- 🔄 OpenGitOps — https://opengitops.dev
Licensed under the Apache License 2.0.
Built with ❤️ for people who want to run Java without containers.