Skip to content
← Free FDE training guides

Free learning / 45–60 minute container lab

Understand what survives a container replacement

An image is the package; a container is one instance. Follow a pending review through a visual lifecycle, then run a real local API to compare restart, replacement and a mounted volume.

No account needed. Use your own copy for writing and keep the original as a reference.

Engineering lab library / Run locally

See what survives replacement.

Predict the lifecycle, then run the API and compare its actual responses. Keep the Python file and Dockerfile together in a new empty folder.

A real local Docker experiment with synthetic data. Preparation downloads an image; no model, cloud account or public service is used.

  1. Start here / Docker · Actual local containers

    Container lifecycle · local API

    Observe a pending review disappear without a volume and survive replacement when its storage is explicitly retained.

    Local Docker Engine or Desktop · curl · Internet for image preparation

A container is one isolated instance of an application. Its image is the reusable package used to create that instance. Docker is a tool for building images and managing containers; neither is a programming language. Start here before choosing a managed container service or putting an agent worker on a server.

You will run a tiny HTTP API, save a fictional pending review, restart its process, then replace its container. First you will lose the record. Then you will keep it by mounting a named volume. No model, GPU or cloud account is involved.

Allow 45–60 minutes. Use Docker Desktop or a local Docker Engine running Linux containers, a terminal and curl. Image preparation needs internet access and local disk space. After the image is prepared, the experiment runs locally. Optional application checks use Python 3.11+ on your computer.

1. Meet the package, process and storage

UNDERSTAND THE SYSTEM

Follow a review through restart and replacement

An image is a reusable application package. A container is one isolated instance made from it, with its own process and writable layer. Follow a fictional review through restart and replacement on one Docker host; then run the free lab to collect your own observations.

FOLLOW ONE EXAMPLE

See what moves and why.

Authored illustration
01 / EXPLORE THE PARTSTap a part to explain it
Direction of information or workReturn / feedback

WHAT THIS PART DOES

Code + Dockerfile

The Dockerfile describes how to assemble the image and start the application. This lab packages a Python HTTP API, not a model.

CONNECTED TO
  • Build package: Reusable image
Read the connections in plain English
  1. 01
    Code + Dockerfile → Reusable image

    Bundle the program and runtime into one image.

  2. 02
    Reusable image → Container instance

    Use that image to create a separate container and start its process.

  3. 03
    Container instance → Writable layer

    The pending review goes into the instance's writable layer.

  4. 04
    Container instance → Named volume

    The volume supplies the application's storage path instead of the writable layer.

Check your understanding: A review survived docker restart. Does that prove it will survive docker rm followed by docker run?

No. Restart retains that container's writable layer; removal deletes it. Put the record in explicitly retained storage and verify that the replacement actually reads it. A local volume still needs a separate backup and host-recovery plan.

If you know a class and an object, you already know a useful part of the idea: one reusable definition can produce several separate instances. An image is more concrete than a class: it contains filesystem layers and startup configuration. Each container has its own process environment and a writable layer on top of those image layers.

An image does not contain a running server. A container can be running or stopped. A stopped container still exists; removing it is a separate operation.

PartIn this exerciseWhat to remember
ImagePython, the API file and its start commandA reusable package; creating a new instance does not copy another instance's later writes.
ContainerThe process serving port 8080One instance, with its own lifecycle and writable layer.
Process memoryA freshly generated instance IDLost when the process ends, even when the same container restarts.
Writable layerThe first /data/review.sqlite3Survives stopping and starting that container; disappears when it is removed.
Named volumelockedin-container-101-data mounted at /dataA separate Docker-managed store, reusable by a replacement container.

A virtual machine supplies its own guest operating system and kernel. Linux containers use the host's kernel; Docker Desktop runs them inside a Linux VM on macOS and Windows. A container image must still match a supported operating system and CPU architecture. Packaging an application does not remove those constraints.

Use the visual walkthrough to predict what changes in each step. The diagram contains authored examples. The commands below produce your actual local evidence.

2. Build the small API image

Create a new, empty folder named lockedin-container-101 and open a terminal there. Download both files into it:

Read both files. The API accepts only the fictional record R-104, with status pending. It has no login system and is only for a local exercise. Do not add customer data or publish it as a service.

Create a file called .dockerignore containing exactly:

Text example
*
!fde-container-lab.py

The build context is the folder sent to the builder. This allowlist keeps unrelated files out of that context. Never use your home folder or a folder containing credentials as the build context.

Code example
docker version
docker context show
docker build -f fde-container-lab.Dockerfile -t lockedin-container-lab:1 .
docker image inspect lockedin-container-lab:1 --format '{{.Id}} {{.Config.User}}'

Continue only with your local Docker environment. If Docker is configured for a remote host, change to your approved local environment before running this lab. The first build retrieves the official Python base image pinned in the Dockerfile. A digest identifies fixed image content; the lockedin-container-lab:1 tag is the convenient name you give your new local image. Record the resulting image ID.

The final image runs as numeric user 10001:10001. Only /data needs to be writable by that user. EXPOSE 8080 describes the application port; it does not publish a host port by itself.

If Python is installed on your computer, you can also run python3 fde-container-lab.py --check. These check the application storage behavior, not Docker isolation or durability.

3. Start an instance and save a review

Check docker ps -a --filter name=lockedin-container-101 and docker volume ls --filter name=lockedin-container-101-data first. If either name already belongs to work you need, choose different names throughout this exercise. Do not remove an existing resource to make the example work. If host port 8765 is in use, choose another free port and replace 8765 in every command and URL; leave the other service running.

Code example
docker run --detach --name lockedin-container-101 \
  --publish 127.0.0.1:8765:8080 \
  --memory 128m --cpus 0.5 --pids-limit 32 \
  --cap-drop ALL --security-opt no-new-privileges \
  lockedin-container-lab:1
curl --fail http://127.0.0.1:8765/healthz
curl --fail http://127.0.0.1:8765/review
curl --fail --header 'Content-Type: application/json' \
  --data '{"id":"R-104","status":"pending"}' \
  http://127.0.0.1:8765/review

After each start or restart, let the server start before making the next request. If a request arrives too early, retry that request after the container is running. A persistent connection failure needs docker logs lockedin-container-101, not a bigger instance.

The first review response has review: null; the POST response contains R-104. The instance field identifies the current process, not a user or a model. Save its actual value.

Read the port mapping from left to right: 127.0.0.1 restricts the published listener to this computer; 8765 is the host port; 8080 is the container's port. Inside its network namespace the server listens on 0.0.0.0 so the forwarded request can reach it. These two addresses serve different purposes.

The resource limits bound this lab's process; they do not make the API an authenticated production service. /healthz only proves this process can answer. It does not prove that a pending review was retained.

4. Restart, then replace without a volume

Predict both the instance ID and the saved review before running each command.

Code example
docker restart --timeout 1 lockedin-container-101
curl --fail http://127.0.0.1:8765/review
docker inspect lockedin-container-101 --format '{{.Id}} {{.Image}}'

The process instance ID changes. The record remains. Restarting the same container kept its writable layer. A passing restart test alone has not proved that a new release can replace this container safely.

Now stop and remove only the container you created. This deliberately destroys its lab record:

Code example
docker stop --timeout 1 lockedin-container-101
docker rm lockedin-container-101
docker run --detach --name lockedin-container-101 \
  --publish 127.0.0.1:8765:8080 \
  --memory 128m --cpus 0.5 --pids-limit 32 \
  --cap-drop ALL --security-opt no-new-privileges \
  lockedin-container-lab:1
curl --fail http://127.0.0.1:8765/review
docker inspect lockedin-container-101 --format '{{.Id}} {{.Image}}'

The container ID is new; the image ID is the same. The review is now null. Reusing a name did not reuse the removed container's writable layer. The image never contained your later POST.

5. Replace the process and keep the review

Stop and remove that empty lab container. Create a new, explicitly named volume and mount it at the path the application uses:

Code example
docker stop --timeout 1 lockedin-container-101
docker rm lockedin-container-101
docker volume create lockedin-container-101-data
docker run --detach --name lockedin-container-101 \
  --publish 127.0.0.1:8765:8080 \
  --memory 128m --cpus 0.5 --pids-limit 32 \
  --cap-drop ALL --security-opt no-new-privileges --read-only \
  --mount type=volume,source=lockedin-container-101-data,target=/data \
  lockedin-container-lab:1
curl --fail --header 'Content-Type: application/json' \
  --data '{"id":"R-104","status":"pending"}' \
  http://127.0.0.1:8765/review
docker inspect lockedin-container-101 --format '{{json .Mounts}}'

The explicit mount supplies the writable /data directory; the rest of the container filesystem is now read-only. Docker initializes this new empty volume from the image's /data directory, including its ownership. An existing volume may have different permissions; do not fix that by running your application as root.

Remove only this lab container, keeping the volume:

Code example
docker stop --timeout 1 lockedin-container-101
docker rm lockedin-container-101

Run the same mounted docker run command above again, then request /review. The process and container IDs change; R-104 remains. Record the volume name and mount destination as well as the response. Naming a volume is not enough: the replacement must mount it at the path the application actually reads.

A named volume on one Docker host is not a backup, a cross-region replica or a highly available database. Losing that host or deleting its volume can still lose the review. This exercise proves replacement behavior on one local host only.

6. Carry the decision into a cloud deployment

Hosting choiceWhat runs your imageWhere the pending review should live
VM running DockerYou manage the VM, container runtime and serviceExplicit durable storage, with a tested backup and recovery plan.
Managed container serviceThe provider manages more of the runtimeA suitable external database or a documented supported persistent mount.
KubernetesA cluster schedules container workloads into podsA state service or deliberately configured persistent storage; a pod's replacement is expected.

Cloud Run, Amazon ECS and Azure Container Apps are examples of container hosting services with different operating models. Do not assume their filesystem behavior matches this local Docker host. Consult the chosen service's storage and lifecycle contract before carrying the design over.

Explain this to a receiving engineer: "The model or worker may be replaceable, but a human's pending review must still exist after deployment." Keep these observations:

  1. One image ID and the container IDs before and after replacement.
  2. The actual response after restart, replacement without a mount and replacement with a mount.
  3. A diagram placing code, process memory, durable reviews and runtime credentials in different locations.
  4. One remaining failure case, such as losing the storage host, and the recovery test you would need.

Change the design on paper: two workers must read the same review from different hosts. Explain why a local named volume alone no longer satisfies the requirement. Choose a storage service and state the concurrency, access and recovery behavior you would need to verify.

7. Clean up only this experiment

Keep your observation notes, then stop and remove the lab container. The following volume removal deliberately deletes the synthetic record:

Code example
docker stop --timeout 1 lockedin-container-101
docker rm lockedin-container-101
docker volume rm lockedin-container-101-data
docker image rm lockedin-container-lab:1
docker ps -a --filter name=lockedin-container-101
docker volume ls --filter name=lockedin-container-101-data

Use the names you actually chose. If a resource is already absent, inspect rather than widening cleanup. Never use a global prune command for this lab. The downloaded base image can remain in Docker's cache for reuse.

8. Read the source explanations

Original LockedIn Labs exercise. Technical references checked 21 October 2026:

Continue in your authorized Academy lesson to connect replacement behavior to durable jobs, bounded retries, review authority and deployment handoff. Completing this exercise is practice evidence, not a vendor certification or a production-readiness approval.

Before you move on

Keep the evidence of your work.

  • The image and container identities from the actual experiment.
  • Responses after restart, replacement without storage and replacement with a volume.
  • A storage diagram and one host-recovery failure still to test.

Keep these in your own working copy. Reading this page does not save work or record completion.

Suggested next free session

Follow a job from accepted to finished

Understand delivery and acknowledgements after process replacement. This is a suggested sequence; choose the practice that addresses your current gap.

Open the next free guide
Have Academy access?

Continue with worked explanations, practice and review in the related lesson.

Open the related Academy lesson →
Back to top ↑