Sign Up

Docker

Run Docker Engine inside Daytona sandboxes.

Docker runs inside a sandbox as a full Docker Engine, so workloads can build images and run containers the same way they do on a regular Linux machine. Daytona does not install Docker. When the sandbox image ships Docker Engine (dockerd), the sandbox starts it automatically on every boot; when the image does not, nothing starts.

Every Linux sandbox has storage prepared for Docker, with no create-time option. The standard Docker data roots /var/lib/docker and /var/lib/containerd are backed by the sandbox disk, so Docker images, containers, and volumes are stored with the rest of the sandbox filesystem and are kept by snapshots and persistent sandboxes.

Docker startup never blocks the sandbox: the sandbox reports as running as soon as the toolbox is reachable, and Docker reports its own readiness through the Docker status. A Docker failure leaves the sandbox usable, so you can read the logs, fix the configuration, and retry.

Use cases

Docker is used when a workload already runs in containers or builds container images.

  • Multi-container applications: an application with a database, a cache, and its services runs in one sandbox. Docker Engine runs inside the sandbox as on a regular Linux machine.
  • Image builds: CI jobs and agents build container images and test them before a push.
  • Integration tests: tests start databases and other dependencies as containers and remove them after the run.
  • Agents that run containers: an agent pulls and runs containers inside the sandbox, with no access to a Docker daemon on your machines.
  • Docker-in-Docker images: an image whose entrypoint is dockerd or the official Docker-in-Docker entrypoint script works without changes. The sandbox recognizes the entrypoint and waits for Docker to become ready.
  • Prepared environments: images and containers pulled once are kept by a captured image, a snapshot, or a persistent sandbox. The next sandbox does not pull them again.
  • Running containers across pauses: pause and resume, a snapshot, or a fork keeps running containers with their processes intact. A persistent stop and start restarts containers according to their restart policy.
  • Docker startup troubleshooting: a Docker failure leaves the sandbox usable. The Docker status and logs show the cause, and Docker is started again after the configuration is fixed.

Start Docker

Start Docker by creating a sandbox from an image that ships Docker Engine. Docker starts in the background after the sandbox is running, so wait for Docker to become ready before you run Docker commands; a command sent earlier can fail because Docker is not answering yet.

from daytona import Daytona

daytona = Daytona()
sandbox = daytona.v2.create("docker-dind")

# Block until Docker Engine answers, up to 120 seconds
sandbox.docker.wait_until_ready(timeout=120)

response = sandbox.process.run("docker run --rm hello-world")
print(response.stdout)

Start modes

Choose how Docker starts with a sandbox environment variable, set when you create the sandbox. The sandbox reads it once per boot. The value is case-insensitive, and an unset, empty, or unknown value selects the default automatic mode.

In automatic mode, the sandbox first checks the image entrypoint. A recognized Docker entrypoint, which is the Docker Engine daemon itself or the official Docker-in-Docker entrypoint script when it runs the daemon, starts Docker, and the sandbox only waits for it. Otherwise, if the image has the Docker Engine daemon in a standard binary directory, the sandbox starts it as root, waits for it, and then starts the image entrypoint. Recognition is narrow: an entrypoint that starts the daemon another way, such as through a shell command or a process supervisor, is not recognized. The sandbox then starts its own daemon first, and the one the entrypoint starts typically fails against it. Use the entrypoint mode for such images.

  • Recognized entrypoints: dockerd with any arguments; dockerd-entrypoint.sh with no arguments, a flag as the first argument, or dockerd as the first argument; docker-entrypoint.sh with dockerd or dockerd-entrypoint.sh as the first argument.
  • Daemon search path: /usr/local/bin, /usr/bin, /usr/sbin, /bin, and /sbin.
  • Sandbox PATH: not searched for the daemon.
from daytona import Daytona

daytona = Daytona()
sandbox = daytona.v2.create(
    "my-dind-image",
    env={"DAYTONA_DOCKER_START": "entrypoint"},
)
ValueBehavior
auto (default)
entrypointThe image entrypoint starts Docker. The sandbox only waits for the socket and never starts dockerd itself.
offThe sandbox neither starts nor waits for Docker, and the state is disabled. The image entrypoint still runs, so a recognized Docker entrypoint still starts Docker; the state is then unmanaged with owner entrypoint.

Get Docker status

Get the Docker status. The status describes Docker in the current boot and is returned immediately. Reading it never starts or restarts Docker.

FieldDescription
stateWhere Docker is in its startup. See the table below.
ownerWho starts Docker: daemon (the sandbox), entrypoint (the image), or none.
reasonWhy the state is what it is, such as a failure cause; null when there is nothing to add.
processId (process_id in Python)The process with Docker's output, or null.
StateMeaning
readyThe Docker socket answers. Docker commands work.
startingDocker is being started or waited for.
deferredDocker startup has not run yet in this boot (reason gate-closed), or it is skipped for the whole boot (reason function-ready-template).
failedDocker did not come up (start failure, early exit, or the 30-second timeout), or it exited later (reason exited). The sandbox stays usable.
not_presentThe image has no dockerd. The reason is cli-only when the image has only the docker CLI.
disabledDAYTONA_DOCKER_START is off.
unmanagedDOCKER_HOST points to a non-local engine, or DAYTONA_DOCKER_START is off and a recognized Docker entrypoint starts Docker. The sandbox does not check that engine.
unsupportedDocker storage could not be prepared, for example because the image ships a non-empty /var/lib/docker, or the sandbox type has no Docker support.
from daytona import Daytona

daytona = Daytona()
sandbox = daytona.v2.create("docker-dind")

status = sandbox.docker.status()
print(status.state, status.owner, status.reason, status.process_id)

Wait for Docker

Wait for Docker to become ready. The wait polls the Docker status and returns as soon as Docker is ready. It fails at once when Docker reaches a state that cannot become ready in the current boot, and fails with a timeout when Docker is still not ready at the end of the time budget.

from daytona import Daytona
from daytona.v2 import DockerNotReadyError, DockerWaitTimeoutError

daytona = Daytona()
sandbox = daytona.v2.create("docker-dind")

try:
    status = sandbox.docker.wait_until_ready(timeout=120)
except DockerNotReadyError as e:
    print("Docker cannot start:", e.status.state, e.status.reason)
except DockerWaitTimeoutError as e:
    print("Docker is still starting:", e.status)
ParameterTypeDescription
timeoutfloatSets how many seconds the wait lasts. 0 waits without a deadline. The default is 60.

Docker logs

Read Docker's output. Docker's output is kept in the logs of the process that runs Docker, and the Docker status names that process. When the sandbox starts Docker itself, the process has the fixed name used in the examples below, and its logs stay readable after Docker exits. When the image entrypoint starts Docker, Docker's output is in the entrypoint's logs.

from daytona import Daytona

daytona = Daytona()
sandbox = daytona.v2.create("docker-dind")

status = sandbox.docker.status()
if status.process_id:
    handle = sandbox.process.connect(status.process_id)
    for frame in handle.logs().items:
        print(f"[{frame.channel}]: {frame.data}")

Docker storage

Docker data lives on the sandbox disk, at the standard paths for rootful Docker:

PathContents
/var/lib/dockerDocker's image layers, containers, and local volumes.
/var/lib/containerdcontainerd's image content, used by Docker Engine 29 and later.

Docker shares the sandbox disk with everything else in the sandbox; there is no separate Docker allowance. To store more images or containers, raise the sandbox disk size at create time.

If the image already contains a non-empty /var/lib/docker or /var/lib/containerd, or either path is a symbolic link, the contents are left untouched, Docker storage is not prepared, and the state is unsupported. Images that preload Docker data this way are not supported.

Persistence

Because Docker data is part of the sandbox disk, it follows the sandbox's persistence:

OperationDocker data
Images and snapshotsEach sandbox created from a captured image or a snapshot gets its own copy of the source's Docker images, containers, and volumes, and can create new ones.
Persistent stop and startDocker data survives, and Docker starts again on the next boot.
Pause, resume, and forkDocker resumes from memory without restarting.

A boot from a captured image and a persistent start are both reboots: running containers come back stopped and restart per their Docker restart policy (--restart). To resume running containers with their processes intact, use pause and resume, a snapshot, or a fork.