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 HTTPScurl: Tool for downloading filesgnupg: GNU Privacy Guard for verifying signatureslsb-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 interfacecontainerd.io: Container runtimedocker-buildx-plugin: Extended build capabilitiesdocker-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:
- Learn Docker basics: Images, containers, networks, volumes
- Deploy applications: Use Docker Hub or build custom images
- Set up Docker Compose: Multi-container applications
- Configure logging: Docker logging drivers
- Implement monitoring: Container resource monitoring
Security Best Practices
Keep Docker updated:
sudo apt update && sudo apt upgrade docker-ceUse official images from Docker Hub when possible
Scan images for vulnerabilities:
docker scan <image-name>Limit container resources:
docker run --memory="512m" --cpus="1.0" <image>Run containers as non-root when possible
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
Related Guides
- 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