DOCKER CONTAINER ARCHITECTURE Ubuntu Host OS (Kernel) Docker Engine + containerd Container 1 App + Deps Image Layer Container 2 App + Deps Image Layer Container 3 App + Deps Image Layer Containers share the host kernel but are isolated via namespaces and cgroups

Docker has become the industry standard for containerization, enabling developers and system administrators to package applications with all their dependencies into portable, lightweight containers. Whether you are setting up a development environment or preparing a production server, installing Docker on Ubuntu is a foundational skill every Linux professional should master.

This guide walks you through the complete process of installing Docker Engine, Docker CLI, containerd, and the Docker Compose plugin on Ubuntu 22.04 (Jammy Jellyfish) and Ubuntu 24.04 (Noble Numbat). We will also cover post-installation steps, verification, essential commands, and troubleshooting common issues.

Prerequisites

Before you begin, make sure you have:

  • A system running Ubuntu 22.04 or 24.04 (desktop or server edition)
  • Terminal access with sudo privileges
  • A stable internet connection
  • Basic familiarity with the Linux command line

Note: These instructions apply to the x86_64 / amd64 architecture. If you are running ARM64, the steps are the same but Docker will automatically pull the correct architecture-specific images.

Step 1: Uninstall Old or Conflicting Versions

Ubuntu may ship with older or unofficial Docker packages such as docker.io, docker-doc, docker-compose, or podman-docker. These must be removed before installing the official Docker Engine to avoid conflicts.

Run the following command to remove any pre-existing Docker-related packages:

sudo apt-get remove docker docker-engine docker.io containerd runc docker-compose docker-doc podman-docker

If none of these packages are installed, apt-get will report that there is nothing to remove. That is perfectly fine.

Next, clean up any leftover configuration:

sudo apt-get autoremove -y

Important: The contents of /var/lib/docker/, including images, containers, volumes, and networks, are not automatically deleted when you uninstall Docker. If you want a completely clean slate, you can remove that directory manually with sudo rm -rf /var/lib/docker /var/lib/containerd, but be aware this destroys all existing Docker data.

Step 2: Set Up the Docker APT Repository

Docker provides an official APT repository that always contains the latest stable release. Setting it up ensures you receive updates through the standard apt upgrade workflow.

First, update the package index and install prerequisite packages:

sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg

Create the directory for the repository keyring:

sudo install -m 0755 -d /etc/apt/keyrings

Download Docker’s official GPG key:

sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

Add the Docker repository to your APT sources:

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Update the package index again so APT picks up the new repository:

sudo apt-get update

You should see the Docker repository listed in the output. If you see a GPG error, verify that the keyring file was downloaded correctly.

Step 3: Install Docker Engine, CLI, and Plugins

Now install the full Docker stack, which includes the Docker Engine daemon, the CLI client, containerd (the container runtime), and the Compose and Buildx plugins:

sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Here is what each package provides:

PackagePurpose
docker-ceThe Docker Engine daemon (Community Edition)
docker-ce-cliThe docker command-line interface
containerd.ioThe container runtime that manages container lifecycle
docker-buildx-pluginExtended build capabilities with BuildKit
docker-compose-pluginThe docker compose subcommand (Compose v2)

Step 4: Verify the Installation

Confirm that Docker was installed and the daemon is running:

sudo systemctl status docker

You should see active (running) in the output. If the service is not running, start it:

sudo systemctl start docker
sudo systemctl enable docker

Now run the classic hello-world container to verify everything works end to end:

sudo docker run hello-world

This command downloads a small test image from Docker Hub and runs it in a container. If you see the message “Hello from Docker!” followed by an explanation of what just happened, your Docker installation is working correctly.

Check the installed versions:

docker --version
docker compose version

Step 5: Post-Installation Setup

Run Docker Without sudo

By default, the Docker daemon binds to a Unix socket owned by root, which means you need sudo for every docker command. To avoid this, add your user to the docker group:

sudo usermod -aG docker $USER

Security Warning: The docker group grants privileges equivalent to root. Only add trusted users to this group. For production environments, consider using rootless mode instead.

For the group change to take effect, log out and log back in, or run:

newgrp docker

Verify that you can run Docker without sudo:

docker run hello-world

Configure Docker to Start on Boot

On Ubuntu 22.04 and 24.04 with systemd, Docker is typically enabled by default. Verify and ensure it is set to start on boot:

sudo systemctl enable docker.service
sudo systemctl enable containerd.service

Configure Default Logging

Docker’s default logging driver (json-file) can consume significant disk space on busy servers. It is a best practice to configure log rotation by creating or editing the Docker daemon configuration file:

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<'EOF'
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}
EOF
sudo systemctl restart docker

This limits each container’s log file to 10 MB and keeps a maximum of 3 rotated log files.

Docker Commands Cheat Sheet

Here is a quick reference of the most frequently used Docker commands to get you started:

Container Lifecycle

# Run a container in the foreground
docker run <image>

# Run a container in the background (detached mode)
docker run -d --name my-container <image>

# Run an interactive shell inside a container
docker run -it ubuntu:24.04 /bin/bash

# List running containers
docker ps

# List all containers (including stopped)
docker ps -a

# Stop a running container
docker stop <container_name_or_id>

# Start a stopped container
docker start <container_name_or_id>

# Remove a stopped container
docker rm <container_name_or_id>

# Remove a running container forcefully
docker rm -f <container_name_or_id>

Image Management

# Pull an image from Docker Hub
docker pull nginx:latest

# List downloaded images
docker images

# Remove an image
docker rmi <image_name_or_id>

# Remove all unused images
docker image prune -a

Inspection and Debugging

# View container logs
docker logs <container_name_or_id>

# Follow container logs in real time
docker logs -f <container_name_or_id>

# Execute a command inside a running container
docker exec -it <container_name_or_id> /bin/bash

# Inspect container details (network, mounts, config)
docker inspect <container_name_or_id>

# View real-time resource usage statistics
docker stats

Cleanup

# Remove all stopped containers
docker container prune

# Remove all unused images, containers, networks, and volumes
docker system prune -a --volumes

# Check disk usage
docker system df

Troubleshooting Common Issues

Permission Denied When Running docker Commands

If you see permission denied while trying to connect to the Docker daemon socket, it means your user is not in the docker group or you have not logged out and back in after adding yourself to the group.

# Check if your user is in the docker group
groups $USER

# If docker is not listed, add it
sudo usermod -aG docker $USER

# Log out and back in, then try again

Cannot Connect to the Docker Daemon

If you get Cannot connect to the Docker daemon at unix:///var/run/docker.sock, the Docker service may not be running:

sudo systemctl start docker
sudo systemctl status docker

Check the Docker daemon logs for errors:

sudo journalctl -u docker.service --no-pager -n 50

DNS Resolution Issues Inside Containers

If containers cannot resolve domain names, Docker’s default DNS configuration may conflict with your system. Fix it by specifying DNS servers in the daemon configuration:

sudo tee /etc/docker/daemon.json <<'EOF'
{
  "dns": ["8.8.8.8", "8.8.4.4"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}
EOF
sudo systemctl restart docker

Disk Space Running Out

Docker images, containers, and volumes can consume substantial disk space over time. Regularly clean up unused resources:

# Check what is consuming space
docker system df

# Clean up everything that is not currently in use
docker system prune -a --volumes

Package Conflicts After Upgrading Ubuntu

If you upgrade from Ubuntu 22.04 to 24.04, the Docker repository should continue to work. However, if you encounter issues, re-run the repository setup steps from Step 2 to ensure the correct codename is used in the sources list.

Next Steps

Now that Docker is installed and running, you are ready to start containerizing applications. Here are some recommended next steps:

Conclusion

You have successfully installed Docker Engine, Docker CLI, containerd, and Docker Compose on Ubuntu. By following the post-installation steps, you configured your environment for both convenience and security. The commands cheat sheet should serve as a handy reference as you begin working with containers.

Docker is a powerful tool that, when paired with Docker Compose and proper orchestration, can streamline your entire deployment workflow. Keep your Docker installation up to date by running sudo apt-get update && sudo apt-get upgrade regularly, and always refer to the official Docker documentation for the latest best practices.