Skip to main content
So far we’ve covered the theory behind virtual machines and containers. Now let’s see them in action so you can compare boot time, isolation, resource usage, and data persistence.
The image illustrates a comparison between containers and virtual machines (VMs) with terms like "Boot Time," "Isolation," "Look," and "Behave." There is also a person wearing a KodeKloud T-shirt.
In this lesson we’ll:
  • Create a virtual machine and observe how it behaves.
  • Run containers with Docker and compare startup time, isolation, and persistence.
  • Walk through practical use cases for VMs and containers at home, at work, and in the cloud.
We’ll start with a VM demo using UTM — a type-2 (hosted) hypervisor available on macOS, Windows, and Linux. Alternatives include VirtualBox and VMware Fusion; choose what fits your OS and workflow.
The image features a cartoon dog on the left and a person on the right, with a list of tasks related to virtual machines and containers displayed in the center.
Demo setup: I have an Ubuntu VM running and I’ll also boot a Windows XP VM to demonstrate differences.
The image shows a virtual machine illustration with Linux, Windows, and Apple logos, along with a person wearing a "KodeKloud" shirt. The text mentions "UTM" and "Type 2 or Hosted VM."
The VM manager lists available VMs (Ubuntu 22.04 and Windows XP in this example).
The image shows a virtual machine manager interface with options for Ubuntu 22.04 and Windows XP, and a person standing beside it.
Key VM concepts to observe
  • Resource allocation: VMs are provisioned with virtual CPU, RAM, and disk. In this demo the Windows XP VM is assigned ~0.5 GB RAM and ~1.7 GB disk. Never allocate more physical RAM to VMs than your host actually has — doing so can cause swapping or instability. Some hypervisors support memory overcommit/ballooning, but that can reduce stability under pressure.
  • Boot time: When I click Start, the Windows XP VM boots. On this setup it takes about a minute from power-on to usable desktop — far slower than containers.
  • Isolation and security: A VM is isolated from the host. Actions inside a VM stay inside the VM unless you intentionally share resources (files, clipboard, network). However, a network-connected VM can be exposed to the internet.
Do not log into real accounts or handle sensitive data inside an unpatched or unsupported VM. Even with isolation, a network-exposed VM can be compromised.
Persistence example: I played Minesweeper in Windows XP and saved a high score. After shutting down and restarting the VM, the saved score remained because the VM’s virtual disk persisted across reboots.
The image shows a screenshot of a Windows XP desktop with the Minesweeper game open and a security alert, alongside a person wearing a black KodeKloud t-shirt.
When to use VMs
  • Strong isolation or running a different OS than the host.
  • Persistent environments for testing, legacy applications, or software that requires a full OS.
  • In the cloud, renting full VMs to host services or test environments.
A person is gesturing while standing next to graphics showing Windows 11 and a "VM" (virtual machine) cube, with text "Risky Apps" and "At Home" in a dark purple-themed background.
The image features a person wearing a "KodeKloud" shirt next to graphics of Windows 11 and a virtual machine labeled "VM," with a button indicating "Run Legacy Systems."
Next: Containers with Docker Desktop Docker Desktop is a one-click installer for macOS and Windows (and available for some Linux distros). It lets you build, share, and run containerized apps. Docker Hub is the central registry for community and vendor images: https://hub.docker.com/. Learn more about Docker Desktop here: https://www.docker.com/products/docker-desktop. A Docker image packages code, runtime, libraries, and configuration into a portable artifact. When you run an image that isn’t local, Docker pulls it from Docker Hub and launches a container. Quick interactive examples
  1. A short-lived container with rancher/cowsay:
  • docker run creates and runs a new container.
  • rancher/cowsay is the image (user rancher, image cowsay on Docker Hub).
  • kode-kow is the text cowsay prints.
Because the image may not be local, Docker pulls it first. The program prints the message, then the container exits immediately. To see all containers, including ones that exited:
Example output:
  1. A long-lived web server (Nginx) mapped to a host port:
  • -d runs the container detached (in the background).
  • -p 8888:80 maps host port 8888 to container port 80. Visit http://localhost:8888 to see the Nginx welcome page.
If nginx:latest isn’t local, Docker pulls it first. Containers start quickly — usually in a fraction of a second — which is a major difference compared to VM boot times. If you need a shell inside a running container:
  • -it allocates an interactive TTY.
  • You can use the shortened, unique prefix of the container ID.
Inside the running Nginx container you can create a test file:
Then visit http://localhost:8888/test.txt to verify persistence inside that running container. Important difference vs VMs: containers are ephemeral. If you remove this container and start a new one from the same image, the new container starts with a clean filesystem and your file will be gone unless you persisted it externally. Persisting data with Docker volumes To retain files beyond a container’s lifetime, use a Docker volume:
  • -v my-nginx-data:/usr/share/nginx/html mounts a named volume (my-nginx-data) at the Nginx web root.
  • Files written to that path are preserved in the volume and available to future containers that mount the same volume.
Use named volumes to persist data independently from container lifecycles. Volumes are the recommended way to keep data when containers are removed and recreated.
If you prefer not to install Docker locally, KodeKloud provides browser-based Docker playgrounds where you can run the same commands in a preconfigured environment. Example KodeKloud session (abridged):
When to use containers
  • Fast startup and lightweight isolation.
  • Ideal for microservices, CI/CD, and ensuring consistent environments across machines.
  • At home for experimenting with apps; in teams for reproducible development environments; at scale in production for dynamic scaling and rolling updates.
The image shows a person in a "KodeKloud" shirt standing next to a graphical representation of a laptop and a monitor, both displaying a container, with the word "AWS" on the monitor.
Quick reference tables Commands and purpose
CommandPurpose
docker run rancher/cowsay kode-kowPulls (if needed) and runs a short-lived container that prints kode-kow.
docker ps -aLists all containers, including exited ones.
docker run -d -p 8888:80 nginxRuns Nginx in the background and maps host port 8888 to container port 80.
docker exec -it <CONTAINER_ID> shOpens an interactive shell inside a running container.
docker run -d -p 8080:80 -v my-nginx-data:/usr/share/nginx/html nginxRuns Nginx with a named volume to persist web content.
VM vs Container: quick comparison
ResourceVirtual MachinesContainers
KernelOwn guest OS kernelShare host OS kernel
IsolationStrong (hardware-level virtualization)Namespace/cgroup isolation
Boot timeMinutes (full OS boot)Milliseconds–seconds
SizeLarge (GBs per VM)Small (MBs per image)
Data persistenceVirtual disk persists by defaultEphemeral by default; use volumes for persistence
Use casesRunning different OSes, legacy apps, strong isolationMicroservices, CI/CD, scalable apps
The image compares virtual machines and containers across categories like architecture, usage scenario, deployment context, and weight & speed. It includes icons, descriptions, and a person gesturing with "KodeKloud" on their shirt.
Summary
  • VMs (UTM, VirtualBox, VMware) run full operating systems and provide strong isolation — useful for legacy systems and running different OSes.
  • Containers (Docker, Podman, containerd) are lightweight, fast to start, and portable — ideal for modern application development and scaling.
  • Use volumes to persist container data; rely on VM virtual disks for persistent VM state.
  • Choose VMs when you need full-OS isolation; choose containers when you need speed, portability, and efficient resource utilization.
That’s the end of this lesson.

Watch Video

Practice Lab