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.

Open Containers in the terminal

What you will do

  1. download an image from a registry docker pull nginx

    Docker shipped open-source in March 2013 (Solomon Hykes, dotCloud). It packaged Linux cgroups and namespaces, kernel features that already existed, behind one usable CLI.

  2. list images stored locally docker images

    An 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.

  3. 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.

  4. list running containers docker ps

    A 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.

  5. 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.

  6. read a container's captured stdout/stderr docker logs web

    Docker 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.

  7. run a one-off command inside an already-running container docker exec web nginx -v

    exec 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.

  8. dump a container's full low-level metadata as JSON docker inspect web

    inspect is the ground truth: exact mounts, port bindings, environment, and state — every higher-level Docker tool is ultimately reading this same data.

  9. gracefully stop a running container docker stop web

    stop 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.

  10. start an existing, stopped container again docker start web

    start reuses the same container: same filesystem changes, same ID. `run` is different, it always creates a brand-new one from the image.

  11. stop it again — a container must be stopped before it can be removed docker stop web

    Docker refuses `rm` on a running container by design: an accidental one-line `docker rm $(docker ps -q)` should not silently kill live services.

  12. delete a stopped container docker rm web

    rm only deletes the container's thin writable layer and metadata — the image underneath is untouched and can spin up a fresh container instantly.

  13. delete a local image (only once nothing references it) docker rmi nginx

    Docker 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.

  14. pull a minimal base image docker pull alpine

    Alpine 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.

  15. 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.

  16. see the one-off container sitting there, Exited (0) docker ps -a

    A container that runs `echo hello` and returns is not a failure — exit code 0 means success. Its filesystem still exists until something removes it.

  17. confirm alpine now shows up locally too docker images

    Every image you pull or build stays cached on disk until you explicitly `rmi` it — the local image store is Docker's own package cache.

  18. 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.

  19. give an existing image a second name docker tag myapp:1.0 myapp:latest

    A 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.

  20. 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.

  21. create a named volume for data that must outlive a container docker volume create dbdata

    A 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.

  22. list volumes managed by the engine docker volume ls

    Named 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.

  23. 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.

  24. list the container networks on this engine docker network ls

    Every 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.

  25. create a custom user-defined bridge network docker network create appnet

    A 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.

  26. 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.

  27. author a compose file describing a two-service stack nano docker-compose.yml

    Compose (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.

  28. bring the whole stack up — and read the fault that appears docker compose up -d

    Compose 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.

  29. check per-service status across the stack docker compose ps

    compose ps is `docker ps` scoped to one project — the fastest way to see, at a glance, which services in a stack are actually healthy.

  30. read the failing service's logs to find the real cause docker compose logs db

    The 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.

  31. tear the broken stack down cleanly before fixing it docker compose down

    down removes the stack's containers and network (but not its named volumes, by default) — the clean-slate reset before you retry a broken deployment.

  32. add the missing environment variable the db service needs echo POSTGRES_PASSWORD=supersecret >> docker-compose.yml

    One 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.

  33. Boss missionbring the fixed two-service stack up — both web and db healthy docker compose up -d

    This 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.

Nearby eras

Previous
2009 · Ship It
Operate one Linux server end to end: systemd units, deploys and rollbacks, users and permissions, disks, logs and networking.
Next
2015 · Container Orchestra
Drive kubectl against a simulated three-node cluster: pods, deployments, services, namespaces, storage and failure triage.

All 25 eras in the Terminal Academy

Open Containers in the terminal