Docker replacement for Linux servers

niso

Linux-native process packaging and isolation. No daemon. No layers. No bloat.

Package your application as a compressed archive, deploy it as an isolated systemd service. Same isolation as Docker, without the Docker daemon.

0
Daemons
7.9
MB binary
57
Commands
305
Tests
18
Packages
9
Crates

“What if we built container tooling today, knowing that Linux already handles process lifecycle, resource limits, process isolation, and networking?”

“We wouldn’t build a daemon. We’d build a package format.”

That’s niso

Why niso

Everything Docker does, without the things Docker shouldn't need.

Zero Daemons

No dockerd, no containerd, no shim. systemd manages the process lifecycle — restarts, logging, boot ordering. If systemd goes down, you have bigger problems.

Tiny Packages

Redis is 1.1 MB in niso, 40 MB in Docker. No OS base layers, no bundled runtimes. Ship only your application.

Isolated by Default

Each service runs in its own environment — separate user, separate filesystem, separate network. Can't see other services or the host. Stricter defaults than Docker.

Dependencies Packaged, Runtimes Deduplicated

Your code and node_modules ship in the package. The Node.js runtime is installed once on the host and bind-mounted into each app's isolated rootfs. Full isolation — the process can't see the host.

Simple Networking

Map ports, create networks, and services discover each other by name. No extra proxy processes running in the background.

Fleet Deploy

Rolling, canary, and all-at-once deployments across servers via SSH. No Kubernetes, no control plane, no agent.

Who is niso for

Backend teams shipping Rust/Go/C++

The problem

Docker images are 300-800MB for a 12MB binary. Build cache invalidation wastes hours.

With niso

niso packages are 5-15MB. No layers, no cache, no base image. Just your binary.

Node.js/Python developers

The problem

Every app ships its own copy of the runtime. 10 apps = 10 copies of Node.js.

With niso

Your code + node_modules ship in the package. Runtime installed once, bind-mounted into isolated rootfs per app. Package size: 5-15MB.

DevOps managing VPS fleets

The problem

Docker daemon uses 200MB+ RAM on every server. Compose v1 bugs. Volume name disasters.

With niso

Zero daemons. systemd manages everything. Volumes are directories with access control.

Security-conscious teams

The problem

Docker runs everything as root. Docker socket is root-equivalent. Containers share a bridge.

With niso

Each service is fully isolated — own user, own network, can't see other services. Packages are signed. Stricter defaults than Docker.

Docker vs niso

Dockerniso
Runtime overheaddockerd + containerd + shim (~200 MB RAM)Zero (systemd is already running)
Package size (Rust binary)50-800 MB (includes OS layer)5-15 MB (just the binary)
Package size (Node.js app)300-600 MB5-15 MB (code + deps, runtime on host)
Boot time1-5 secondsInstant (systemd unit start)
IsolationKeeps extra permissions by defaultFully isolated by default
Port mappingRuns a proxy process per portNo extra processes
Service discoveryDocker socket APIDNS hostnames
Daemon requiredYes, for everythingNo

Compare sizes

niso packages vs Docker images. Same software, fraction of the size.

redis40x smaller
niso
3 MB
Docker
120 MB
nginx23x smaller
niso
3 MB
Docker
70 MB
nodejs22x smaller
niso
18 MB
Docker
390 MB
postgres10x smaller
niso
25 MB
Docker
250 MB
grafana5x smaller
niso
100 MB
Docker
450 MB
bun4x smaller
niso
45 MB
Docker
200 MB

Docker sizes from official slim/alpine images. niso packages include the application binary/code and its dependencies. Language runtimes are on the host.

Same isolation as Docker, no daemon

niso activate my-api generates this service configuration. Linux enforces the isolation directly — no container runtime sitting in between.

niso-my-api.service (auto-generated)
[Unit]
Description=niso: my-api v1.0.0
After=network-online.target
OnFailure=niso-notify@%n.service
[Service]
Type=exec
ExecStart=/opt/niso/packages/my-api/current/bin/my-api
DynamicUser=yes
Restart=on-failure
# Filesystem
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
PrivateDevices=yes
PrivateIPC=yes
ProtectProc=invisible
# Security
NoNewPrivileges=yes
CapabilityBoundingSet=
RestrictNamespaces=yes
SystemCallFilter=@system-service
SystemCallFilter=~@mount ~@reboot ~@swap
# Resources
MemoryMax=512M
CPUQuota=200%
TasksMax=4096
[Install]
WantedBy=multi-user.target

Key directives

DynamicUser=yes

Every service gets its own unique user. Nothing runs as root.

ProtectSystem=strict

Host filesystem is invisible. Only declared volumes are writable.

CapabilityBoundingSet=

No special permissions. Docker keeps 14 by default — niso removes all of them.

SystemCallFilter=@system-service

Only safe operations allowed. Dangerous ones are blocked.

MemoryMax=512M

Hard memory limit. The process is stopped if it exceeds this.

NoNewPrivileges=yes

The process can never gain additional permissions.

Compose multi-service stacks

Like docker-compose, but with dependency health conditions, isolation presets, and runtime deduplication. One TOML file.

stack.toml
[stack]
name = "my-platform"
 
[[service]]
name = "api"
package = "@company/api:2.0"
ports = ["8080:8080"]
depends_on = { db = "healthy", redis = "started" }
 
[[service]]
name = "worker"
package = "@company/worker:2.0"
depends_on = { db = "healthy", redis = "started" }
 
[[service]]
name = "db"
package = "postgres:16"
volumes = { pgdata = { mount = "/data", exclusive = true } }
 
[[service]]
name = "redis"
package = "redis:7.2"

Dependency ordering

redispostgresapiworker

postgres waits for healthy (health check passes). api and worker start after both deps are ready.

$ niso stack up

Start all services in dependency order

$ niso stack status

Show running state of every service

$ niso stack logs -f

Multiplexed logs from all services

$ niso stack down

Stop everything in reverse order

One manifest, everything declared

No Dockerfile. No docker-compose.yml. Just manifest.toml.

manifest.toml
[package]
name = "my-api"
version = "1.0.0"

[binary]
entrypoint = "my-api"

[runtime]
use = "nodejs:20"          # runtime on host, deps in package

[healthcheck]
http = "http://127.0.0.1:8080/health"

[network]
ports = ["8080:8080"]

[isolation]
preset = "server"          # fully isolated
[isolation.resources]
memory_max = "512M"

[volumes]
data = { mount = "/data", mode = "rw" }

Full manifest reference →

Architecture

9 crates. 2 binaries. Zero daemons. Written in Rust.

niso-core

Manifest, config, state DB, discovery

~8K
niso-pack

Pack, install, sign, scan

~4K
niso-systemd

Unit generation, systemctl

~3K
niso-runtime

Isolation presets, security

~2K
niso-net

Networking, port mapping, DNS

~3K
niso-registry

HTTP server, client, chunks

~5K
niso-fleet

SSH deploy, strategies

~3K
niso-machine

macOS/Windows VM

~2K
niso-cli

57 commands

~8K
                    ┌──────────────┐
                    │   niso CLI   │  57 commands
                    └──────┬───────┘
           ┌───────────────┼───────────────┐
     ┌─────┴─────┐   ┌────┴────┐   ┌──────┴──────┐
     │ niso-pack  │   │ systemd │   │ niso-fleet  │
     │ pack/sign  │   │ units   │   │ SSH deploy  │
     └─────┬─────┘   └────┬────┘   └─────────────┘
           │              │
     ┌─────┴──────────────┴─────┐
     │        niso-core          │
     │  manifest · state · config│
     └───────────┬───────────────┘
                 │
     ┌───────────┼───────────────┐
     │           │               │
┌────┴────┐ ┌───┴────┐  ┌───────┴───────┐
│ runtime │ │  net   │  │   registry    │
│ isolate │ │ ports  │  │ push/pull/auth│
│ presets │ │  DNS   │  │   chunks      │
└─────────┘ └────────┘  └───────────────┘

Install

$ curl -sSL https://niso.dev/install.sh | sh

Requires Linux with systemd 250+ and cgroups v2. x86_64 and aarch64 supported. macOS and Windows developers can use niso machine for a lightweight development VM.

Get notified when niso 1.0 launches

No spam. One email when it ships.

Ready to replace Docker?

Start deploying in minutes. Read the docs, browse official packages, or install now.