Doki v0.12.0 — Runtime Fidelity: Interactive I/O, Real CRI Streaming, Podman Engine Wiring, k4s Restart/Readiness, Security Hardening
LatestDoki v0.12.0 — Runtime Fidelity: Interactive I/O, Real CRI Streaming, Podman Engine Wiring, k4s Restart/Readiness, Security Hardening
A note on the wait
This release took a little over a month, and that is longer than I wanted. I owe
you an honest explanation and an apology for the delay.
The gap was not neglect. Most of 0.12 is the kind of work that only counts when
it is done for real — interactive terminals, exec/attach streaming, the Podman
API talking to the actual engine, restart and readiness semantics — and each of
those is easy to fake and hard to get right. I chose to get them right rather than
ship convincing stubs. On top of that I was on a deliberate break for study and
personal reasons, and I would rather move slowly and truthfully than rush and lie
to you in a changelog. Everything below is real, tested, and running.
Thank you for your patience.
Highlights
- Interactive containers:
doki run -it,doki attach, anddoki exec -itnow attach to a live process over a real PTY (or multiplexed pipes), with window resize and multi-client fan-out. - Real Kubernetes exec/attach streaming: a hand-rolled RFC 6455 WebSocket server implementing the
remotecommandchannel protocol —kubectl exec/attachreach the real container. - Podman API wired to the real engine: libpod endpoints delegate to the actual runtime, image, network, and volume stores. Honest
503/501instead of silent stubs. - k4s runtime fidelity: restart policy with backoff and
RestartCount(K14), readiness probes (K13), and ConfigMap/Secret volume projection. doki updateapplies live cgroup v2 limits; the scheduler filters nodes by resource requests (K16).- A large security-hardening pass, including five critical fixes and a CVE-2018-15664-class symlink-escape defense.
79 files changed, +13,786 / -1,256 over v0.11.1.
Interactive Containers — run -it, attach, exec -it (pkg/runtime/stdio.go, internal/pty/pty_linux.go)
- A real stdio broker. TTY sessions get a PTY with line discipline,
Ctrl-DEOF, and window-resize viaTIOCSWINSZ; non-TTY interactive sessions get three pipes with a Docker-style multiplexed stream. doki run -it,doki attach, anddoki exec -itattach live to the process with correct stdin/stdout/stderr fan-out to multiple clients (bounded queues, slow-client drop).- Controlling-terminal setup (
setsid/TIOCSCTTY) runs only in namespaces mode; proot line discipline works without it (proot rejectsTIOCSCTTY). - Fast
run -itthat exits before attach no longer 400s — attach tolerates the exited container and replays its log. - Tests:
stdio_test.go,exec_stdin_test.go.
Real CRI Exec/Attach Streaming (pkg/cri/wsstream.go, pkg/cri/streamer.go)
- A hand-rolled RFC 6455 WebSocket server plus the Kubernetes
remotecommandchannel protocol:v5.channel.k8s.iowith av4fallback, channels 0–5 (stdin/stdout/stderr/error/resize/close). Reserve()issues short-lived streaming tokens; the streamer bridgeskubectl exec/attachto the real container process and returns ametav1.Statusexit code.- Tests:
wsstream_test.go.
Podman API Wired to the Real Engine — P1–P7 (pkg/podman/containers.go, resources.go, api.go)
- libpod endpoints now delegate to the actual runtime, image, network, and volume stores through an injected
Depsstruct: real create/start/stop/kill/logs/stats/exec, build,play/generate kube, and volume CRUD. - Honest status codes:
503when a subsystem is unavailable,501for genuinely deferred endpoints — no more stubs pretending to succeed. - Tests:
api_test.go.
k4s Runtime Fidelity (pkg/kubelet/probe.go, apiserver)
- Restart policy (K14):
Always/OnFailure/Neverwith exponential backoff (capped at 5 minutes) and a realRestartCountin pod status. - Readiness probes (K13):
exec,tcpSocket, andhttpGetprobes honoringinitialDelaySecondsandtimeoutSeconds; the podReadycondition reflects real probe results. - ConfigMap/Secret volume projection: keys are written to disk and mounted into the container.
- apiserver: writable
scale/statussubresources, label selectors, JSON-patch, real container logs/exec, and the correctdeleteresponse shape. - Tests:
probe_test.go,projection_test.go.
Container Resource Updates + Scheduler Resource Fit
doki updateapplies cgroup v2 CPU/memory limits to a running container (D1).- Scheduler (K16): nodes are filtered by CPU/memory requests against already-committed pods before scoring (
pkg/scheduler/scheduler.go). - Tests:
scheduler_test.go.
Security Hardening
- Five critical fixes: digest write-what-where, image-cache poisoning,
docker cppath traversal, build-secret leakage, and unsandboxedRUN. - CVE-2018-15664-class symlink escape: tar extraction goes through
SecureJoin, and bind mounts open over anO_NOFOLLOWfd to defeat the masked-path symlink race (HIGH-7). - Decompression-bomb bounds: a single layer is capped at 16 GiB / 2,000,000 entries.
- Dangerous xattrs and device nodes are stripped from image layers; SSRF guard on the registry auth realm; same-origin control API; bounded JSON and image-load request bodies; firewall proto/IP validation.
- New suites:
archive_security_test.go,digest_security_test.go,securejoin_test.go,symlink_escape_test.go.
Honest Security Posture (C1)
/infoand container inspect report the realSecurityOptionsfor the active runtime mode (native / proot / namespaces) instead of hardcoded claims; capability warnings surface in the CLI.
Plumbing and CLI
pkg/events/bus.go: a real event stream.pkg/stdcopy/stdcopy.go: Docker multiplexed-stream demux for non-TTY attach/logs.- CLI correctness: combined boolean short flags (
-it),--key=valueparsing,doki updateflag order (Docker-compatible), and a firewallnftempty-daddrfix. - 32-bit builds:
maxLayerUncompressedBytestypedint64so armv7 (GOOS=linux GOARCH=arm) builds without overflow.
Installer
- The
dok1.xyzinstaller (curl -sL dok1.xyz | bash) now downloads and installs every binary individually (previously onlydokilanded), fixes x86_64/Intel-Mac architecture selection, usescurl -fso a 404 is never saved as a binary, and removes all six binaries on--uninstall.
Quality Metrics
| Metric | v0.11.1 | v0.12.0 |
|---|---|---|
| Files changed vs prev | 177 total | 79 changed |
| Lines vs prev | — | +13,786 / -1,256 |
| Go files touched | — | 64 |
| New/changed test files | +9 | +17 |
| New packages | pkg/emulation |
pkg/events, pkg/stdcopy, internal/pty, pkg/network/firewall |
go vet |
0 | 0 |
go build ./... |
pass | pass (incl. GOARCH=arm 32-bit) |
go test ./... |
pass | pass (all packages) |
| Release binaries | 42 | 36 (6 tools × platforms) |
| Release assets | 72 | 72 (36 binaries + 36 SHA-256) |
Known Limitations
- Seccomp/capability enforcement by a shim is not shipped in this release: it needs a real Linux host (root or user namespaces) to verify honestly, and Termux/proot cannot. 0.12 reports the true security posture (C1) rather than claiming enforcement it cannot prove.
- gRPC readiness probes are treated as ready (not evaluated);
exec/tcp/httpprobes are fully implemented. - macOS ships only
doki,doki-kube, anddoki-kubectl(nodokid/doki-compose/doki-init); the daemon-backed features require Linux or Termux. - On Termux the container still shares the host network namespace via proot — functional but not isolated (unchanged from 0.11.1).
Security
- Layer extraction is bounded (16 GiB / 2M entries), path-checked through
SecureJoin, and mounted overO_NOFOLLOWfds; dangerous xattrs and device nodes are dropped. - The control API is same-origin; sensitive host binds are blocked; JSON and image-load bodies are size-bounded; the registry auth-realm is SSRF-guarded.
Install / Upgrade
# One-liner (auto-detects platform, installs all binaries)
curl -sL dok1.xyz | bash
# Or by hand — ARM64 (most Android devices, Apple Silicon, Linux ARM servers)
curl -L https://github.com/OpceanAI/Doki/releases/download/v0.12.0/doki-android-arm64 -o doki
curl -L https://github.com/OpceanAI/Doki/releases/download/v0.12.0/dokid-android-arm64 -o dokid
chmod +x doki dokid
# Verify
doki version
dokid --version
doki-kube version
doki-kubectl versionBuilding from Source
git clone https://github.com/OpceanAI/Doki.git
cd Doki
git checkout v0.12.0
make releaseFull changelog: v0.11.1...v0.12.0