OutpostImage turns every edge node into a zero-overhead OCI registry by reusing the local Docker/containerd image store — enabling node-to-node image sharing at LAN speed, without extra storage.
OutpostImage runs as a transparent HTTP proxy on every edge node.
OutpostImage intercepts image pulls, resolves from peers first, and shares back to the LAN — in three phases.
Phase 1 — Intercept: Docker or containerd is configured with a single env var: HTTP_PROXY=http://localhost:3128. All registry traffic flows through OutpostImage automatically — no mirror config, no daemon changes. For HTTPS registries, a locally-generated CA certificate enables transparent inspection.
Phase 2 — Resolve: For every blob or manifest, OutpostImage checks the local image store first, then queries P2P peers on the LAN via /api/v1/digests/{digest}. Only on a complete miss does it fall back to the upstream registry.
Phase 3 — Share: Once a node has an image, it becomes a source for every other node. Each instance exposes a standard OCI registry API on :5000, serving blobs directly from the local store. Peers discover each other via static config or mDNS auto-discovery — no central coordinator needed.
Built for edge deployments where bandwidth and storage are constrained.
Works with both Docker and containerd via HTTP proxy — no daemon config changes required.
Reuses the existing Docker or containerd image store. Blobs are never duplicated on disk.
Static peer lists and mDNS auto-discovery build a LAN-speed mesh across all edge nodes.
A single HTTP_PROXY env var is all you need. Zero-intrusion deployment.
Built-in metrics endpoint at :9090 plus /healthz and /readyz probes.
Fully compliant OCI registry API at :5000 — compatible with any OCI-conformant client.
Works with Docker Hub, GHCR, ECR, and any other OCI-compatible registry simultaneously.
All options available as CLI flags or environment variables. Hot-reloading peers file supported.
Both solve P2P image distribution — OutpostImage targets broader runtime compatibility.
| Feature | Spegel | OutpostImage |
|---|---|---|
| Runtime support | containerd only | Docker + containerd |
| Interception method | containerd mirror config | HTTP_PROXY env var |
| Extra storage | None (containerd reuse) | None (Docker/containerd reuse) |
| P2P discovery | OCI / libp2p | Static peers + mDNS |
| Multi-registry | Yes | Yes |
| Invasiveness | Modifies containerd config | Zero-intrusion (env var only) |
Real-world validation across Docker and containerd on edge VMs (2026-03-30).
| Claim | Test | Result |
|---|---|---|
| Zero-intrusion setup | Single HTTP_PROXY env var, no daemon config changes |
PASS |
| Multi-registry transparent interception | docker.io + ghcr.io + custom registry, all served locally | PASS |
| Docker + containerd dual runtime | 5 Store×Consumer combinations (docker/containerd/auto × docker/ctr) | PASS |
| Minimal dependencies | 7 direct deps, 56 total, 11 MB static binary (vs Spegel ~40 MB) | PASS |
| Offline-first | Full network isolation (iptables DROP), P2P sharing works | PASS |
Simulated edge AI model distribution between two QEMU VMs (1 vCPU, 2 GB RAM each).
| Scenario | Image Size | Transfer Rate | Time |
|---|---|---|---|
| 500 MB model (first pull) | 603 MB | 18.84 MB/s | 32 s |
| 2 GB model (first pull) | 2.23 GB | 15.86 MB/s | 144 s |
| Repeat pull (cache hit) | 603 MB | ∞ | 123 ms (260x faster) |
| Parallel pull (500 MB + 2 GB) | 2.83 GB total | — | 129 s (27% faster than serial) |
Up and running in minutes on any Linux node.
# Download the latest binary
curl -L https://github.com/outpostos/outpostimage/releases/latest/download/outpostimage-linux-amd64 \
-o /usr/local/bin/outpostimage && chmod +x /usr/local/bin/outpostimage
# Run with defaults (auto-detects Docker or containerd store)
outpostimage registry
# Run with explicit peers
outpostimage registry --peers node2:5000 --peers node3:5000
docker run -d \
--name outpostimage \
--network host \
-v /var/lib/docker:/var/lib/docker:ro \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
outpostimage:latest registry
git clone https://github.com/outpostos/outpostimage
cd outpostimage
# Optional: create peers.txt with other node addresses
echo "192.168.1.101:5000" > peers.txt
echo "192.168.1.102:5000" >> peers.txt
docker compose up -d
# /etc/docker/daemon.json — point Docker at the proxy
{
"proxies": {
"http-proxy": "http://localhost:3128",
"https-proxy": "http://localhost:3128"
}
}
# Trust the OutpostImage CA certificate
cp /etc/outpostimage/ca.crt /usr/local/share/ca-certificates/outpostimage-ca.crt
update-ca-certificates