Step-by-Step Guide: Running Ubuntu in Docker for Streamlined Development
Virtual machines introduce overhead—but containerized Ubuntu instances sidestep that entirely. For infrastructure engineers and developers who need throwaway, reproducible Linux environments without the bloat, Dockerized Ubuntu is the practical answer.
Why Use Ubuntu in Docker Instead of a VM?
- Resource efficiency: Containers leverage the host kernel directly. Expect lower RAM and disk usage.
- Dev/test parity: Identical container images run on laptops, CI/CD runners, or cloud hosts.
- Zero configuration drift: Tear down and spin up clean containers, minus orphaned config files.
- Standard tooling: Full
apt
support, shell access, persistent volumes if needed.
Prerequisites
- Docker Engine ≥ 20.10 (testable with
docker version
—older versions may lack key features or security updates) - Terminal (bash, PowerShell, or Windows CMD)
- Network connectivity
Docker Desktop is needed on Windows/macOS. For Linux, apt install docker.io
on Ubuntu 22.04+ suffices. Validate installation first.
1. Verify Docker Is Installed and Running
docker --version
Example output:
Docker version 24.0.5, build 1234567
If you receive command not found
, Docker is either not installed or missing from your $PATH
. Address this before proceeding.
2. Identify and Pull the Official Ubuntu Image
Command:
docker pull ubuntu:22.04
Rationale: Pinning to 22.04
(LTS) avoids surprises if latest
moves to a newer, incompatible major version later.
Expected output:
22.04: Pulling from library/ubuntu
...
Status: Downloaded newer image for ubuntu:22.04
Note: You can list all available Ubuntu tags via docker search ubuntu
or at https://hub.docker.com/_/ubuntu
3. Launch an Interactive Ubuntu Container
docker run --rm -it ubuntu:22.04 bash
--rm
: Cleans up the container after exit. Useful for ephemeral sessions.-it
: Interactive terminal with TTY.bash
: Launches directly to a bash shell.
Result:
A fresh Ubuntu root shell.
Example:
root@c1135d8fe1c8:/#
No sudo
—you're already root.
4. Update and Install Essential Packages
First step inside every base image: update apt metadata.
apt update
Install standard build/development tools:
apt install -y build-essential git curl
build-essential
gives you gcc/g++/make.- Consider
software-properties-common
if you’ll add PPAs.
Known issue: apt
may throw warnings about missing locales or tzdata. Non-interactive installs can sometimes hang—add DEBIAN_FRONTEND=noninteractive
if scripting.
5. Verify the Setup
Check distribution version:
cat /etc/os-release
Sample output:
PRETTY_NAME="Ubuntu 22.04.4 LTS"
VERSION_ID="22.04"
Confirm installed tooling:
git --version
gcc --version
If you see version output, the installation succeeded.
6. Container Lifecycle Management
View Active Containers
docker ps
List All (Including Exited)
docker ps -a
Restart Stopped Containers
Reuse an exited container to preserve work:
docker start -ai <container_id>
-a
: Attach STDOUT/STDERR.-i
: Interactive.
Important: Containers removed with --rm
cannot be restarted. Consider omitting --rm
if you want persistence.
Remove Containers
docker rm <container_id>
Tip: Unused containers and images can quickly occupy disk. Periodic cleanup with docker system prune
helps, but be careful—not selective.
7. Making Repeatable, Custom Ubuntu Images
A bare Ubuntu image is rarely enough for real workflows. Use a Dockerfile
for repeatable environments.
Sample Dockerfile:
FROM ubuntu:22.04
RUN apt update && \
apt install -y \
build-essential \
git \
curl \
vim \
&& rm -rf /var/lib/apt/lists/*
CMD ["bash"]
- The additional
rm -rf /var/lib/apt/lists/*
shrinks image size by deleting cached package lists.
Build and run:
docker build -t dev-ubuntu:22.04 .
docker run --rm -it dev-ubuntu:22.04
Advanced tip:
Bind-mount your codebase:
docker run --rm -it -v "$PWD":/workspace dev-ubuntu:22.04
Your local directory is now at /workspace
inside the container.
Side Notes & Edge Cases
- Want persistent data? Use Docker volumes (
-v
) or named volumes. - Networking with the host is bridged by default. For special testing (e.g., running servers on host ports), pass
-p 8080:80
etc. - Debugging startup failures:
Often related to permission issues or outdated Docker versions on certain Linux distros.docker: Error response from daemon: OCI runtime create failed: ...
Closing Thoughts
For most build and CI tasks, ephemeral Ubuntu containers outperform VMs both in setup speed and environmental cleanliness. The “stateless by default” model is a feature, not a disadvantage.
Still, for highly stateful workloads, consider hybrid strategies.
Practical takeaway: use tagged images, pin dependencies, and script container setup to avoid surprises mid-project. For anything persistent, avoid --rm
and leverage Docker volumes.
Known alternates:
Podman offers similar workflows rootless, but minor CLI/compatibility differences exist.
Systemd in containers requires custom setup—out of scope here.
For comments or deeper Docker/container practices, start the discussion below or ping me directly.