Running containers with the Docker CLI
protect-dockerd speaks the Docker Engine HTTP API over a Unix socket and translates each request into Edera Protect zone and workload operations.
Point the standard docker CLI, or any Docker-SDK-speaking tool at it, and you get Protect isolation without installing Docker or containerd on the host.
What’s supported
The supported Docker Engine API version is v1.45.
protect-dockerd implements the container, image, and exec surface everyday docker usage needs: create, start, stop, kill, wait, attach, exec, logs, rm.
The following is not supported:
- Legacy
docker build(see Building images with Docker Buildx for the supported path) docker volume *docker network *, beyond the implicit default networkdocker statsdocker eventsdocker pause/unpausedocker cp,docker commit,docker save/load/export- Restart policies
- Port mapping enforcement—no iptables/portmap rules are installed
- Swarm, plugin, and distribution endpoints
How it works
Each Docker container maps 1-to-1 onto a Protect zone + workload pair: protect-dockerd creates the zone, launches the workload inside it, and tracks the mapping in its local state (container name, config, status, log path, zone/workload UUIDs).
The Protect daemon’s gRPC socket is the only runtime dependency—no Docker, no containerd, no CNI plugins.
docker CLI / SDK
│ Docker Engine API (HTTP/1.1 over Unix Domain Socket)
│ /var/run/edera-docker.sock
▼
protect-dockerd
│ Protect control service (gRPC)
│ /var/lib/edera/protect/daemon.socket
▼
protect-daemon
│
└── Zone ── Workload (OCI image, process, mounts)IP addressing is entirely daemon-managed—protect-dockerd doesn’t run a CNI plugin pipeline or manage network namespaces itself.
Prerequisites
- A host running
protect-daemon protect-dockerdinstalled- The
dockerCLI (or a Docker SDK client)
Start protect-dockerd
protect-dockerd \
[DAEMON_PATH] # default: /var/lib/edera/protect/daemon.socket
[LISTEN_PATH] # default: /var/run/edera-docker.sock
[DATA_PATH] # default: /var/lib/edera/protect/dockerprotect-dockerd needs root, or at least enough privilege to reach the Protect daemon socket and write to /var/run.
Point the Docker CLI at it
export DOCKER_HOST=unix:///var/run/edera-docker.sock
docker run --rm alpine:latest echo helloOr target the socket per-command without exporting DOCKER_HOST:
docker -H unix:///var/run/edera-docker.sock run -d --name web nginx:latestContainer lifecycle
Each docker command drives the Protect zone and workload lifecycle underneath:
| Docker command | What happens |
|---|---|
docker create | The daemon records the container in its local state (no zone yet) |
docker start | A zone is created, with a workload started in it; a log watcher streams logs to disk |
docker stop | The workload is stopped gracefully, with a default timeout of 10 seconds |
docker kill | A KILL signal maps to an immediate stop, any other signal to the same graceful path as docker stop |
docker rm | The workload and zone are deleted, as well as the the container recorded in the local state |
docker run --rm | All of the above; the container is auto-removed on exit |
Zone and workload UUIDs live in the ContainerRecord, so docker rm (or a crash-recovery pass) can always find the right resources to tear down.
Logs
Each container’s stdout/stderr is captured to Docker’s standard json-file format:
{DATA_PATH}/containers/{container-id}/{container-id}-json.log{"log":"hello\n","stream":"stdout","time":"2026-01-31T07:00:00.000000000Z"}docker logs reads this file from disk.
Add --follow on a running container, and protect-dockerd also opens a live console stream and tails it after the on-disk history.
Exec into a container
docker exec -it mycontainer shdocker exec tunnels stdin/stdout/stderr over a bidirectional gRPC stream to the workload, the same way docker attach and docker logs --follow do.
Current limitations
protect-dockerd doesn’t currently reconcile its local state against live daemon zones and workloads on startup.
A container recorded as Running that the Protect daemon no longer knows about stays in that state until you remove it with docker rm -f.