Skip to Content
ConfigurationMulti-Repo & Shared Clusters

Multi-Repo & Shared Clusters

Nanokit supports two project architectures: Monorepo (single nanokit.yml for all services) and Multi-Repo (each application lives in its own repository but shares a common cluster).


Monorepo (Default)

A monorepo places all services under one nanokit.yml. This is the default and simplest setup.

my-platform/ ├── apps/ │ ├── auth/ # Auth microservice │ ├── billing/ # Billing microservice │ └── api/ # API gateway ├── packages/ │ └── shared/ └── nanokit.yml # ← single config for everything

nanokit.yml (monorepo):

name: my-platform version: "1" services: auth: runtime: node path: ./apps/auth expose: 3001 host: auth.my-platform.localhost billing: runtime: node path: ./apps/billing expose: 3002 host: billing.my-platform.localhost api: runtime: node path: ./apps/api expose: 3000 host: my-platform.localhost environments: local: infra: provider: docker

Deploy:

nkdev up # launches all services nkdev up auth # launches only the auth service

[!TIP] In a monorepo, all services share the same gateway, Docker network, and state file. Cross-service communication uses internal container DNS (e.g., nk-my-platform-local-auth).


Multi-Repo

In a multi-repo setup, each application repository has its own nanokit.yml but all repos share a common Nanokit cluster (Docker daemon on a VPS, or the same ECS/VPC on AWS).

Key Concepts

ConceptDescription
nameThe project name — must be the same in all repos to share infrastructure.
componentA unique identifier for each repo within the project. Prevents cross-repo resource deletion.
infra.sharedSet to true in secondary repos. Tells Nanokit to adopt existing infrastructure instead of creating it.

How it Works

┌────────────────────────────────────────────────┐ │ Cluster: "my-platform" / local │ │ │ │ ┌──────────────────┐ ┌──────────────────┐ │ │ │ repo-auth │ │ repo-billing │ │ │ │ component: auth │ │ component: bill │ │ │ │ │ │ │ │ │ │ [nk-auth-svc] │ │ [nk-bill-svc] │ │ │ └──────────────────┘ └──────────────────┘ │ │ │ │ [Shared Gateway] ← auto-discovers both │ └────────────────────────────────────────────────┘

The Nanokit Reconciler uses the nk-component Docker/AWS tag to scope ownership: each repo only creates, updates, or deletes containers that belong to its own component.

Step-by-Step Setup

1. Infra Owner Repo

One repository is designated as the infrastructure owner. It provisions the cluster, gateway, and shared networking.

repo-infra/ ← or repo-auth if it's the "main" app └── nanokit.yml
# repo-auth / nanokit.yml name: my-platform # ← shared project name component: auth # ← this repo's component ID services: auth: runtime: node path: . expose: 3001 host: auth.my-platform.localhost environments: local: infra: provider: docker # no shared: true here — this repo OWNS infra
# In repo-auth nkdev up

This creates the Docker network, Caddy gateway, and the auth containers.


2. Secondary Repos

Secondary repos add component and infra.shared: true.

repo-billing/ └── nanokit.yml
# repo-billing / nanokit.yml name: my-platform # ← same project name as repo-auth component: billing # ← different component ID services: billing: runtime: node path: . expose: 3002 host: billing.my-platform.localhost environments: local: infra: provider: docker shared: true # ← adopts existing gateway/network, does NOT create one
# In repo-billing nkdev up

[!IMPORTANT] infra.shared: true tells Nanokit not to create or modify the Docker network and gateway. The infra-owner repo must have already run nkdev up at least once.


Cross-Service Communication

Services from different repos can communicate directly over the shared Docker network using container DNS names:

# From billing service → call auth http://nk-my-platform-local-auth:3001/validate # Or via the exposed host (through the gateway) http://auth.my-platform.localhost/validate

The shared Caddy gateway auto-discovers all components and routes correctly:

auth.my-platform.localhost → nk-my-platform-local-auth:3001 billing.my-platform.localhost → nk-my-platform-local-billing:3002

Multi-Repo on AWS (ECS / Fargate)

The same pattern applies to cloud deployments. The infra-owner repo creates the VPC, NLB, and ECS cluster. Secondary repos attach their services to the existing cluster.

Infra-owner (repo-auth):

name: my-platform component: auth environments: prod: infra: provider: aws region: us-east-1 # No shared: true — this repo owns the VPC and ECS cluster

Secondary (repo-billing):

name: my-platform component: billing environments: prod: infra: provider: aws region: us-east-1 shared: true # ← adopts VPC/NLB/Cluster created by repo-auth

[!WARNING] Destroy operations (nkdev destroy) in a secondary repo will only remove its own services (tagged nk-component: billing). The shared VPC and cluster are never touched.


State Management

SetupState Location
Monorepo / Local Docker.nanokit/ in the project directory
Cloud provider (AWS, DO, …)~/.nanokit/clusters/<provider>_<project>_<env>/
Multi-repo with shared: trueSame ~/.nanokit/clusters/ directory, shared across repos

The global state store ensures all repos working on the same cluster have a consistent view of deployed resources.


Reference: component and shared Fields

component

# nanokit.yml component: auth # Optional. Defaults to `name` if omitted.
Single-repoMulti-repo
DefaultSame as nameSet explicitly per repo
EffectNo isolation neededScopes all resource ownership
Tag appliednk-component: <name>nk-component: auth etc.

infra.shared

infra: provider: docker shared: true # Optional. Default: false.
shared: false (default)shared: true
Creates gateway, network, VPCAdopts existing gateway/VPC
Full infrastructure ownerService-only deployment
Use in infra-owner reposUse in secondary repos