Skip to content

Capability profiles & security

minimal, docker, full -- isolation levels, read-only rootfs, Docker-in-Docker, and when to use each.

Capability profiles - isolation levels and security boundaries

Every plan has a capability profile (capSet)

The capSet determines your instance's isolation level, what capabilities it has, and whether it can run Docker-in-Docker.

ProfileRootfsAppArmorno-new-privilegesDocker-in-DockerBest for
minimalRead-onlyCustom profileYesNoUntrusted workloads, CI runners, shared hosting
dockerWritableunconfined (seccomp)NoYesApps, Docker Compose, DinD, build pipelines
fullWritableunconfinedNoYesKVM, GPU, kernel modules, dedicated plans only

What each profile means

minimal — Maximum isolation

  • Root filesystem read-only -- persistent data must go in volumes or /var/lib/docker
  • Custom AppArmor profile blocks /sys/** w, /proc/** w, /boot/** w, mount/umount/ptrace/syslog
  • no-new-privileges -- prevents privilege escalation
  • Baseline caps only (CHOWN, DAC_OVERRIDE, FOWNER, KILL, SETGID, SETUID, NET_BIND_SERVICE, NET_RAW, SYS_CHROOT, MKNOD, AUDIT_WRITE)
  • No CAP_SYS_ADMIN, CAP_NET_ADMIN, CAP_SYS_PTRACE, CAP_SETFCAP
  • No Docker daemon access

Best for: Untrusted customer code, CI/CD runners, shared multi-tenant workloads.

docker — Docker-in-Docker (default for app plans)

  • Full Docker daemon inside the instance (DinD)
  • CAP_SYS_ADMIN for nested mount/clone
  • CAP_NET_ADMIN for bridge/network management
  • systempaths=unconfined for session keyring access
  • cgroupns=host for cgroup v2 controller delegation
  • Custom seccomp profile allows keyctl, pivot_root for nested runc

Best for: Application hosting, Docker Compose, CI/CD with Docker.

full — Privileged (dedicated plans only)

  • --privileged -- all capabilities
  • Access to /dev/kvm, /dev/dri, /dev/vfio (if present on host)
  • Kernel module loading

Best for: KVM/libvirt, GPU workloads, kernel development, single-tenant dedicated hardware.

Network security (all profiles)

ControlImplementation
Per-instance firewalliptables chain NAIRACLOUD->instanceId< in FORWARD
Egress denySMTP (25), metadata, control plane IP blocked
Inter-instance isolationFORWARD DROP docker0→docker0
Website edgeOne Caddy on the node owns 80/443; Host header selects the instance, unknown Hosts return 404

If the runtime monitor ever detects a breakout attempt, the node auto-suspends the instance. You get a 2-day window to appeal. See Instance quarantines & appeals.

Disk isolation (all plans)

Each instance gets a dedicated ext4 disk image (sized to plan's storageGb), loop-mounted at /var/lib/docker inside the container. The instance sees only its allocated GB -- not the host's total disk.

Instance identity

  • Instance ID: non-enumerable cuid
  • Public IP: the node's IPv4, shared by instances on that node
  • Private IP: 10.20.0.x on the node's data network
  • SSH port: persisted across rebuild
  • Website host: <hostname>.nairacloud.xyz for the default web site; <label>-<hostname>.nairacloud.xyz for other sites, routed by the node edge

Practical -- try it now

Check your instance's profile

  1. SSH into your instance
  2. Run: cat /run/nairacloud/credentials.conf
bash
NAIRACLOUD_CAP_SET=docker
NAIRACLOUD_HOSTNAME=my-site
Ask a question...
Ctrl+I