What it is
A container is an isolated process (often with child processes) that sees its own filesystem, its own network interface, and limits on CPU and memory. The filesystem comes from an image, a stack of layers built from a recipe. The host's kernel runs the process. There is no second operating system boot. The standards name you will see is OCI (the Open Container Initiative): images and runtimes that agree on a format so Docker is not the only implementation.
A virtual machine emulates hardware and runs a guest kernel. It is heavier and a stronger boundary in some threat models. Containers start in milliseconds and pack more densely because they share the kernel. That sharing is the performance win and the security caveat.
Why and when it is used
Use containers when you want a repeatable deploy unit: the same image in CI, staging and production, with configuration injected outside the image. Use them when orchestrators (Kubernetes, Cloud Run, ECS, Container Apps) are how your platform runs services. Use a VM when you need a different kernel, a stronger isolation boundary, or a legacy OS the process cannot leave.
Do not containerise data as a substitute for backups. Do not assume a container escape is impossible. Do not run a dozen unrelated processes in one container; one service per container keeps restarts and logs sane.
How it works
Namespaces in Linux hide process ids, mounts and networks. Cgroups limit resources. The runtime (containerd, and Docker's use of it) unpacks the image and starts the process with those controls. The image does not include the kernel. A container that needs a GPU needs the host's drivers mounted in a specific way. Logging should be stdout and stderr so the platform collects them. A restart policy brings the process back; it does not fix a crash loop.
Orchestrators schedule containers onto machines, attach them to networks, and inject secrets at runtime. You can use containers without an orchestrator: one host, one runtime, a few processes. That is a valid production for a small system if you handle updates and disk.
Technologies and dependencies
A runtime, an image builder, and a registry. Docker is the usual developer entry. The cloud pages (Azure Fundamentals for Application Developers, AWS Fundamentals for Application Developers, Google Cloud Fundamentals for Application Developers) each have a way to run the resulting image. CI and CD builds it. Configuration is Environment Variables or mounted files. Your application remains responsible for its own health check.
How to get started
- Read a Dockerfile and name the process it will start. If you cannot name the process, the image is a junk drawer.
- Build and run it locally. Limit its memory. Watch what happens when the limit hits.
- Stop it with a normal stop and confirm the app handles the signal.
- Push the image to a private registry and run it on a second machine. The second machine should not need your language toolchain.
- Delete the container and confirm whether your data survived. If it should have, it needed a volume or an external database.
- Only then look at an orchestrator.
If step 4 fails because the image assumed your laptop's CPU architecture, pin the platform. Apple silicon builds do not always run on AMD64 servers.
Cautions and trade-offs
Containers feel like VMs and are not. A kernel vulnerability is shared. A mis-set capability or a mounted docker socket gives the container control of the host. Root inside the container is still a risk. Read-only filesystems and a non-root user are reasonable defaults.
Image sprawl and unscanned base images accumulate CVEs. Rebuild regularly. And orchestration adds a distributed system. If you have one server, a simple runtime and a reverse proxy may be the whole platform. Do not adopt Kubernetes because a container tutorial's last chapter assumed it.