Practice brief
Container Lifecycle & Interaction Exercises
The TaskFlow API container is running from Module 2. In Module 4 you learn to interact with it: get inside it, pass environment variables, and manage its lifecycle deliberately. These are the commands you will use every day.
Build from scratch
Get Inside the Running Container
The TaskFlow API has been running as a detached container since Module 2. But you have only interacted with it from the outside — checking logs, hitting the health endpoint. In this exercise you will get inside the running container, inspect what is there, pass it an environment variable, and then practice stopping it two different ways to understand the difference. By the end of this exercise the API will be running with NODE_ENV set explicitly — a small but important step toward proper configuration.
Done when
Try it yourself first. Open the guided path if you get blocked.
Step 1 — Start the API container
docker run -d --name taskflow-api -p 8000:8000 -v "$(pwd)":/app -w /app node:20-alpine node api/server.mjs The same command from Module 2. If taskflow-api is already running from a previous exercise, run docker rm -f taskflow-api first to clear it before running this.
Step 2 — Check what processes are running inside the container
docker exec taskflow-api ps aux docker exec runs a command inside a running container without attaching to it interactively. ps aux lists every process. You should see the node process running api/server.mjs. Notice the PID — inside the container it is likely PID 1 or a low number, completely separate from your host's process table.
Step 3 — Open an interactive shell inside the container
docker exec -it taskflow-api sh -i keeps stdin open. -t allocates a terminal. Together they give you an interactive shell. You are now inside the container's filesystem. Run ls to see /app. Run cat /etc/os-release to confirm you are on Alpine Linux. Type exit to leave the shell — the container keeps running.
Step 4 — Stop the container and restart it with an environment variable
docker stop taskflow-api
docker rm taskflow-api
docker run -d --name taskflow-api -p 8000:8000 -e NODE_ENV=production -v "$(pwd)":/app -w /app node:20-alpine node api/server.mjs -e NODE_ENV=production injects an environment variable into the container at startup. The API can read it with process.env.NODE_ENV. Stop and rm first because a container with the same name already exists — Docker will not let you create a second one with the same name.
Step 5 — Verify the environment variable is set inside the container
docker exec taskflow-api env docker exec taskflow-api env runs the env command inside the container and prints all environment variables to your terminal. Look for NODE_ENV=production in the output. This confirms the -e flag worked and the API process has access to it.
Step 6 — Compare docker stop and docker kill
docker stop taskflow-api
docker start taskflow-api
docker kill taskflow-api docker stop sends SIGTERM — a polite request to shut down. The process gets a moment to finish what it is doing before exiting. docker start restarts the stopped container using its original configuration. docker kill sends SIGKILL — the process is terminated immediately with no cleanup. For a database or a server finishing in-flight requests, the difference between stop and kill matters. Always prefer stop unless the process is unresponsive.
Step 7 — Remove the container
docker rm taskflow-api After kill the container is stopped but still recorded. docker rm clears it. Module 5 will build a proper Dockerfile for the API — from that point you will no longer need the bind mount or the manual run command.
Break-fix
Exec Into a Container That Is Not Running
A teammate needs to debug the TaskFlow API. They remember that docker exec lets you get inside a running container. They run docker exec -it taskflow-api sh and get an error: Error response from daemon: container taskflow-api is not running. They checked — the container exists in docker ps -a. It is just not in docker ps. They are not sure what to do next. Reproduce this situation, figure out why exec failed, and get the teammate to a working shell inside the container.
Reproduce this
docker stop taskflow-api
docker exec -it taskflow-api sh You're done when
Show investigative hints
- docker ps and docker ps -a show different things. Understanding what each shows is the key to this exercise.
- docker exec can only run commands inside a container that is currently in the running state. A stopped container has no running process to attach to.
- There is a command that transitions a container from stopped to running without creating a new one.
Show diagnosis and fix rationale
docker exec only works against a running container because it starts a new process inside that container's existing process namespace. The container still exists after docker stop, but it has no running process tree. Start it again with docker start taskflow-api, then run docker exec -it taskflow-api sh to open the shell.