Global Runtimes
Global Runtimes allow you to define common execution environments once and reuse them across all services in your project. This reduces boilerplate in nanokit.yml and ensures identical provisioning across similar workloads.
The runtimes Block
Runtimes are defined at the top level of your nanokit.yml. Each runtime can specify a Docker image, environment variables, and provisioning steps.
runtimes:
node:
image: node:22-slim
provisioning:
install: npm install --prefer-offline
env:
NODE_ENV: production
services:
api:
runtime: node # Inherits image, install command, and env from above
path: ./apps/api
port: 3000Auto-Discovery
If a service definition omits both image and runtime, Nanokit will attempt to automatically infer the runtime by scanning the service directory for specific project files.
| File Detected | Inferred Runtime |
|---|---|
package.json | node |
requirements.txt | python |
go.mod | go |
composer.json | php |
Gemfile | ruby |
index.html | static |
[!TIP] Even if you use auto-discovery, you can still define a global
runtimes.[id]block to customize the defaults applied to those inferred services.
Inheritance Hierarchy
Nanokit resolves the final configuration of a service using a strict priority order:
- Service Configuration: Explicit values in
services.[name]. - Global Runtime: Defaults from the assigned (or inferred)
runtimes.[id]. - Environment Overrides: Overrides defined in
environments.[env].services.[name]. - System Defaults: Built-in fallbacks (e.g., the default
nodeimage).
Example: Mixed Runtimes
runtimes:
node:
image: node:22-slim
static:
image: nginx:latest
services:
web:
runtime: node
path: ./apps/web
docs:
runtime: static
path: ./apps/docs
## Structural Dependencies (`depends_on`)
Runtimes can define global dependencies. When a service uses a runtime with a `depends_on` block, it automatically inherits those dependencies in the project's execution graph.
This is a powerful pattern for **Shared Resource Provisioning**. For example, ensuring that all lightweight "slim" containers wait for a full-featured container to initialize a shared `node_modules` volume:
```yaml
runtimes:
node:
image: node:22-slim
depends_on:
- hub # All services using 'node' will wait for 'hub'
node-full:
image: node:22 # Full image with build toolsIn this setup, you don’t need to manually add depends_on to every service; they inherit the “wait for hub” behavior automatically through their runtime.
## Auto-Injected Variables
Every service managed by Nanokit automatically receives a set of "Transparent Metadata" variables in its environment:
### Core Metadata
- `NANOKIT_PROJECT`: The name of the current project.
- `NANOKIT_SERVICE`: The name of the current service.
- `NANOKIT_ENV`: The current active environment (local, stage, etc).
### Service Discovery
Nanokit automatically resolves and injects the URLs of all services defined in the environment:
- `NANOKIT_URL_<SERVICE_NAME>`: The primary hostname of the sibling service (e.g., `NANOKIT_URL_DOCS`).
> [!IMPORTANT]
> **Framework Exposure**: These variables use the generic `NANOKIT_` prefix. For frameworks like Next.js that require a `NEXT_PUBLIC_` prefix for client-side access, you should map them in your `next.config.js`. Nanokit's standard boilerplate includes an automatic mapper for this purpose.