Networking

niso networking uses Linux bridges, veth pairs, and nftables for kernel-level port mapping — no userland proxy. Services discover each other via DNS.

How it works#

When you activate a service with network configuration, niso:

  1. Creates a Linux bridge (if it doesn't exist)
  2. Creates a veth pair — one end in the host, one in the service's network namespace
  3. Assigns an IP from the subnet via IPAM
  4. Adds nftables DNAT rules for port mapping
  5. Updates /etc/hosts for DNS resolution

This is entirely kernel-level. Docker uses a userland proxy (docker-proxy) for port forwarding — niso uses nftables DNAT, which is faster and uses no extra processes.

Manifest configuration#

manifest.toml
[network]network = "backend"          # Bridge name (default: niso-default)ports = ["8080:8080"]        # host:container port mappinghostname = "api"             # DNS name: api.niso.localip = "10.99.1.10"            # Static IP (optional)

Managing networks#

bash
# Create a network with custom subnet$ niso net create backend --subnet 10.99.1.0/24# List all networks$ niso net list  NAME          SUBNET           SERVICES  niso-default  10.99.0.0/24     3  backend       10.99.1.0/24     2# Show network details$ niso net inspect backend  Name:     backend  Subnet:   10.99.1.0/24  Bridge:   niso-backend  Services:    api       10.99.1.2  ports: 8080→8080    worker    10.99.1.3  ports: none# Remove a network$ niso net remove backend

Port mapping#

Port mappings use nftables DNAT rules in the inet nisotable. Supports TCP and UDP:

toml
[network]ports = [  "8080:8080",         # TCP (default)  "8080:8080/tcp",     # Explicit TCP  "53:53/udp",         # UDP  "0.0.0.0:443:443",   # Bind to all interfaces]
bash
# Show all port mappings$ niso net ports  SERVICE    HOST         CONTAINER    PROTO  api        0.0.0.0:8080  8080       tcp  dns        0.0.0.0:53    53         udp# Dynamic port forwarding (without restart)$ niso port-forward api 9090:9090# Show nftables rules$ niso net rules

Service discovery#

Services on the same network discover each other via DNS hostnames. niso writes entries to /etc/hosts inside each service's rootfs:

# Inside the api service:$ cat /etc/hosts  10.99.1.2  api.niso.local api  10.99.1.3  postgres.niso.local postgres  10.99.1.4  redis.niso.local redis

Connect to other services by hostname:

toml
# In your applicationDATABASE_URL = "postgres://user:pass@postgres.niso.local:5432/mydb"REDIS_URL = "redis://redis.niso.local:6379"

Network policies#

Control which services can communicate with each other and what external traffic is allowed:

manifest.toml
[network.policy]# Only allow connections from the frontend serviceallow_from = ["frontend"][network.policy.egress]# Only allow outbound to postgres and HTTPSallow = [  "postgres.niso.local:5432",  "0.0.0.0/0:443",]
Note
Network policies generate nftables rules per service. They are enforced at the kernel level — no application changes needed.

Network modes#

niso supports four network modes:

  • bridge (default) — isolated network with port mapping
  • host — share the host network namespace (no isolation)
  • none — no network access at all
  • share — share another service's network namespace

Connectivity testing#

bash
# Test connectivity between services$ niso net ping api postgres  api (10.99.1.2) → postgres (10.99.1.3): ok (0.3ms)# Debug DNS resolution$ niso exec api -- getent hosts postgres.niso.local  10.99.1.3  postgres.niso.local