Quick Answer: Ubuntu/Debian:
curl -fsSL https://get.docker.com | sh && sudo usermod -aG docker $USER. Log out and back in. Verify:docker run hello-world. That's it.
Need a VPS? Vultr (free credit), DigitalOcean ($200 free credit), or RackNerd (cheap annual deals).
What Is Docker?
Docker runs applications in containers — lightweight, isolated environments that include everything the app needs (code, libraries, dependencies). Instead of installing software directly on your server (and dealing with version conflicts), you run each app in its own container.
Think of it like this:
- Without Docker: Install Nginx, then install Node.js, then install PostgreSQL — all on the same OS. They share libraries and can conflict.
- With Docker: Each runs in its own container with its own libraries. They can't interfere with each other.
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Nginx │ │ Node.js │ │ PostgreSQL │
│ Container │ │ Container │ │ Container │
└─────────────┘ └─────────────┘ └─────────────┘
Docker Engine
─────────────────────────────────────────────────
Linux (Ubuntu/Debian/etc.)
Method 1: Convenience Script (Fastest)
The official Docker convenience script works on all supported Linux distros:
curl -fsSL https://get.docker.com | sh
This detects your distro, adds the Docker repository, and installs Docker Engine + Docker Compose.
Post-Install: Run Docker Without sudo
By default, Docker requires sudo. Add your user to the docker group:
sudo usermod -aG docker $USER
Log out and log back in (or run newgrp docker) for the group change to take effect.
Verify Installation
docker --version
# Docker version 27.x.x, build ...
docker compose version
# Docker Compose version v2.x.x
docker run hello-world
# Should print "Hello from Docker!"
If docker run hello-world works, Docker is installed and running correctly.
Method 2: Official Repository (Ubuntu/Debian)
For more control over the installation:
Remove Old Versions
sudo apt remove docker docker-engine docker.io containerd runc 2>/dev/null
Add Docker's Official Repository
# Install prerequisites
sudo apt update
sudo apt install ca-certificates curl gnupg -y
# Add Docker's GPG key
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Add the 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
For Debian, replace ubuntu with debian in the two URLs above.
Install
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
Post-Install
sudo usermod -aG docker $USER
# Log out and back in
# Enable Docker to start on boot
sudo systemctl enable docker
# Verify
docker run hello-world
Method 3: CentOS/RHEL/Fedora
Remove Old Versions
sudo dnf remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine 2>/dev/null
Add Docker Repository
sudo dnf install dnf-plugins-core -y
sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
For Fedora, replace centos with fedora in the URL.
Install
sudo dnf install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
Start and Enable
sudo systemctl start docker
sudo systemctl enable docker
sudo usermod -aG docker $USER
# Log out and back in
docker run hello-world
Docker Compose
Docker Compose comes bundled with Docker Engine (as docker compose, no hyphen). No separate installation needed.
# Verify
docker compose version
# Basic usage
docker compose up -d # Start services in background
docker compose down # Stop and remove
docker compose logs -f # Follow logs
docker compose pull # Update images
docker compose ps # Show running containers
Your First Compose File
Create compose.yml:
services:
web:
image: nginx:alpine
ports:
- "8080:80"
restart: unless-stopped
docker compose up -d
# Visit http://your-server:8080 — you'll see the Nginx welcome page
Full reference: Docker Compose Examples
Essential Docker Commands
# Run a container
docker run -d --name myapp -p 8080:80 nginx
# List running containers
docker ps
# List all containers (including stopped)
docker ps -a
# Stop a container
docker stop myapp
# Start a stopped container
docker start myapp
# Remove a container
docker rm myapp
# View logs
docker logs myapp
docker logs -f myapp # Follow (tail)
# Shell into a running container
docker exec -it myapp /bin/sh
# List images
docker images
# Remove an image
docker rmi nginx
# Clean up unused resources
docker system prune # Remove stopped containers, unused networks
docker system prune -a # Also remove unused images (re-downloads needed)
Full reference: Docker Cheat Sheet
Configure Docker
Log Rotation (Important!)
Docker logs can fill your disk. Set up automatic rotation:
sudo nano /etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
sudo systemctl restart docker
This limits each container's log to 10MB with 3 rotated files (30MB max per container).
Change Docker Storage Location
By default Docker stores data in /var/lib/docker. To move it (e.g., to a larger disk):
sudo systemctl stop docker
sudo nano /etc/docker/daemon.json
{
"data-root": "/mnt/docker-data"
}
sudo rsync -a /var/lib/docker/ /mnt/docker-data/
sudo systemctl start docker
Uninstall Docker
# Ubuntu/Debian
sudo apt purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
sudo rm -rf /var/lib/docker /var/lib/containerd
# CentOS/Fedora
sudo dnf remove docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
sudo rm -rf /var/lib/docker /var/lib/containerd
Troubleshooting
# Check if Docker is running
sudo systemctl status docker
# Start Docker if it's stopped
sudo systemctl start docker
# Check Docker info
docker info
# Test network connectivity inside a container
docker run --rm alpine ping -c 3 google.com
| Problem | Fix | |
|---|---|---|
permission denied |
Add user to docker group: sudo usermod -aG docker $USER, then log out/in |
|
Cannot connect to Docker daemon |
Docker not running: sudo systemctl start docker |
|
docker compose: command not found |
Old Docker version. Update Docker or install plugin: sudo apt install docker-compose-plugin |
|
No space left on device |
Clean up: docker system prune -a. Check log rotation. |
|
port is already allocated |
Another service using that port. Check: `ss -tlnp \ | grep :PORT` |
dns resolution failed in container |
Add DNS to daemon.json: {"dns": ["1.1.1.1", "8.8.8.8"]} |
What's Next?
Now that Docker is installed:
- Docker Cheat Sheet — every command you need
- Docker Compose Examples — ready-to-use service templates
- Complete Docker Guide — deep dive
- Complete Self-Hosting Guide — deploy full server
- Nginx Reverse Proxy — put services behind HTTPS
- Server Hardening — secure your server