You want to freeze a running container mid-flight and bring it back exactly where it left off, and docker checkpoint is the command that promises it. This guide takes you through saving a running Docker container as a checkpoint, checking that it exists, and restoring from it. The command is experimental and depends on daemon support, CRIU and kernel features, so success on one host is not a portability guarantee.
Allow about twenty minutes for a first test. You need:
sudo access to the daemon. Docker group membership is effectively root-equivalent, so do not grant it casually.Safety boundary: Creating a checkpoint changes the container's runtime state and normally pauses it while the state is captured. Removing a checkpoint is destructive. Do not test against a production container until its pause, restore and rollback behaviour are understood.
Start with read-only checks. They do not create, stop or modify a container:
$ docker --version
Docker version 29.8.1, build 4a63305
$ docker info --format '{{.ServerVersion}} {{.ExperimentalBuild}}'
29.8.1 false
The exact build identifier and daemon values vary. The installed package here is docker-ce-cli 5:29.8.1-1~ubuntu.24.04~noble.
The catch is in that trailing false. Checkpoint commands are experimental, and the client can be installed while the connected daemon has experimental features disabled, as in the output above.
docker checkpoint cannot enable it for itself.List running containers and select one whose workload can tolerate a pause. This is read-only:
$ docker ps --format '{{.ID}}\t{{.Names}}\t{{.Status}}'
CONTAINER_ID CONTAINER_NAME STATUS
Replace the labels in the example with a real container name or ID. Do not guess a name, and do not use a service container simply because it is convenient.
Warning: A checkpoint captures process state, not a portable image. Volumes, external services, network peers and host dependencies still need their own recovery plan.
Confirm that the selected container is running immediately before capture:
$ CONTAINER_NAME='replace-with-disposable-container'
$ docker inspect --format '{{.State.Status}}' "$CONTAINER_NAME"
running
Checkpoint: The result must be running. If it is not, stop and choose another container or start it through its normal operational procedure. Do not use docker start merely to make an unplanned production test possible.
Choose a descriptive checkpoint name and capture the running container:
$ CHECKPOINT_NAME='before-maintenance-2026-09-23'
$ docker checkpoint create "$CONTAINER_NAME" "$CHECKPOINT_NAME"
before-maintenance-2026-09-23
The command takes the container and checkpoint name as positional arguments. The optional --checkpoint-dir DIRECTORY selects custom checkpoint storage. The default is managed by Docker, so do not assume the files are in your current directory.
By default, the container is not left running after capture. Treat it as paused or stopped until you have checked its state. If the workload must keep serving while you capture it, the documented option is:
$ docker checkpoint create --leave-running "$CONTAINER_NAME" "$CHECKPOINT_NAME"
before-maintenance-2026-09-23
Tip: Use --leave-running only when you have considered consistency. It changes the post-capture state, not the fact that a point-in-time copy was made. For a first test, a short planned pause is easier to observe and recover.
Inspect the container after creation:
$ docker inspect --format '{{.State.Status}}' "$CONTAINER_NAME"
exited
Checkpoint: The status is host- and option-dependent. The useful check is that it matches the choice you made.
Recovery: If creation fails, preserve the error, inspect daemon logs and check CRIU support. Do not delete partial files by hand from Docker's data directory.
Ask Docker for the checkpoints belonging to this container:
$ docker checkpoint ls "$CONTAINER_NAME"
CHECKPOINT NAME ID
before-maintenance-2026-09-23 before-maintenance-2026-09-23
Column formatting and identifiers can vary by Docker release. The checkpoint name you supplied should be identifiable in the result.
Tip: If the list is empty, check that you are using the same container, Docker context and checkpoint directory. A checkpoint belongs to its container; it is not an image tag that can be applied to an unrelated container.
Restoration uses docker start, not another checkpoint subcommand. First confirm that the container is stopped and that you have recorded any application-level recovery steps. Then run:
$ docker start --checkpoint "$CHECKPOINT_NAME" "$CONTAINER_NAME"
replace-with-disposable-container
A successful result prints the container name or ID. Verify that it is running:
$ docker inspect --format '{{.State.Status}}' "$CONTAINER_NAME"
running
$ docker logs --tail 20 "$CONTAINER_NAME"
The restored process should continue from the captured point, but application output is workload-specific. Check the application's own health endpoint, queue position, open connections and data consistency. A Docker exit status of zero is not proof that an external dependency accepted the restored session.
Recovery: If restore fails, do not immediately remove the checkpoint. Keep it while you collect the daemon error, CRIU diagnostics and the container's state. You may be able to start the container normally with docker start "$CONTAINER_NAME", but only if its normal startup path is acceptable, and remember that this is not a checkpoint restore.
Destructive action: Removing a checkpoint cannot be undone through Docker. Only remove it after the restored container and its replacement recovery evidence have been checked.
$ docker checkpoint rm "$CONTAINER_NAME" "$CHECKPOINT_NAME"
before-maintenance-2026-09-23
$ docker checkpoint ls "$CONTAINER_NAME"
CHECKPOINT NAME ID
The final list should no longer include the removed checkpoint. If it does, check the container name and any custom --checkpoint-dir value. Never use broad filesystem deletion under Docker's data root as a substitute for this command.
--checkpoint-dir must be repeated for create, list and remove when you use it. Omitting it can make a valid checkpoint appear to be missing.sudo may solve daemon access, but it cannot add CRIU support, repair an incompatible workload or make a missing checkpoint appear.docker checkpoint ls.docker start --checkpoint, and its running state and application health were checked.docker checkpoint rm after recovery was verified.