Skip to Content
ConfigurationGlobal Runtimes

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: 3000

Auto-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 DetectedInferred Runtime
package.jsonnode
requirements.txtpython
go.modgo
composer.jsonphp
Gemfileruby
index.htmlstatic

[!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:

  1. Service Configuration: Explicit values in services.[name].
  2. Global Runtime: Defaults from the assigned (or inferred) runtimes.[id].
  3. Environment Overrides: Overrides defined in environments.[env].services.[name].
  4. System Defaults: Built-in fallbacks (e.g., the default node image).

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 tools

In 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.