Skip to content

Docker And Containers

51 companion flashcards · AI-assisted study content · Open the deck →

This deck introduces you to the world of Docker and containerization, starting with the core ideas and gradually moving into practical commands and concepts. You'll explore foundational questions like what a container is, how it differs from a virtual machine, and what role Docker plays in modern software development. From there, the cards walk you through key building blocks such as images, the Docker daemon, Docker Hub, and Dockerfiles, along with the instructions you'll use to define and build your own images.

It's a great fit if you're new to containers and want a structured way to pick up the terminology and essential commands without getting lost in the details. Whether you're a developer curious about how apps get packaged and shipped, a student learning about deployment workflows, or someone preparing for a DevOps role, these cards offer a clear entry point into a widely used technology stack.

To get the most out of the deck, try spacing your review sessions across several days rather than cramming everything at once — that's how the information tends to stick. As you work through the command-related cards, it helps to have a terminal open so you can try the actual commands on your own machine. Pairing the flashcards with a bit of hands-on practice will make the concepts feel much more concrete and easier to recall later on.

Foundations of Containers and Docker

A container is a lightweight, standalone, executable package that bundles an application together with everything it needs to run: the application code, a runtime, libraries, and all of its dependencies. Because the package is self-contained and isolated from the host system, the application behaves the same way regardless of where it is deployed. The broader practice of packaging software this way is called containerization, a virtualization method that operates at the operating system level rather than the hardware level.

This approach differs significantly from traditional virtual machines. Virtual machines include a full guest operating system on top of a hypervisor, which makes them larger, slower to boot, and more resource-intensive. Containers, by contrast, share the kernel of the host operating system and only package what is unique to the application. As a result, containers start in seconds and consume far less memory and disk space, allowing many more of them to run on the same physical hardware.

Docker is the most widely adopted platform that implements containerization. It automates the building, deployment, scaling, and management of containerized applications, and it introduces two key concepts that recur throughout the ecosystem. A Docker image is a read-only template containing the application's code, dependencies, libraries, and configuration. A Docker container is a runnable instance created from that image, providing the isolated environment where the application actually executes. Images are typically stored and shared through registries, with Docker Hub being the largest public registry where developers can publish and pull images for reuse.

Docker Architecture, Installation, and Core CLI

Under the hood, Docker is built around a long-running background process called the Docker daemon, often invoked as dockerd. The daemon is the engine that creates and manages Docker objects such as images, containers, networks, and volumes, and it exposes its functionality through a REST API. Client tools, including the docker command-line interface, communicate with the daemon over this API to perform actions on the user's behalf.

Installing Docker on a Linux system such as Ubuntu involves a few well-defined steps. You add Docker's official GPG key, configure the package repository, refresh the package index, and then install the docker-ce package using sudo apt install docker-ce. After installation, the Docker service is started and enabled so that the daemon runs automatically on boot, ready to accept requests from the CLI.

Once Docker is installed, a small set of commands is enough to inspect and download images. The docker images command, also written as docker image ls, lists all images stored locally along with their repository names, tags, image IDs, and sizes. To obtain an image from a registry like Docker Hub, you use docker pull followed by the image name, which downloads the image and stores it locally so it can be turned into a container. The docker inspect command is a general-purpose debugging tool that returns detailed JSON information about any Docker object, whether that object is a container, an image, a volume, or a network.

Building Images with Dockerfile

A Dockerfile is a plain-text file containing a series of instructions that Docker uses to build an image automatically. The build is triggered with docker build -t name:tag ., where the trailing dot specifies the current directory as the build context. Each instruction in the Dockerfile creates a new layer in the resulting image, and the order of those instructions matters for both correctness and efficiency.

The Dockerfile always begins with a FROM instruction, which selects a base image that everything else is built on top of, such as ubuntu:20.04. From there, RUN executes shell commands during the build (for example, RUN apt-get update) and each RUN creates a new image layer. WORKDIR sets the working directory used by subsequent instructions and creates it if it does not already exist, while CMD provides default arguments for the command that will run when a container starts. ENTRYPOINT goes a step further by configuring the container's main executable, with any CMD values passed as arguments to that executable. USER switches to a non-root user for the following instructions, which is a key security practice, and HEALTHCHECK defines a command that Docker runs periodically inside the container to report whether the service is actually healthy.

Several techniques help produce smaller, faster, more secure images. Multi-stage builds use multiple FROM statements so that compilers and build tools can live in an early stage while only the final artifacts are copied into a slim runtime stage. Layer caching means Docker reuses any layer whose inputs have not changed, so it pays to place stable, rarely-modified instructions early and to combine related shell commands onto a single RUN line. A .dockerignore file works like a .gitignore, excluding files such as node_modules from the build context. Together with choosing minimal base images, these practices reduce image size and improve build performance.

Running and Managing Containers

The docker run command is the primary way to create and start a new container from an image. For example, docker run -it ubuntu bash launches an Ubuntu container with an interactive terminal. By default, docker run attaches to the container's foreground, but adding the -d flag runs the container in detached mode in the background and prints the container ID instead. Many other flags control networking, environment variables, mounted volumes, and resource limits, making docker run both the simplest and the richest command in the toolkit.

To see what is currently running, docker ps lists active containers, while docker ps -a also includes containers that have stopped. The output includes useful information such as container IDs, the image used, status, port mappings, and names. To manage lifecycle, docker stop container_id sends a graceful SIGTERM signal, whereas docker kill forces immediate termination with SIGKILL. Once a container is stopped, it can be deleted with docker rm container_id, or you can clean up many at once with docker container prune.

Often you need to interact with a container that is already running. The docker exec command runs an additional process inside an existing container; the common pattern docker exec -it container_id /bin/bash opens an interactive shell so you can investigate or fix problems without restarting the service. Combined with docker ps, docker stop, docker rm, and docker exec, these commands form the day-to-day toolkit for working with containers by hand.

Data Persistence and Networking

Containers are designed to be ephemeral, so data written inside them is lost when the container is removed. Docker solves this with volumes, which are persistent storage objects managed by Docker that exist independently of any single container's lifecycle. Volumes can be mounted into multiple containers at once, making it easy to share data between services or to keep state across restarts. You create a named volume with docker volume create volume_name and list existing volumes with docker volume ls.

A common alternative is the bind mount, which maps an arbitrary host directory to a path inside the container. Bind mounts are simple and useful during development because the host filesystem is exposed directly inside the container, but they tie the container to a specific host path and reduce portability. Named volumes are generally preferred for production because Docker handles where they are stored, they work the same way across hosts, and they integrate with the rest of the Docker ecosystem.

Networking follows a similar idea of providing isolation while enabling communication. Each container gets its own network stack, and you choose how containers connect to each other and to the outside world through network drivers such as bridge, host, overlay, or custom networks. The default bridge network lets containers on the same host communicate via IP addresses or automatically assigned names. For more structured setups, docker network create network_name creates a user-defined bridge, while specifying --driver overlay enables multi-host communication used by Swarm clusters.

Docker Compose and Orchestration with Swarm

Most real applications are not a single container but a collection of cooperating services such as a web server, an application server, and a database. Docker Compose is a tool for describing such multi-container applications declaratively in a YAML file called docker-compose.yml, which lists each service along with its image, ports, environment, networks, and volumes. Compose keeps the configuration in source control so the whole application stack can be brought up, torn down, or recreated in a single step.

To launch the defined application you run docker-compose up, which builds or pulls the necessary images, creates the required networks and volumes, and starts all the services together. Adding the -d flag runs everything in detached mode so the terminal remains free. To observe what is happening, docker-compose logs service_name prints the logs for a named service, or omits the name to see logs from every service at once. Compose effectively turns a multi-container application into one command-line operation.

When you need to run containers across many machines rather than one, Docker Swarm provides clustering and orchestration. You initialize a cluster with docker swarm init, which turns the current node into a manager and prints a join token for worker nodes. Inside a Swarm, a Docker service describes the desired state of a group of containers: which image to run, how many replicas, what networks to attach, and what resources to allocate. You deploy one with docker service create --name name --replicas N image and inspect the cluster with docker service ls. Swarm also provides Docker secrets, which are encrypted objects for storing sensitive data such as passwords. Secrets are mounted into services through in-memory tmpfs filesystems so the data never touches the container image or disk. Overlay networks complement Swarm by enabling multi-host container communication using VXLAN encapsulation, allowing containers on different physical nodes to talk to one another securely and transparently.

Security and Troubleshooting

Security is a recurring concern when packaging and running shared workloads. Docker Content Trust, abbreviated DCT, is a mechanism that signs images with cryptographic keys so that consumers can verify both the integrity and the publisher of an image during push and pull operations. You enable it by exporting the environment variable DOCKER_CONTENT_TRUST=1, after which Docker refuses to pull or run images that are not properly signed.

Beyond trust, the most serious class of risk is the container breakout, a vulnerability in which a process running inside a container escapes its isolation and gains access to the host system. Breakouts typically exploit weaknesses in the kernel or misconfigured privileges. Defending against them requires following well-known best practices: build images from minimal bases, run containers as a non-root user via the USER instruction, scan images for known vulnerabilities using tools like Trivy, drop unnecessary Linux capabilities, and keep the host kernel up to date. Combined with content trust, these habits significantly reduce the attack surface of a containerized deployment.

When something does go wrong, Docker provides a layered set of diagnostic tools. docker logs container prints the standard output and error streams of a container, which is usually the first place to look. docker inspect returns detailed JSON metadata about a container, image, volume, or network and is invaluable for understanding configuration. docker exec lets you open a shell inside a running container to investigate the live filesystem and processes, while docker events provides a real-time stream of daemon activity. Checking resource limits, reviewing health status from HEALTHCHECK results, and cross-referencing logs with compose or service output together form a reliable workflow for resolving most container issues.

Frequently asked questions

What is a container in computing?

A container is a lightweight, standalone, executable package that includes everything needed to run a piece of software, such as code, runtime, libraries, and dependencies, isolated from the host system.

What is a Docker container?

A Docker container is a runnable instance of a Docker image, providing an isolated environment for running applications.

What does <code>docker pull</code> do?

docker pull <image> downloads a Docker image from a registry like Docker Hub to your local machine for use in creating containers.

What is <code>docker run</code>?

docker run creates and starts a container from a specified image, e.g., docker run -it ubuntu bash runs an interactive Ubuntu container.

What are Docker volumes?

Docker volumes are persistent storage solutions that outlive container lifecycles, allowing data to be shared and accessed by multiple containers.

How do you create a custom Docker network?

docker network create <network_name> creates a bridge network by default; specify --driver overlay for multi-host.

What is the WORKDIR instruction?

The WORKDIR instruction sets the working directory for subsequent RUN, CMD, etc., creating it if nonexistent, e.g., WORKDIR /app.

What is Docker layer caching?

Docker layer caching speeds up builds by reusing unchanged layers from previous images; changes invalidate cache from that layer onward.

What command deploys a service in Swarm?

docker service create --name <name> --replicas <num> <image> deploys a service; use docker service ls to list.

What is USER instruction in Dockerfile?

The USER instruction sets the user/group for RUN, CMD, and ENTRYPOINT, enhancing security by avoiding root.

Drill this topic

51 flashcards on Docker And Containers — free, no signup needed to start.

Study Docker And Containers flashcards

LearnWiki pages are generated with AI assistance from LearnCoachAssist's reviewed study catalog and may contain errors — verify anything critical against your course materials.