Installation
Installing Nucleus means installing one binary: the nucleus CLI. This page
covers the requirements, the install command, and how an application picks
its database driver — each driver is a module the application imports.
Requirements
- Go 1.26 or newer (matches the
godirective ingo.mod) - One database: SQLite, PostgreSQL, MySQL, SQL Server or Oracle — the driver is a module your application imports (see below)
- Optional: Redis, for the Redis session store and the background-task runtime
Budget a few minutes for the first build. A fresh
nucleus new --template api application, which starts on SQLite, resolves
95 modules and links to a 42.7 MB binary (29.2 MB stripped); without the
driver import it is 82 modules and 36.8 MB (25.4 MB stripped). Measured on
darwin/arm64 with Go 1.26.9. Each driver module links its own engine and no
other. A cold go build downloads that graph once; warm builds are seconds.
Install the CLI
go install github.com/jcsvwinston/nucleus/cmd/nucleus@latest
This places the nucleus binary in $GOBIN (or $GOPATH/bin). Make sure
that directory is on your PATH.
Verify the install:
nucleus --version
nucleus doctor
nucleus doctor reads the project's nucleus.yml and checks the
framework subsystems it configures — the jobs provider, outbox, storage,
observability exporters, tenancy, RBAC, security posture and the
authentication chain. Optional subsystems you have not enabled are
reported as not configured (-) and do not count against the verdict,
so a freshly scaffolded project reports Overall Status: HEALTHY.
Warnings are reserved for half-configured subsystems, errors for broken
ones.
Run from a directory without a nucleus.yml, it checks the built-in
defaults — useful to confirm the binary works, but the interesting run is
inside a project.
Run the CLI from a container image
Releases also publish the CLI as a container image on GitHub Container
Registry, built for linux/amd64 and linux/arm64:
docker run --rm ghcr.io/jcsvwinston/nucleus:<version> --version
The image entrypoint is the CLI, so everything after the image name is
arguments to nucleus. To run it against a project, mount the project and
work from there:
docker run --rm -v "$PWD:/work" -w /work \
ghcr.io/jcsvwinston/nucleus:<version> doctor
Tags follow the releases, without the leading v the git tag carries: release
v1.2.3 publishes ghcr.io/jcsvwinston/nucleus:1.2.3. latest moves only
for releases that are not prereleases, so a release candidate never becomes
what a bare docker pull hands out. Pin the version tag, or the digest,
anywhere the answer matters.
The image runs as uid 65532 on a distroless base — no shell and no package
manager — so docker run … sh has nothing to start, and mounted files have
to be readable by that uid. Releases cut before the image pipeline existed
have no image; the repository's Packages page lists the tags that do.
Each image is signed and carries a build provenance attestation, the same way the release archives do. Verifying a release has the commands.
What gets installed
The nucleus binary is the only artifact of a go install. There is no
daemon, no agent, no global configuration file. Each project ships its own
nucleus.yml and reads it from the project root by default.
Database drivers are modules
The framework links no database driver. Each engine ships as its own Go
module — drivers/sqlite, drivers/postgres, drivers/mysql,
drivers/mssql, drivers/oracle — and an application imports the one it
uses for its side effect, the way database/sql drivers have always been
wired. nucleus new already writes the SQLite import into main.go;
switching engines is one command, which runs go get and adds the blank
import:
nucleus add postgres # or mysql, sqlite, sqlserver, oracle
Set a database_url for an engine whose module is not imported and the
application refuses to start, printing the go get and import _ lines to
add. Every driver is pure Go, so no C toolchain is needed for any of them.
A module registers two things: the database/sql driver, and the code that
recognises the engine's unique-constraint errors, which is what makes
db.IsUniqueViolation answer true for a duplicate key. Import a driver
package yourself instead — github.com/go-sql-driver/mysql, say — and the
application starts, but nothing recognises those errors and
db.IsUniqueViolation answers false for every one of them. The
application says so once at startup, with a warning that names the engine
and the module to import (or the driver.RegisterUniqueViolation call to
make if you keep your own driver). PostgreSQL is the exception: its errors
are recognised whichever driver you use.
The nucleus CLI itself links all five engines: it is a tool you install
once and point at whatever database is in front of it, and nucleus migrate
has to work there without a rebuild.
The same pattern covers the other optional pieces: the telemetry exporters
(nucleus add otlp, nucleus add prometheus), the cloud storage backends
(nucleus add s3|gcs|azure), the LDAP authentication backend
(nucleus add ldap), SAML sign-in (nucleus add saml, see
SAML sign-in) and the Sentry error reporter
(nucleus add sentry, see Error reporting).
nucleus add --help lists them all.
Updating
Re-running go install …@latest overwrites the binary in place.
The CLI follows semantic versioning. On the stable v1.x line, minor and
patch upgrades never remove a frozen surface — removals need a new major
version and a deprecation record first. The
CHANGELOG
lists what each release adds.