Containers, 2013
Containers were not new in 2013; a usable command line around them was. This era runs a simulated Docker host where you pull images, publish ports, mount volumes, read logs, write a Dockerfile and bring up a stack with Compose.
Infrastructure and operations track · 33 missions · boss mission, written exam and certificate · free, no signup. Everything below runs in the browser terminal on the SERVBG home page.
What you will do
- download an image from a registry
docker pull nginxDocker shipped open-source in March 2013 (Solomon Hykes, dotCloud). It packaged Linux cgroups and namespaces, kernel features that already existed, behind one usable CLI.
- list images stored locally
docker imagesAn image is a read-only, layered filesystem plus metadata. Layers are content-addressed and shared — pulling a second image with a common base costs nothing extra.
- start a container from an image, detached, with a published port
docker run -d --name web -p 8080:80 nginx-d backgrounds the container; -p HOST:CONTAINER maps a host port to a port inside the container's own network namespace — the same mechanism that gives every container its own eth0.
- list running containers
docker psA container is a process (or a small process tree) with its own PID, mount, network and UTS namespaces — not a VM. That is exactly why it starts in milliseconds, not minutes.
- list every container, running or not
docker ps -a-a (--all) is the flag you reach for constantly: `docker ps` alone hides every container that already exited, which is most of the ones you will be debugging.
- read a container's captured stdout/stderr
docker logs webDocker captures whatever PID 1 inside the container writes to stdout/stderr. No SSH, no log-shipping agent required — the logging driver is built into the engine.
- run a one-off command inside an already-running container
docker exec web nginx -vexec joins a new process into a running container's existing namespaces — useful for a shell, a version check, or a health probe without restarting anything.
- dump a container's full low-level metadata as JSON
docker inspect webinspect is the ground truth: exact mounts, port bindings, environment, and state — every higher-level Docker tool is ultimately reading this same data.
- gracefully stop a running container
docker stop webstop sends SIGTERM, waits a grace period (10s by default), then SIGKILL if the process ignored it — the same signal contract systemd uses to stop a service.
- start an existing, stopped container again
docker start webstart reuses the same container: same filesystem changes, same ID. `run` is different, it always creates a brand-new one from the image.
- stop it again — a container must be stopped before it can be removed
docker stop webDocker refuses `rm` on a running container by design: an accidental one-line `docker rm $(docker ps -q)` should not silently kill live services.
- delete a stopped container
docker rm webrm only deletes the container's thin writable layer and metadata — the image underneath is untouched and can spin up a fresh container instantly.
- delete a local image (only once nothing references it)
docker rmi nginxDocker refuses to delete an image still referenced by a container, running or stopped — that guard is what stops `rmi` from corrupting something still in use.
- pull a minimal base image
docker pull alpineAlpine Linux uses musl libc and BusyBox instead of glibc/coreutils — the full image is under 8MB, which is why it became the default base for countless Docker images.
- pass an environment variable and run a one-off command that exits
docker run --name box -e APP_ENV=prod alpine echo hello-e injects an environment variable into the container's process — the standard way apps read config (a DB password, a feature flag) without baking it into the image.
- see the one-off container sitting there, Exited (0)
docker ps -aA container that runs `echo hello` and returns is not a failure — exit code 0 means success. Its filesystem still exists until something removes it.
- confirm alpine now shows up locally too
docker imagesEvery image you pull or build stays cached on disk until you explicitly `rmi` it — the local image store is Docker's own package cache.
- build a custom image from a Dockerfile in the current directory
docker build -t myapp:1.0 .Each Dockerfile instruction (FROM, COPY, RUN, CMD...) becomes its own cached layer — change one line near the bottom and only that layer, and everything after it, rebuilds.
- give an existing image a second name
docker tag myapp:1.0 myapp:latestA tag is just a pointer to an image ID, the same way a Git branch points at a commit — `myapp:1.0` and `myapp:latest` can name the exact same bytes.
- see both tags of the image you just built
docker images:latest is not special to Docker itself — it is only a convention. Pin real deployments to an explicit version tag or a digest, never bare :latest.
- create a named volume for data that must outlive a container
docker volume create dbdataA container's writable layer dies with the container. A named volume lives outside that layer, managed by the engine — the standard way to persist a database's data.
- list volumes managed by the engine
docker volume lsNamed volumes are the recommended pattern over bind-mounting a host path — the engine owns the location, permissions, and driver, and it is portable across hosts.
- mount a named volume into a long-running container
docker run -d --name dbtest -v dbdata:/var/lib/data alpine sleep 1000-v NAME:PATH mounts the volume at PATH inside the container. Anything the process writes there survives `docker rm` — only deleting the volume itself loses the data.
- list the container networks on this engine
docker network lsEvery fresh install ships bridge, host, and none. bridge is the default: containers on it get their own IP and can reach each other by container name via embedded DNS.
- create a custom user-defined bridge network
docker network create appnetA user-defined network gives containers automatic DNS resolution by name (`ping db` just works) — the default bridge network does not offer that without extra flags.
- force-remove a still-running container in one step
docker rm -f dbtest-f sends SIGKILL immediately, skipping the graceful-stop grace period — fine for a throwaway test container, risky on anything holding open writes.
- author a compose file describing a two-service stack
nano docker-compose.ymlCompose (originally "fig", 2014, folded into Docker in 2015) turns a directory of `docker run` flags into one declarative YAML file — the whole stack, versioned as text.
- bring the whole stack up — and read the fault that appears
docker compose up -dCompose brings services up honoring depends_on order, but "depends_on" only waits for the container to start, not for the application inside it to actually be ready.
- check per-service status across the stack
docker compose pscompose ps is `docker ps` scoped to one project — the fastest way to see, at a glance, which services in a stack are actually healthy.
- read the failing service's logs to find the real cause
docker compose logs dbThe official postgres image refuses to start with a blank superuser password unless you explicitly opt in — a deliberate safety rail against ever running with no password.
- tear the broken stack down cleanly before fixing it
docker compose downdown removes the stack's containers and network (but not its named volumes, by default) — the clean-slate reset before you retry a broken deployment.
- add the missing environment variable the db service needs
echo POSTGRES_PASSWORD=supersecret >> docker-compose.ymlOne missing required environment variable is one of the most common "why won't my container start" tickets in real operations. Always read the logs before touching anything else.
- Boss missionbring the fixed two-service stack up — both web and db healthy
docker compose up -dThis is the whole loop: author the stack, watch it fail, read the logs, diagnose the exact cause, fix it, and re-apply — that loop, not memorised flags, is what running containers in production actually is.
Certificate
This track is certifiable. Clear the boss mission in the terminal, then run EXAM DOCKER for the written paper: 20 server-graded questions drawn from our own bank, pass mark 14 of 20. The certificate is issued once both are done, and it carries a verification code.
Independently developed; not affiliated with, endorsed by, or sponsored by Docker. Content is aligned to Docker’s publicly published exam objectives for the Docker Certified Associate exam.