Run multiple isolated Docker daemons on a single host, each with its own network, storage, and socket — without touching the system Docker.
The stock Docker daemon is a singleton. You get one dockerd, one bridge, one set of iptables rules. If you need isolation between workloads — different runtimes, different networks, different storage — you're stuck with hacks or heavyweight VMs.
Dockyard spins up fully independent Docker instances that:
- Run sysbox-runc by default — containers that can run systemd, Docker-in-Docker, and other system workloads without
--privileged - Coexist peacefully — each instance gets its own bridge, subnet, containerd, socket, and data directory. No shared state, no conflicts
- Manage their own firewall rules — no more iptables chain clobbering between daemons (a real problem with multiple dockerd instances)
- Survive reboots — systemd services with proper dependency ordering, automatic restart, and clean teardown
- Install in seconds — one command generates config, another downloads Docker + sysbox binaries, generates a self-contained systemd service, and starts everything
# Download
curl -O https://raw.githubusercontent.com/thieso2/dockyard/refs/heads/main/dockyard.sh && chmod +x dockyard.sh
# Generate a config with randomized, conflict-free networks
./dockyard.sh gen-env
# Create instance
sudo ./dockyard.sh create
# Run a container (uses sysbox-runc automatically)
/dockyard/docker-runtime/bin/docker run --rm -it alpine ashEach instance needs its own config file with unique values. Use gen-env with overrides to create them:
# First instance (defaults: dy_ prefix, /dockyard root)
./dockyard.sh gen-env
sudo ./dockyard.sh create
# Second instance (custom prefix and root)
DOCKYARD_DOCKER_PREFIX=tc_ DOCKYARD_ROOT=/docker2 DOCKYARD_ENV=./docker2.env ./dockyard.sh gen-env
DOCKYARD_ENV=./docker2.env sudo -E ./dockyard.sh creategen-env randomizes bridge and pool networks from 172.16.0.0/12, checks for conflicts against ip route and existing installations, and writes a clean config file:
# Dockyard configuration
# Generated by: dockyard.sh gen-env
DOCKYARD_ROOT=/dockyard
DOCKYARD_DOCKER_PREFIX=dy_
DOCKYARD_BRIDGE_CIDR=172.22.147.1/24
DOCKYARD_FIXED_CIDR=172.22.147.0/24
DOCKYARD_POOL_BASE=172.28.0.0/16
DOCKYARD_POOL_SIZE=24Each instance runs independently with its own systemd service (dy_docker, tc_docker, etc.), its own bridge, and its own iptables rules scoped to its bridge interface.
./dockyard.sh gen-env [--nocheck] # Generate dockyard.env
sudo ./dockyard.sh create [--no-systemd] [--no-start] # Create instance
sudo ./dockyard.sh enable # Install systemd service
sudo ./dockyard.sh disable # Remove systemd service
sudo ./dockyard.sh start # Start manually (no systemd)
sudo ./dockyard.sh stop # Stop manually (no systemd)
./dockyard.sh status # Show diagnostics
sudo ./dockyard.sh destroy # Remove instance completelyAll commands except gen-env require a config file. Lookup order:
$DOCKYARD_ENVif set → use that file./dockyard.envin current directory../etc/dockyard.envrelative to the script (for the installed copy)$DOCKYARD_ROOT/docker-runtime/etc/dockyard.env
The installer downloads static binaries (cached in .tmp/ for repeated installs):
| Software | Version | Binaries |
|---|---|---|
| Docker CE | 29.2.1 | dockerd, containerd, docker, ctr, runc, etc. |
| Docker Rootless Extras | 29.2.1 | dockerd-rootless, vpnkit, rootlesskit, etc. |
| Sysbox CE | 0.6.7 | sysbox-runc, sysbox-mgr, sysbox-fs |
${DOCKYARD_ROOT}/
├── docker.sock # Docker API socket
├── docker/ # Images, containers, volumes
│ └── containerd/
└── docker-runtime/
├── bin/ # dockerd, containerd, sysbox-runc, dockyardctl, docker wrapper
├── etc/
│ ├── daemon.json # Daemon configuration
│ └── dockyard.env # Copy of config (written by create)
├── log/ # containerd.log, dockerd.log
└── run/ # PID files
/etc/systemd/system/${PREFIX}docker.service # Self-contained systemd unit
/run/${PREFIX}docker/ # Runtime state (tmpfs)
The systemd service file is generated with all paths hardcoded at create time. It has no dependency on this repository — you can delete the repo after creation and everything keeps running.
Each instance creates its own Linux bridge and manages its own iptables rules. Docker's built-in iptables management is disabled (--iptables=false) because multiple daemons fight over shared chain names like DOCKER-FORWARD — whichever starts last wins and breaks the others.
Instead, each service adds four rules on startup and removes them on shutdown:
iptables -I FORWARD -i dy_docker0 -o dy_docker0 -j ACCEPT # container ↔ container
iptables -I FORWARD -i dy_docker0 ! -o dy_docker0 -j ACCEPT # container → internet
iptables -I FORWARD -o dy_docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT # internet → container (replies)
iptables -t nat -I POSTROUTING -s 172.30.0.0/24 ! -o dy_docker0 -j MASQUERADE # NAT for outbound
Every rule is scoped to the instance's bridge name, so instances can never interfere with each other or with the system Docker.
Each dockyard instance includes a docker wrapper that sets the correct DOCKER_HOST automatically:
/dockyard/docker-runtime/bin/docker ps # dockyard instance
docker ps # system docker (unchanged)Or use DOCKER_HOST directly:
export DOCKER_HOST=unix:///dockyard/docker.sock- Linux with systemd
- sysbox installed and running (
sysbox-fs.service,sysbox-mgr.service) curl,tar,dpkg-debfor binary downloads- Root access for installation
sudo ./dockyard.sh destroy
# For a non-default instance
DOCKYARD_ENV=./docker2.env sudo -E ./dockyard.sh destroyThis stops the daemon, disables the systemd service, and removes all data including images and containers.
| Project | What it does | How it differs |
|---|---|---|
| Sysbox | OCI runtime enabling rootless system workloads (Docker-in-Docker, systemd) inside containers | The runtime Dockyard uses — but doesn't manage multiple daemons or networks |
| multidocker | Run multiple Docker daemons for testing different versions | Closest overlap — but test-oriented, no iptables isolation or systemd integration |
| Kata Containers | Lightweight VMs via KVM that look like containers | VM-level isolation per container, heavier overhead, different trust model |
| gVisor | User-space application kernel intercepting syscalls (runsc) |
Sandboxes individual containers, doesn't address multi-daemon orchestration |
| Firecracker | MicroVM monitor for serverless workloads (powers AWS Lambda) | Per-workload micro-VMs, no Docker API — needs containerd integration |
| RootlessKit | Fake-root via user namespaces for rootless Docker/Kubernetes | Makes a single daemon rootless — could be combined with Dockyard |
Dockyard's niche: multi-daemon orchestration with per-instance network isolation, sysbox-runc as default runtime, and self-contained systemd services.
This project was written entirely by Claude (Anthropic). Thies C. Arntzen provided direction and requirements as navigator.
MIT License — see LICENSE for details.