Introduction

Docker provides a powerful platform for building, shipping, and running applications in containers. This guide walks through installing Docker Engine (community edition) on Ubuntu Server using the official Docker repository.

What you’ll learn:

  • Install Docker Engine from official repository
  • Install Docker Compose plugin
  • Configure user permissions for Docker
  • Verify Docker installation
  • Run your first container

Use cases for Docker:

  • Application development and testing
  • Microservices deployment
  • CI/CD pipelines
  • Isolated application environments
  • Running multiple services on single server

Prerequisites

  • Ubuntu Server (18.04 LTS, 20.04 LTS, 22.04 LTS, or 24.04 LTS)
  • sudo privileges on the system
  • 64-bit architecture (x86_64/amd64, arm64, or armhf)
  • Internet connection to download Docker packages

Part 1: Install Docker Engine

Step 1: Update System Packages

sudo apt update
sudo apt upgrade -y

Step 2: Install Prerequisites

sudo apt install -y ca-certificates curl gnupg lsb-release

Packages explained:

  • ca-certificates: SSL certificates for HTTPS
  • curl: Tool for downloading files
  • gnupg: GNU Privacy Guard for verifying signatures
  • lsb-release: Provides Linux distribution information

Step 3: Add Docker’s Official GPG Key

# Create directory for apt keyrings
sudo install -m 0755 -d /etc/apt/keyrings

# Download and install Docker's GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# Set permissions
sudo chmod a+r /etc/apt/keyrings/docker.gpg

Step 4: Add Docker Repository

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

This adds the official Docker repository to your system’s software sources.

Step 5: Update Package Index

sudo apt update

Expected output:

Hit:1 http://archive.ubuntu.com/ubuntu jammy InRelease
Get:2 https://download.docker.com/linux/ubuntu jammy InRelease [48.8 kB]
Get:3 https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages [24.0 kB]
Fetched 72.8 kB in 1s (72.8 kB/s)

The Docker repository is now available.

Step 6: Install Docker Engine

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

Packages installed:

  • docker-ce: Docker Engine (Community Edition)
  • docker-ce-cli: Docker command-line interface
  • containerd.io: Container runtime
  • docker-buildx-plugin: Extended build capabilities
  • docker-compose-plugin: Docker Compose V2

Expected output:

Reading package lists... Done
Building dependency tree... Done
The following NEW packages will be installed:
  containerd.io docker-buildx-plugin docker-ce docker-ce-cli docker-ce-rootless-extras
  docker-compose-plugin pigz slirp4netns
0 upgraded, 8 newly installed, 0 to remove and 0 not upgraded.
Need to get 119 MB of archives.
After this operation, 434 MB of additional disk space will be used.

Installation may take a few minutes.

Step 7: Verify Docker Installation

sudo docker --version

Expected output:

Docker version 24.0.7, build afdd53b
sudo docker compose version

Expected output:

Docker Compose version v2.21.0

Part 2: Verify Docker is Running

Check Docker Service Status

sudo systemctl status docker

Expected output:

● docker.service - Docker Application Container Engine
     Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2024-12-07 10:00:00 UTC; 5min ago

Docker should be active (running) and enabled (starts on boot).

Test Docker with Hello World

sudo docker run hello-world

Expected output:

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
c1ec31eb5944: Pull complete
Digest: sha256:4bd78111b6914a99dbc560e6a20eab57ff6655aea4a80c50b0c5491968cbc2e6
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

If you see this message, Docker is working correctly!


Part 3: Configure User Permissions

By default, Docker requires sudo. To run Docker without sudo:

Add User to Docker Group

sudo usermod -aG docker $USER

This adds your current user to the docker group.

Apply Group Changes

You need to log out and back in for group membership to take effect.

Option 1: Exit and Reconnect (Recommended)

exit

Then reconnect via SSH:

Option 2: Switch User Context (Without Disconnecting)

su - $USER

Enter your password when prompted.

Option 3: Start a New Shell

newgrp docker

This activates the docker group in the current shell.

Verify Group Membership

groups

Expected output:

username sudo docker

You should see docker in the list of groups.

Test Docker Without Sudo

docker run hello-world

This should now work without sudo.


Part 4: Basic Docker Commands

View Docker Information

docker info

Shows system-wide Docker information (version, storage driver, containers, images, etc.).

List Docker Images

docker images

Example output:

REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
hello-world   latest    9c7a54a9a43c   6 months ago   13.3kB

List Running Containers

docker ps

List all containers (including stopped):

docker ps -a

Remove Images and Containers

# Remove stopped container
docker rm <container-id>

# Remove image
docker rmi <image-id>

# Remove all stopped containers
docker container prune

# Remove all unused images
docker image prune -a

Part 5: Docker Compose

Docker Compose is already installed via the docker-compose-plugin package.

Verify Docker Compose

docker compose version

Note: Docker Compose V2 uses docker compose (space) instead of docker-compose (hyphen).

Example docker-compose.yml

Create a simple example:

mkdir ~/docker-test && cd ~/docker-test
nano docker-compose.yml

Paste this example:

version: '3.8'

services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html

Create an HTML file:

mkdir html
echo "<h1>Hello from Docker Compose!</h1>" > html/index.html

Start the service:

docker compose up -d

Expected output:

[+] Running 2/2
 ✔ Network docker-test_default  Created
 ✔ Container docker-test-web-1  Started

Test the web server:

curl http://localhost:8080

Output:

<h1>Hello from Docker Compose!</h1>

Stop and remove containers:

docker compose down

Troubleshooting

Cannot Connect to Docker Daemon

Error:

Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

Solution:

# Start Docker service
sudo systemctl start docker

# Enable to start on boot
sudo systemctl enable docker

Permission Denied

Error:

permission denied while trying to connect to the Docker daemon socket

Solution:

# Add user to docker group
sudo usermod -aG docker $USER

# Log out and back in
exit
# Reconnect via SSH

docker compose: command not found

Cause: Using old syntax docker-compose instead of docker compose

Solution: Use docker compose (with space) instead of docker-compose (with hyphen).

If you need the old docker-compose tool:

sudo apt install docker-compose

Storage Space Issues

Error:

no space left on device

Solution:

# Clean up unused Docker resources
docker system prune -a --volumes

# Check disk usage
df -h
docker system df

Next Steps

Now that Docker is installed:

  1. Learn Docker basics: Images, containers, networks, volumes
  2. Deploy applications: Use Docker Hub or build custom images
  3. Set up Docker Compose: Multi-container applications
  4. Configure logging: Docker logging drivers
  5. Implement monitoring: Container resource monitoring

Security Best Practices

  1. Keep Docker updated:

    sudo apt update && sudo apt upgrade docker-ce
    
  2. Use official images from Docker Hub when possible

  3. Scan images for vulnerabilities:

    docker scan <image-name>
    
  4. Limit container resources:

    docker run --memory="512m" --cpus="1.0" <image>
    
  5. Run containers as non-root when possible

  6. Use Docker secrets for sensitive data (in Swarm mode)


Uninstalling Docker (if needed)

To completely remove Docker:

# Stop all containers
docker stop $(docker ps -aq)

# Remove all containers
docker rm $(docker ps -aq)

# Remove all images
docker rmi $(docker images -q)

# Uninstall Docker packages
sudo apt purge -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# Remove Docker data
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd

# Remove Docker group
sudo groupdel docker

  • How to Create a VM in Proxmox
  • How to Set Up SSH on Ubuntu Server
  • How to Configure Static IP on Ubuntu with Netplan

Last updated: November 2025