Getting Started
Use Nova Platform for the fastest developer path, or follow this page for the self-hosted Nitro path.
Nova Platform — the fastest path
If you want a fully managed deployment experience (build, deploy, attest, verify), use Nova Platform. This guide covers the self-hosted path using capsule-cli directly on your own infrastructure.
Prerequisites
Nitro-Enabled EC2 Instance
An enclave-capable instance type (e.g., m5.xlarge, c5.2xlarge, or larger). See Nitro Host Setup for full preparation.
Docker
Docker Engine installed on the host. Your application must be packaged as a Docker image.
capsule-cli
The Capsule CLI binary for x86_64-linux. Download from GitHub Releases or build from source.
Step 1: Install capsule-cli
Option A: Download release binary
# Download the latest release
curl -LO https://github.com/sparsity-xyz/nova-enclave-capsule/releases/latest/download/capsule-cli-x86_64-unknown-linux-musl.tar.gz
# Extract
tar xzf capsule-cli-x86_64-unknown-linux-musl.tar.gz
# Move to PATH
sudo mv capsule-cli /usr/local/bin/
# Verify
capsule-cli --version
Option B: Use the install script
# From the repository root
./install.sh
Option C: Build from source
# Install cross (for musl builds)
cargo install cross
# Build
cd capsule-cli
cross build --release --target x86_64-unknown-linux-musl \
--features run_enclave,capsule-runtime
# Binary at: target/x86_64-unknown-linux-musl/release/capsule-cli
Step 2: Prepare Your Docker App
Your application must be a working Docker image. Capsule doesn't change how you write your app — it wraps it.
Application requirements
- Standard Docker image with a working entrypoint
- Listens on TCP ports for incoming requests
- Uses HTTP/HTTPS for outbound calls (not raw TCP)
- Works with the standard proxy environment variables if outbound access is needed
Optional: Use Capsule APIs
- HTTP requests to
127.0.0.1:18000for attestation, signing, encryption - Use the mock service for local development
- Switch to real API inside enclave with environment variable detection
Recommended pattern for local / enclave switching
Set IN_ENCLAVE=true in your Dockerfile's ENV. In local dev, omit or set to false. Your app reads this to choose between mock and real Capsule API base URL.
import os
IN_ENCLAVE = os.getenv("IN_ENCLAVE", "false").lower() == "true"
CAPSULE_API_MOCK_URL = os.getenv("CAPSULE_API_MOCK_URL", "http://localhost:18000")
CAPSULE_API_BASE_URL = "http://127.0.0.1:18000" if IN_ENCLAVE else CAPSULE_API_MOCK_URL
Step 3: Write capsule.yaml
The manifest tells Capsule how to build and run your enclave application.
version: v1
name: "my-app"
target: "my-app-enclave:latest"
sources:
app: "my-app:latest"
defaults:
cpu_count: 2
memory_mb: 4096
ingress:
- listen_port: 8080
egress:
allow:
- "api.example.com"
api:
listen_port: 18000
sources.app is the only required image. Capsule Runtime and Shell images are pulled from the public registry by default. See capsule.yaml reference for all options.
Step 4: Build the Capsule Image
# Make sure your app image is available locally
docker build -t my-app:latest .
# Build the capsule image
capsule-cli build -f capsule.yaml
target value from your manifest (e.g., my-app-enclave:latest). The image contains the Capsule Shell, the EIF, and your manifest.
What happens during build
1. Your app image is amended with Capsule Runtime binary and manifest.
2. nitro-cli build-enclave converts it into an EIF (Enclave Image File).
3. The EIF is packaged into the Capsule Shell base image as the final release artifact.
Step 5: Run the Enclave
# Basic run
sudo capsule-cli run my-app-enclave:latest
# With port mapping
sudo capsule-cli run my-app-enclave:latest -p 8080:8080
# With debug console
sudo capsule-cli run my-app-enclave:latest -p 8080:8080 -d
# With resource overrides
sudo capsule-cli run my-app-enclave:latest \
--cpu-count 4 --memory-mb 8192 \
-p 8080:8080
# With host-backed mount
sudo capsule-cli run my-app-enclave:latest \
-p 8080:8080 \
--mount appdata=/var/lib/my-app/data
Verify It Works
# Check if the app responds
curl http://localhost:8080/health
# If your app calls the Capsule API, verify from inside the enclave:
# The app can reach http://127.0.0.1:18000/v1/eth/address
# and http://127.0.0.1:18000/v1/random