Help us shape the future of Go! Take the 2026 Go Developer Survey

nemo

module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 27, 2026 License: Apache-2.0

README

nemo

nemo

Ship applications made of containers to any Docker host, as versioned packages.
Compose on one machine, Swarm on many: from a laptop, a CI pipeline, or a site with no network.

Release Latest release CNAB 1.2

Getting started · Concepts · Use cases · Documentation · CLI reference


Your application is a dozen services described in compose files. Deploying it means building images, pushing them, copying files to servers, running docker compose up or docker stack deploy in the right order, passing the right secrets, and remembering what is running where. Every team ends up writing that glue, and every environment drifts from the others.

nemo replaces the glue. It turns each compose file into a bundle: one versioned package that carries the services, their images pinned by digest, and the installer that deploys them. Bundles are grouped into a stack, which says where they go and with what settings. nemo up brings the target to the stack: in dependency order, with live progress, and with a record of every run.

$ nemo up
shop · swarm · 4 installations

✔ database  install    2 services · 2 volumes · 1 network  9.4s
✔ broker    install    1 service · 1 volume · 1 network   6.1s
⠼ api       install    1/3 services ready  4.2s
    ✔ api-http    ▰▰       2/2   running
    ◌ api-worker  ▰▱       1/2   verifying
    ◌ api-cron    ▱        0/1   preparing
· frontend  install    waiting

Why nemo

  • Keep your compose files. A bundle is your compose file plus a few lines of metadata. Services, networks, volumes, configs, secrets, healthchecks and deploy settings keep their meaning.
  • One package per component, versioned. Images are pinned by digest inside the bundle: what you tested is exactly what runs, on every node.
  • Stacks instead of scripts. Declare the components and their dependencies once; nemo installs dependencies first, upgrades what is there, and uninstalls what you removed.
  • Anywhere Docker runs. Compose on a single host, Swarm on one to many nodes, reached through the local socket, ssh://, tcp:// or a docker context. One bundle runs on all of them unchanged.
  • No registry required. Copy bundles onto a disk, carry them to a site with no network, and nemo loads their images straight into the target's Docker.
  • Secrets stay where they are. Credentials are read from files, environment variables or commands when an action runs. nemo never stores them.
  • Know what runs. nemo status, nemo logs, and the history of every install, upgrade and uninstall, with its parameters and outputs.
  • Built on standards. Bundles are CNAB 1.2, stored in any OCI registry or OCI layout. Records follow the CNAB claims specification.

Install

Homebrew (macOS and Linux):

brew install sntns/tap/nemo

Binaries for Linux, macOS and Windows, amd64 and arm64, are attached to every release.

From source, with Go 1.26 or later:

go install github.com/sntns/nemo/cmd/nemo@latest

nemo talks to Docker through its API: the machine you run it on needs no Docker of its own when the target is remote, only the target runs Docker Engine. For shell completion, see nemo completion --help.

A first deployment in five minutes

The examples/hello stack has two bundles: nginx, which serves a page and a secret, and whoami, which depends on it. Build both bundles from their compose files, keep the stack, and bring it up on your local Docker:

git clone https://github.com/sntns/nemo && cd nemo

nemo bundle build -f examples/hello/nginx/compose.yaml \
  --image nginx:1.27-alpine=docker://nginx:1.27-alpine -o oci:examples/hello/build/nginx.oci
nemo bundle build -f examples/hello/whoami/compose.yaml \
  --image traefik/whoami:v1.10=docker://traefik/whoami:v1.10 -o oci:examples/hello/build/whoami.oci

nemo stack import examples/hello/stack.yaml
export HELLO_TOKEN=s3cret
nemo up
$ curl localhost:8080
hello from nemo in eu5
$ nemo status
hello · compose

✔ nginx   1.0.0  installed just now  1/1 services
✔ whoami  1.0.0  installed just now  1/1 services

Then change a setting and apply it, follow the logs, and remove everything:

nemo stack set --param region=eu6 && nemo up    # upgrades both installations
nemo logs nginx -f
nemo down --purge

The getting started guide walks through each step.

How it works

flowchart LR
    compose["compose.yaml<br/>+ x-nemo-bundle"] -- "nemo bundle build" --> bundle[("bundle<br/>registry or OCI layout")]
    bundle --> manifest["stack manifest<br/>target · parameters · credentials"]
    manifest -- "nemo up" --> nemo["nemo"]
    nemo -- "runs, on the target" --> gill["gill<br/>(installer container)"]
    gill -- "Compose or Swarm" --> app["services · networks<br/>volumes · configs · secrets"]
    nemo -. "keeps" .-> history[("history<br/>~/.nemo")]
  1. Build. nemo bundle build reads a compose file with an x-nemo-bundle block and makes a CNAB bundle: its ${VARIABLES} become parameters, its secrets become credentials, its images are pinned by digest, and gill, nemo's installer, becomes its invocation image. The bundle is written to a registry or to an OCI layout directory, with its images.
  2. Describe. A stack manifest lists the bundles to install on one target, the target's orchestrator and address, and the parameters and credential sources the bundles need.
  3. Deploy. nemo up orders the bundles by their dependencies, and for each one starts gill on the target with the Docker socket. gill applies the compose project with Compose or Swarm, labels everything it creates, and waits until the services are up. nemo shows the progress and records the run.

There is no server and no agent: nemo keeps its records on the machine it runs on, and gill only lives for the duration of an action. Read how it works for the details.

What you can do with it

You want to nemo gives you
Give every developer the whole platform on their machine One nemo up; nemo up api after rebuilding one component
Spin up a fresh environment for each pull request nemo up and nemo down --purge in CI, with --json records
Deploy to customer sites, factories, stores, edge boxes Bundles over ssh://, Compose on a single host
Run production on a Swarm cluster Rolling updates, versioned configs and secrets, verified convergence
Install where there is no network nemo bundle copy to a disk, images: load on the target
Ship your software to customers Versioned bundles they configure with nemo stack create

Each one is described in use cases.

Documentation

Getting started Install nemo and deploy a first stack
Concepts Bundles, gill, targets, stacks, installations
How it works What happens when you build, deploy and remove
Use cases Development platforms, CI, edge, Swarm, offline sites, software vendors
Writing bundles From a compose file to a versioned bundle
Managing stacks Manifests, parameters, credentials, dependencies, up and down
Targets Compose or Swarm, remote Docker, registries or no registry, volume types
Continuous delivery Build, publish and deploy from a pipeline
Offline sites Deploy without network or registry
Reference Every command, the manifest, the bundle format, the environment
Comparison nemo next to Compose, Swarm stacks, Porter, Helm and scripts
Troubleshooting Common errors and how to read them

Contributing

Bug reports, ideas and pull requests are welcome: read CONTRIBUTING.md. Please report security issues privately, as described in SECURITY.md. Everyone taking part follows the code of conduct.

License

nemo is licensed under the Apache License 2.0. Copyright 2026 Sentiens SAS.

The nemo logo is derived from the Go gopher, designed by Renée French and licensed under CC BY 4.0. See docs/assets.

Directories

Path Synopsis
cmd
gill command
Command gill is the entrypoint of nemo's invocation image, /cnab/app/run.
Command gill is the entrypoint of nemo's invocation image, /cnab/app/run.
nemo command
Command nemo deploys CNAB bundles to Docker, with Compose or Swarm.
Command nemo deploys CNAB bundles to Docker, with Compose or Swarm.
internal
decode
Package decode reads the documents nemo is given, YAML or JSON once parsed, into its types.
Package decode reads the documents nemo is given, YAML or JSON once parsed, into its types.
testimage
Package testimage writes images for tests, without a registry.
Package testimage writes images for tests, without a registry.
pkg
bundle
Package bundle builds nemo bundles from a compose project, and moves them between registries and OCI layout directories.
Package bundle builds nemo bundles from a compose project, and moves them between registries and OCI layout directories.
credentials
Package credentials resolves the credentials of an action from their sources, the strategies of a CNAB credential set (cnab-spec 802-credential-sets.md), as Porter writes them:
Package credentials resolves the credentials of an action from their sources, the strategies of a CNAB credential set (cnab-spec 802-credential-sets.md), as Porter writes them:
docker
Package docker is the installer's client of the Docker Engine for what every Docker has: a Client that creates, finds and deletes networks, volumes, containers and images from their specs, one file per kind.
Package docker is the installer's client of the Docker Engine for what every Docker has: a Client that creates, finds and deletes networks, volumes, containers and images from their specs, one file per kind.
installer
Package installer is the invocation image side of nemo: it reads the operation a CNAB runtime hands to the container and applies the bundle's compose project to the target with the Orchestrator the target names.
Package installer is the invocation image side of nemo: it reads the operation a CNAB runtime hands to the container and applies the bundle's compose project to the target with the Orchestrator the target names.
installer/compose
Package compose is the Compose orchestrator: it applies a compose project to one Docker as plain containers, the way docker compose up --wait does, and labels them the way docker compose does, so that docker compose ps and logs still see them.
Package compose is the Compose orchestrator: it applies a compose project to one Docker as plain containers, the way docker compose up --wait does, and labels them the way docker compose does, so that docker compose ps and logs still see them.
installer/compose/convert
Package convert turns a compose project into what the Compose orchestrator creates on the Docker Engine: the create options of each container, its networks and volumes, and the state to wait for, the way docker compose does.
Package convert turns a compose project into what the Compose orchestrator creates on the Docker Engine: the create options of each container, its networks and volumes, and the state to wait for, the way docker compose does.
installer/swarm
Package swarm is the Swarm orchestrator: it applies a compose project to a swarm as services, the way docker stack deploy does, and waits until they converged.
Package swarm is the Swarm orchestrator: it applies a compose project to a swarm as services, the way docker stack deploy does, and waits until they converged.
installer/swarm/convert
Package convert turns a compose project into the specs of Swarm objects, the way docker stack deploy does (docker/cli, cli/compose/convert).
Package convert turns a compose project into the specs of Swarm objects, the way docker stack deploy does (docker/cli, cli/compose/convert).
labels
Package labels holds the labels nemo puts on everything the installer creates.
Package labels holds the labels nemo puts on everything the installer creates.
nemo
Package nemo is nemo's API.
Package nemo is nemo's API.
progress
Package progress is how long operations report what they do.
Package progress is how long operations report what they do.
runtime
Package runtime runs the actions of a bundle's installations, as a CNAB runtime: it builds the claim, hands the operation to the driver that runs the invocation image, and returns the claim, its result and its outputs.
Package runtime runs the actions of a bundle's installations, as a CNAB runtime: it builds the claim, hands the operation to the driver that runs the invocation image, and returns the claim, its result and its outputs.
stack
Package stack is the desired state of a stack: the target, the installer, and the installations to make there, by their spec: a bundle, its parameters and the sources of its credentials.
Package stack is the desired state of a stack: the target, the installer, and the installations to make there, by their spec: a bundle, its parameters and the sources of its credentials.
storage
Package storage keeps what nemo knows of its installations, as Porter keeps it: an Installation, its spec and how its last action went, and for each action its Run, the CNAB claim with the bundle it ran, its Result and its outputs, documents of cnab-spec 400-claims.md.
Package storage keeps what nemo knows of its installations, as Porter keeps it: an Installation, its spec and how its last action went, and for each action its Run, the CNAB claim with the bundle it ran, its Result and its outputs, documents of cnab-spec 400-claims.md.
storage/file
Package file is a store in a local directory, one per installation, in the directory of its stack, next to the stack's manifest:
Package file is a store in a local directory, one per installation, in the directory of its stack, next to the stack's manifest:
target
Package target describes where a bundle is deployed, and where its installer runs.
Package target describes where a bundle is deployed, and where its installer runs.
transfer
Package transfer carries a bundle's images into the target's daemon, with no registry in between.
Package transfer carries a bundle's images into the target's daemon, with no registry in between.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL