# Nanocl defaults to the nightly branch and its news section stops at 2024

> A Rust orchestrator that stores cluster state in CockroachDB and drives it with YAML, TOML or JSON Statefiles. The repository's default branch is nightly, the Quick Start pins ApiVersion v0.16 while the current release is 0.18.1, and the Latest news list ends in November 2024.

**next-hat/nanocl** — Work in progress distributed system that simplifies the orchestration of containers and virtual machines.

- Repository: https://github.com/next-hat/nanocl
- Website: https://next-hat.com
- Stars: 996 · Forks: 53
- Language: Rust
- License: Apache-2.0
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/next-hat-nanocl

## The default branch is nightly, so a clone is not a release

The repository's default branch is `nightly`. That single fact reframes everything else about how you adopt this: `git clone` gives you the head of a moving branch rather than a tagged release, and the release feed is per binary rather than per project. The three most recent releases are `nanocld-0.18.1` and `nanocl-0.18.1`, both published on 2026-09-26, and `ncproxy-0.15.1` from 2026-09-16. So the daemon, the client and the proxy are not on the same version number, and the gap between the proxy and the rest is three minor releases. Nothing in the visible text says which combinations are supported, so picking binaries is an exercise in matching tags yourself. For a system whose whole argument is reproducibility between environments, the branch default is the first thing to override.

## Quick Start pins ApiVersion v0.16 while releases read 0.18.1

The smallest Statefile in the README declares `ApiVersion: v0.16`, and the documentation Statefile used to deploy the project's own docs does the same. The releases are at 0.18.1. The gap is small on paper and awkward in practice, because a Statefile is the unit of deployment and its version field is how a daemon decides whether it can act on it. Two versions of drift between the documented example and the shipped daemon is exactly the kind of thing that turns into an afternoon of error messages, and no migration note appears in the visible text. Check what your installed `nanocld` accepts before copying the example, and treat the version field in your Statefiles as something to bump deliberately.

## Canonical keys are namespace.name, and the flags are asymmetric

Cargoes and virtual machines are addressed by a canonical key in `{namespace}.{name}` order, with `global.hello` and `system.ncproxy` given as the examples. The flag behaviour around that is not symmetric, and it is the kind of detail that produces confusing errors. Collection commands return every namespace by default and narrow with `nanocl cargo ls --namespace system`. Commands that target an object which already exists take the full key directly and accept no namespace option at all. Creation commands still default to the `global` namespace when `--namespace` is omitted. In practice that means `nanocl cargo logs global.hello` is the correct form and adding `--namespace global` to it is not, which is a reasonable design and an easy thing to get wrong the first time.

## Four apply-and-inspect commands cover the whole loop

The operational loop is four commands, and the Statefile is the document in the middle of it:

```bash
nanocl state apply -s ./state.yml
nanocl cargo ls
nanocl cargo logs global.hello
nanocl state rm -s ./state.yml
```

Apply takes the file, the list shows what exists, logs take the canonical key, and removal takes the same file it applied from. There is no separate verb for a single object, no edit command and no patch in what the README shows, so a change to a running system means changing the Statefile and re-applying it. That is the declarative bargain, and it means the Statefile has to be under version control to be usable in practice. Listing and inspection are the escape hatch for when the file and reality disagree, which is also why the audit, logs and health-check surfaces matter more here than in a system where you can patch a deployment directly.

## Cluster state is CockroachDB in single-node mode

The state store is not a sidecar or an embedded database but CockroachDB, pinned in the development compose file to `docker.io/cockroachdb/cockroach:v25.4.13` and started with `cockroach start-single-node`, listening on 26257 and exposing a SQL port on 26258. Both ports are published to the host. State lives under a `STATE_DIR` that defaults to `${HOME}/.nanocl_dev/state`, and the service carries a full set of `io.nanocl.*` labels describing itself to the system it is part of: kind, namespace, name, replica id, ordinal, role `app`, `essential=true`, network mode and position. That labelling is the mechanism by which the orchestrator recognises its own infrastructure, and it is worth reading if you ever inspect state directly.

## The compose file ships with its certificate generation commented out

The store's startup command in `docker-compose.yaml` contains a block that would create a certificate authority, a node certificate and a client certificate under `$STATE_DIR`, and the whole block is commented out with a leading hash on each line. What remains is the `cockroach start-single-node` invocation with its listen and SQL addresses. So the development compose file runs the store without the certificate steps its own comments describe, and the TLS story has to come from elsewhere. The documentation points at a TLS secret page for certificate persistence and calls the end-to-end TLS support in progress, including internal mesh primitives. The network definition is also more than a default bridge: `nanoclbr0` sets `driver_opts` with `com.docker.network.bridge.name`, so the host interface name is fixed rather than generated.

## The release profile optimizes for size, and four crates are patched locally

The workspace manifest has nine members, four library crates under `crates/`, two client and error crates patched from local paths, and five binaries: `ncproxy`, `ncdns`, `ncvpnkit`, `nanocld` and `nanocl`. The release profile is tuned hard: `strip = true`, `opt-level = "z"`, `lto = true`, `codegen-units = 1`. That combination trades compile time and debuggability for a small binary, which fits the project's claim of a minimal host footprint. The `[patch.crates-io]` section redirects `nanocl_error`, `nanocl_stubs`, `nanocl_utils` and `nanocld_client` to local paths, and a fifth entry for `bollard-next`, the Docker API client, sits commented out pointing at a fork branch. That last line is the one to notice: the container layer depends on a forked client that is not currently part of the default build.

## The Latest news list stops in November 2024

The news section runs newest first and its top two entries are a release note for Nanocl 0.18.0 with no date and a blog post about automating deployment with GitHub Actions dated 24.11.2024. Below that come end-to-end TLS and the first step toward network meshing on 01.11.2024, a man page and backup post on 11.06.2024, a Merge Berlin event on 01.06.2024, and context and SubState on 07.05.2024. Every dated item is from 2024, while the releases themselves are dated 2026. The changelog therefore does not describe the current line, and the newest release it mentions, 0.18.0, predates the shipped 0.18.1. Combined with a `nightly` default branch, the practical consequence is that the release notes on the documentation site and the tag you run can be a year apart without the README showing it.

## Conclusion

Nanocl is worth reading if you run a handful of services and find docker-compose limiting but a full Kubernetes control plane heavier than the problem, since its pitch is a declarative model shared between development and production without the operational weight. Two things argue for caution. The default branch is `nightly`, so a clone gives you the moving target rather than a release, and the release train is per-binary: nanocld and nanocl both shipped 0.18.1 on 2026-09-26 while ncproxy was still on 0.15.1 from 2026-09-16, so mixing artifacts across binaries is a choice you have to make deliberately. And the documentation set has drifted: the Quick Start example declares `ApiVersion: v0.16` and the Latest news list stops in November 2024. Pin a release, read the health-check and TLS secret pages, and expect to reconcile the version in your Statefiles yourself.

## FAQ

### What is Nanocl and what does it replace?

It is an open source distributed system written in Rust for orchestrating containers and virtual machines, aimed at platform engineers who want multi-tenant isolation and predictable performance without operating a full Kubernetes control plane. The framing in the README is that you rebuild Kubernetes inside Nanocl only if you want to.

### How do you install Nanocl quickly?

Run `curl -fsSL https://download.next-hat.com/scripts/get-nanocl.sh | sh`, which requires Docker, then complete the post-installation steps the README links to. Linux, macOS and Windows are supported, and a single-node install is described as taking under two minutes when you are only evaluating.

### What is a Statefile in Nanocl?

It is the declarative document that drives everything, written in YAML, TOML or JSON, and it stays identical across development and production. You act on it with `nanocl state apply -s ./state.yml` and remove it with `nanocl state rm -s ./state.yml`.

### Which services make up the Nanocl architecture?

Five modular containerized services: nstore persists cluster state, ndaemon exposes the REST API and control surface, nmetrics collects resource usage, ncproxy is a proxy controller with an embedded nginx data plane, and ncdns is a DNS controller with an embedded dnsmasq data plane. The last two are marked optional.

### What database does Nanocl use for cluster state?

CockroachDB. The development compose file pins `cockroachdb/cockroach:v25.4.13` and starts it with `cockroach start-single-node`, listening on port 26257 with the SQL port on 26258.

### Which licence applies to Nanocl?

The repository root carries both `LICENSE-APACHE` and `LICENSE-MIT` alongside `SECURITY.md` and `CONTRIBUTING.md`, and the project is recorded under Apache-2.0. The visible text does not state how the two files divide the work.

## Sources

- [License: Apache-2.0](https://github.com/next-hat/nanocl/blob/nightly/LICENSE)
- [next-hat/nanocl on GitHub](https://github.com/next-hat/nanocl)
- [Project website](https://next-hat.com)
- [README](https://github.com/next-hat/nanocl/blob/nightly/README.md)
- [Releases](https://github.com/next-hat/nanocl/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/next-hat-nanocl
