Appearance
Getting Started with Nanokit
Nanokit is a developer-first container orchestration platform built around a single config file — nanokit.yml. This guide walks you from zero to a running local environment, then all the way through staging and production deployment.
Prerequisites
Before you begin, make sure the following are in place:
| Requirement | Notes |
|---|---|
| Docker | Must be running locally. Used by nkapp up -e local. |
| nkapp CLI | Install via npm install -g @nkapp/cli or your package manager of choice. |
| SSH key pair | Required for VPS-based environments (staging, production). |
| A VPS | Any Linux server accessible over SSH. Root access is recommended for first-time bootstrapping. |
Note. You do not need Kubernetes or any cloud provider to get started. Nanokit runs on plain Docker — locally and on remote servers.
Step 1 — Initialize Your Project
Navigate to your project root and run:
bash
nkapp initThis scaffolds a nanokit.yml file in the current directory with sensible defaults derived from your project structure.
If you prefer an interactive setup wizard, use nkapp configure instead:
bash
nkapp configurenkapp configure walks you through naming your project and defining its initial services. It is the recommended path if you are new to Nanokit.
configure only runs on a fresh project
If a nanokit.yml already exists, nkapp configure refuses to run and points you at nkapp service add. It is a scaffolder, not an editor. To change an existing configuration use nkapp service add, nkapp config set, or edit the YAML directly.
Step 2 — Understand nanokit.yml
nanokit.yml is the single source of truth for your entire project. It defines your services and how they behave across every environment.
Here is a realistic minimal example:
yaml
name: my-app
services:
api:
runtime: node
port: 3000
start: node dist/index.js
host: api.my-app.localhost
env:
NODE_ENV: development
environments:
local:
infra:
provider: docker
services:
api:
start: npm run dev
stage:
infra:
provider: docker
deploy:
target: root@185.47.172.104
sshKey: ~/.ssh/id_rsa
method: rsync
prepare: npm ci && npm run build
services:
api:
host: api.my-app.com
env:
NODE_ENV: productionKey concepts:
services— the top-level block defines service defaults shared across all environments. Each service gets aruntime, aport, astartcommand, and an optionalhostfor routing.environments.local— overrides for local development. Here,apiusesnpm run dev(hot-reload) instead of the production start command. Theprovider: dockermeans Nanokit manages everything through local Docker.environments.stage— adds adeployblock pointing to a remote VPS. Thepreparecommand runs on the server (in an isolated runtime container) after the code sync and before the reconcile. Service-level overrides (likehostandenv) replace the defaults for this environment only.- Environment promotion — the same
nanokit.ymlgoverns all environments. You promote by targeting a different environment, not by maintaining separate config files.
A non-empty per-environment services: block restricts membership
Listing any service under environments.<env>.services means only those services deploy to that environment. Root services you did not list are excluded, not merged. See Environments → Exclude by Default.
Important. Never commit secrets directly into
nanokit.yml. Use theenvblock for non-sensitive values and manage secrets separately withnkapp secrets.
Step 3 — Start Local Development
With your nanokit.yml in place, bring up your local environment:
bash
nkapp up -e localNanokit will:
- Parse
nanokit.ymland resolve thelocalenvironment block. - Resolve every
vault:///env://secret reference. - Pull or build required Docker images.
- Start all services as containers on the shared private Docker network
nanokit-net. - Start the Caddy gateway and configure HTTPS routing to each service's
.localhostdomain.
Your API will be reachable at https://api.my-app.localhost (or whatever host you configured) within seconds. If a service has no explicit host, Nanokit derives one automatically as <service>.<project>.localhost.
Trust the local HTTPS certificate
The Caddy gateway issues certificates for .localhost domains from a local Nanokit Root CA. On first run, your browser may warn you. To silence the warning permanently, install the Root CA into your system trust store with one command:
bash
nkapp host trustThis works on macOS (System Keychain), Linux (update-ca-certificates + NSS databases for Chrome/Firefox), and WSL2 (also propagates to the Windows certificate store). Fully restart your browser afterwards. See nkapp host trust for details.
Open the Hub
nkapp up starts and manages the bridge container (nk-<project>-<env>-bridge) that feeds the Hub. To open the dashboard:
bash
nkapp hubThe Hub gives you a live view of running containers, resource usage, and log streams for every service in your project.
Step 4 — Run a Health Check
Before you start building in earnest, verify your environment is fully healthy:
bash
nkapp doctornkapp doctor is read-only and reports on:
- System architecture support (x64 / arm64)
- Docker daemon reachability and version
nanokit.ymlsyntax and schema validity- Gateway / infrastructure status for the current project
- Cloud deploy preflight (a region must resolve for every cloud environment)
- Mail delivery configuration (when configured)
- Container hygiene — how many stale containers have accumulated
- Image space — how much Docker image space is reclaimable
- CLI freshness (whether a newer
@nkapp/cliis available)
Warning. Always run
nkapp doctorwhen switching machines or after a Docker/system update. It catches the majority of "why won't it start" issues before they become time sinks.
Fix any issues flagged by doctor before proceeding. Each problem comes with a suggested remediation step.
Step 5 — Useful Local Commands
Once your stack is running locally, these commands cover the most common day-to-day operations:
Tail logs from a service
bash
nkapp logs apiStream live log output from a container. Press Ctrl+C to stop tailing.
Open a shell inside a container
bash
nkapp shell apiDrops you into an interactive shell inside the running api container. Useful for one-off commands, inspecting the filesystem, or debugging.
Stop all local services
bash
nkapp stop -e localGracefully stops all containers for the local environment without removing them — restart instantly with nkapp start. To remove the containers (and the project network and gateway), use nkapp destroy; volumes and images are preserved either way.
Tip. Use
nkapp stop/nkapp destroyrather than rawdockercommands — they ensure the Caddy gateway and project resources are managed consistently.
Step 6 — Deploy to Staging
When your local work is ready for a shared environment, deploy to your staging VPS.
Configure the stage environment
Make sure the stage block in your nanokit.yml is populated (see Step 2). At minimum you need:
yaml
environments:
stage:
infra:
provider: docker
deploy:
target: root@<your-vps-ip>
sshKey: ~/.ssh/id_rsa
method: rsync
prepare: npm ci && npm run build
services:
api:
host: api.my-app.com
env:
NODE_ENV: productionPreview what will change
Before applying any changes to a remote environment, run a dry-run to see exactly what Nanokit would do:
bash
nkapp plan -e stageThis shows added, modified, and removed services — plus a preview of the deploy scope — without touching the server.
Provision and deploy
bash
nkapp deploy -e stagedeploy — not up — provisions a new environment
Since the up/deploy split, nkapp up no longer provisions infrastructure or syncs code by default. Against a never-provisioned remote environment it fails fast and tells you to run nkapp deploy. Use deploy for the first run and for every subsequent ship; use up for the service-only inner loop.
On first run, nkapp deploy -e stage:
- SSHes into the target server using your configured key.
- Offers to install Docker and configure the firewall if the VPS is bare.
- Ensures the private Docker network and the Caddy gateway on the host.
- Rsyncs your project code to
/opt/nanokit/projects/my-app/. - Runs the
preparecommand on the server (npm ci && npm run build). - Starts all containers and configures the gateway for your production-style domains.
Subsequent runs are change-proportional: deploy computes which services actually changed since the last successful deploy to this target and deploys only those plus their dependents. When nothing changed it prints Nothing to deploy and exits without touching the server. Force a full deploy with --all. See deploy scoping.
Pull resolved secrets locally
If your project references remote secrets (e.g. vault:// URIs), resolve them into a local .env file:
bash
nkapp secrets pull # writes .env (local environment)
nkapp secrets pull -e stage # writes .env.stageThese files contain resolved plain-text values — keep them in .gitignore and never commit them.
Step 7 — The Two Loops
Once staging exists, you have two commands with different jobs:
| Loop | Command | What it does |
|---|---|---|
| Inner — iterate on a running environment | nkapp up -e stage | Reconciles services only. No provisioning, no code sync. Fast. |
| Outer — ship a change | nkapp deploy -e stage | Syncs code, runs prepare on the host, reconciles the changed services. |
bash
# Typical workflow
git add .
git commit -m "fix: handle empty state in /api/items"
nkapp deploy -e stage
nkapp logs api # confirm the fix is liveIf you need up to behave the way it did before the split, pass --infra --sync (or --legacy).
Step 8 — Promote to Production
When staging has been validated, promote your changes to production:
bash
nkapp plan -e production # dry-run first
nkapp deploy -e production # provision (first run) and ship
nkapp up -e production # service-only reconcile afterwardsProduction environments follow the same structure as staging. Add a production block to nanokit.yml pointing to your production server(s):
yaml
environments:
production:
infra:
provider: docker
deploy:
target: root@<prod-ip>
sshKey: ~/.ssh/id_rsa_prod
method: rsync
prepare: npm ci && npm run build
services:
api:
host: api.my-app.com
env:
NODE_ENV: productionCaution. Always run
nkapp plan -e productionand review the output before deploying. Changes to production are applied immediately. If a deploy goes wrong,nkapp deploy -e production --rollbackrestores the previous reconciler state — it does not revert code on the remote host, and it is never triggered automatically.
Multi-Environment Workflow at a Glance
Local (Docker) → Staging (VPS) → Production (VPS)
nkapp up nkapp deploy nkapp deploy ← provision + ship
-e local -e stage -e production
nkapp up nkapp up ← service-only inner loop
-e stage -e productionAll three environments are driven by the same nanokit.yml. Environment-specific overrides (hosts, env vars, deploy targets) live in their respective environments.<name> blocks. There are no separate config files to keep in sync.
Next Steps
- Configuration Reference — every field in
nanokit.ymlexplained. - Secrets Management — storing and rotating secrets with
nkapp secrets. - Databases & Branching — managed databases, forks, and resets.
- Networking, Domains & TLS — configuring Caddy for production HTTPS.
- CI pipelines — scaffold a GitHub Actions / GitLab CI deploy workflow.
- CLI Reference — full command listing with all flags.