Welcome to Nanorack

Nanorack is a developer-first platform designed for running containerized services with zero infrastructure overhead.

Describe your application in a nanorack.yaml manifest. Nanorack provisions automated HTTPS, sets up private networking between services, securely delivers secrets, mounts NVMe storage, and collects your logs and metrics out of the box.

Quickstart

Deploying a service takes less than a minute. Create a nanorack.yaml manifest in your project directory and deploy using the nanorack CLI.

1. Write your manifest

project: shop
stage: prod
region: dc1
---
name: hello-world
image: nginx:latest
port: 80
cpu: 0.1
memory: 64

public:
  expose: http

2. Deploy via CLI

$ nanorack login
$ nanorack deploy nanorack.yaml
Stage shop/prod [dc1]
  dc1    deploy    hello-world  ok
done: 1 deployed, 0 unchanged, 0 stopped

3. Open your service

Every service with expose: http gets a free HTTPS subdomain automatically. Use nanorack get to find it:

$ nanorack get hello-world
hello-world  status=running replicas=1/1 domain=hello-world-prod-8k3fa.nrck.dev endpoints=

Manifest Reference

A nanorack.yaml file contains a coordinate document defining where the stage lives, followed by one or more service documents separated by ---.

Coordinate Fields

Field Type Description
project string · required The name of your application project.
stage string · required The target deployment environment, such as prod or staging.
region string · required Target region placement, such as region: dc1.

Service Fields

Field Type Description
name string · required The service name within your stage. Doubles as the internal DNS hostname (e.g. a service named db is reachable at db.internal).
tier string · optional
default: app
Compute tier: app (sandboxed container, the default) or sys (dedicated virtual machine).
image string · required The Docker image to run, from a public or private registry. The tag is resolved to an exact image on each deploy — see Image Tags & Updates.
port number · required
if public.expose set
The container port receiving traffic. Required when public.expose is set.
cmd string · optional Override the container image's default command.
replicas number · optional
default: 1
Number of instances to run (max 100). Run 2+ for zero-downtime deploys and high availability — see Deployments.
cpu number · required
unless cores set
vCPUs to reserve per replica, in steps of 0.1 (e.g. 0.5). Minimum 0.1 (App) / 0.3 (Sys). Mutually exclusive with cores.
cores number · optional Pinned dedicated CPU cores, the alternative to shared cpu. Set one, not both.
memory number · required Memory to reserve per replica, in MB. Minimum 16 (App) / 128 (Sys).
disk number · optional Ephemeral scratch disk in GB, wiped on every redeploy.
volume object · optional A dedicated NVMe volume kept across redeploys, with size (GB) and mount (absolute path). A service with a volume runs exactly one replica.
env map · optional Plain environment variables. Use secrets for anything sensitive.
public object · optional Public exposure: expose: http (optionally with custom domain) or expose: port (a raw public port, TCP and UDP). Omit to keep private.

Stages & Service Discovery

Projects in Nanorack are organized into Stages (e.g. prod, staging).

Services within the same stage can communicate with each other using simple internal hostnames. For example, if you run a service named db in your stage, any other service in that stage can connect directly to db.internal.

Services in different stages or different projects are isolated from one another and cannot communicate over the private network.

Deployments

Deploying is declarative: nanorack deploy converges your stage to the manifest — declared services are created or updated, and anything no longer in the file is stopped.

When a service's image or configuration changes, Nanorack performs a rolling update. Whether that update is seamless depends on your replica count:

The rule of thumb: run 2 or more replicas for zero-downtime deploys. That's the same thing you want for high availability — extra replicas keep your service up if a host goes away — so a single knob covers both. A single replica is the simplest, lowest-cost option, ideal for dev/staging or anything that can tolerate a momentary blip during a deploy.

Image Tags & Updates

Your image points at a tag, like nginx:latest or myapp:v2. Each time you run nanorack deploy, Nanorack looks up the exact image that tag points to at that moment and pins your service to it. Two things follow, and together they're what you want:

So :latest is perfectly fine to use: it's convenient, and you stay in control because updates land only on a deploy. If you'd rather lock a service to one exact, unchanging build, reference it by digest (myapp@sha256:…) — that always resolves to the same image no matter what happens to any tag.

Secrets Management & Registry Auth

Set stage secrets via CLI without putting credentials in source code:

$ nanorack secret set DB_PASSWORD "your-secret-key"

Secrets are encrypted at rest using per-project data encryption keys (AES-256-GCM) and never touch your image, manifest, or build logs. Secrets are scoped to the stage, so every service in the stage sees the same set, and prod and staging keep separate values.

Static File Delivery

At container boot, secrets arrive as a read-only JSON file bind-mounted at /secrets/secrets.json — a flat map of key-value strings that your application can read during initialization.

Dynamic IMDS API (169.254.169.254)

Workloads can also fetch secrets dynamically at runtime via the host-local Instance Metadata Service (IMDS) at http://169.254.169.254/secrets. This allows applications to pick up rotated secrets without needing a container restart.

Security Requirement (SSRF Guard): Every IMDS request MUST include the X-Nanorack-Metadata: 1 HTTP header. Requests lacking this header are rejected locally to prevent Server-Side Request Forgery (SSRF) vulnerabilities in application code from leaking secrets:

curl -H "X-Nanorack-Metadata: 1" http://169.254.169.254/secrets

Private Registry Authentication

To deploy images from private container registries (such as Docker Hub, GitHub GHCR, or AWS ECR), set your registry credentials via CLI or the web dashboard:

$ nanorack registry set ghcr.io "username" "ghp_yourtoken"

Private registry credentials are encrypted at rest and served over the host-local IMDS metadata API at /registry-auth when pulling container images. Your credentials are never embedded into container images, stored in Nomad job specifications, or exposed in version control.

Public Access & Custom Domains

Configure public internet access for your services in nanorack.yaml:

Web Ingress (HTTP): Set expose: http to route web traffic to your service over HTTPS. Every exposed service gets a free generated subdomain (like myapp-a1b2c3.nrck.dev) with HTTPS already set up — no DNS configuration needed. To serve from your own domain, add domain: app.example.com and follow the two steps below.

Direct Ports (TCP/UDP): Set expose: port for game servers, database brokers, or non-HTTP protocols. Each replica is assigned its own raw public port — reachable over both TCP and UDP — stable across redeploys; run nanorack get <service> to list the endpoints.

Bringing your own domain

Serving from a hostname you own (e.g. app.example.com) takes two DNS records. Both are shown for you, with their exact values, on the domain's setup page in the dashboard — you add them once and never touch them again.

  1. Point it at Nanorack. Add a CNAME from your hostname to your region's ingress:

    CNAME   app.example.com   →   ingress-dc1.nanorack.dev
    

    The ingress name is region-specific — the dashboard shows the exact one for your stage — so traffic lands directly in the datacenter your service runs in. Using a CNAME means you never have to look up or maintain an IP address.

  2. Let us manage your certificate. Add the second CNAME exactly as shown. It delegates certificate validation to us so we can issue and renew your SSL certificate for you, automatically and forever:

    CNAME   _acme-challenge.app.example.com   →   <your-token>.nrck-acme.dev
    

Once both records resolve, your certificate is issued automatically (usually within a minute) and renews on its own — there's nothing to install and nothing to rotate.

Root domains. DNS doesn't allow a CNAME on a bare root domain (example.com with no subdomain in front). For record 1, use your DNS provider's ALIAS/ANAME option, or an A record to the IP shown in the dashboard; Cloudflare users get this automatically via CNAME flattening. Record 2 is always an ordinary CNAME and is unaffected.

Putting your own CDN or proxy in front (Cloudflare, Fastly, …). Bring whatever edge you like — point record 1 at your proxy and your proxy's origin at ingress-dc1.nanorack.dev, and leave record 2 as-is. Because we validate and renew your certificate over DNS, it keeps working no matter what sits in front of us — no origin-certificate juggling, no special rules. If you use Cloudflare's proxy (orange cloud), set your SSL/TLS mode to Full (Strict) — not Flexible, which causes a redirect loop.

Compute Tiers

Nanorack provides two compute tiers for running your workloads:

App Tier (tier: app, the default): Sandboxed containers designed for web applications, APIs, background workers, and stateless microservices. Allocations start at 0.1 vCPU and 16 MB of memory.

Sys Tier (tier: sys): A dedicated virtual machine with its own kernel, built for databases, game servers, and workloads that need full kernel control. Allocations start at 0.3 vCPU and 128 MB of memory.

Disk Storage & Volumes

All storage runs on the same local NVMe drives — there is no slower tier. The only difference between the two kinds is what happens to the data when you redeploy:

Ephemeral Disk: Set disk: 10 for temporary space (build files, caches, scratch data). It is tied to the deployment — every redeploy or reschedule starts with a clean, empty disk. Never store anything there you can't lose.

Dedicated Volume: Set a volume with size (GB) and mount (path) for storage that is kept — your data survives restarts, redeploys, and reschedules. Use it for databases and anything stateful. A service with a volume runs exactly one replica.

Logs & Metrics

Every service streams its logs and reports resource usage automatically — no agents, sidecars, or configuration required. Both commands read the stage coordinate from the manifest in your current directory, and both are also available in the dashboard.

Logs

Follow a service's live output, or query its recent history:

# Follow live output
$ nanorack logs web

# Query history: the last hour, only lines matching "error"
$ nanorack logs web --since 1h --filter error

Logs are retained for 7 days. Passing any time or filter flag switches from the live stream to a historical query:

Flag Description
--since <dur> Look back a relative window, e.g. 15m, 1h, 24h.
--start / --end An explicit range — a duration like -6h, or an RFC 3339 timestamp.
-f, --filter <text> Return only lines matching the given term.
-n, --limit <n> Cap the number of lines returned (default 100, max 1000).

The dashboard offers the same live/historical view with a time-range selector and search box.

Metrics

Check a service's current resource usage — CPU, memory, and disk — from the terminal:

$ nanorack metrics web
$ nanorack metrics web -o json   # machine-readable

The dashboard graphs the same signals (plus network throughput) per service.

Platform Status

Live operational status for the Nanorack control plane, data plane, and internal network — with 90 days of uptime history — is published on the status page.

CLI Reference

The nanorack CLI is the primary way to interact with the platform. All commands run from your project directory, where they pick up the stage coordinate from your manifest.

Command Description
nanorack login Authenticate via the browser and save a token locally.
nanorack deploy <path> Converge the stage to the manifest: declared services are created or updated, and services no longer in the file are stopped. Use --dry-run to preview the plan, and --purge to delete undeclared services (destroying their volumes) instead of stopping them.
nanorack purge <service> Tear down a stopped service, destroying its volumes and releasing its ports.
nanorack logs <service> Stream the service's live logs. Add a time or filter flag — --since <dur>, --start/--end, -f/--filter <text>, -n/--limit <n> — to query up to 7 days of history instead.
nanorack metrics <service> Print the service's latest CPU, memory, and disk telemetry. Add -o json for machine-readable output.
nanorack get <service> Print live runtime state: status, replica count, domain, and public endpoints. Add -o json for machine-readable output.
nanorack secret set <KEY> <VALUE> Set a stage-level secret.
nanorack registry set <REGISTRY> <USER> <PASS> Set a project-level private registry credential (e.g. ghcr.io).