The Quick Summary
Most online tutorials for setting up Docker are outdated. They tell you to use deprecated tools, or they copy-paste steps from older Ubuntu versions that break on Ubuntu 24.04 LTS (Noble Numbat).
If you are running a production-grade dedicated server, you cannot afford sloppy configurations. This guide gets the official Docker Engine and Docker Compose V2 up and running the right way. No legacy code, no security shortcuts.
Copy-and-Paste Quick Start
If you just want the commands without the explanation, run this block as root or a sudo user:
# Clean out legacy versions
sudo apt remove -y docker docker-engine docker.io containerd runc
# Setup modern, secure keyring directory
sudo apt update && sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
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 official repository
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
# Install the actual suite
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# Verify it works
sudo systemctl enable --now docker
docker compose version
Why Standard Guides Fail on Ubuntu 24.04
I constantly see big hosting blogs publish tutorials that introduce serious security vulnerabilities or broken dependencies. Here are three mistakes you need to avoid when configuring bare metal:
- Using
apt install docker.io: This pulls an old version maintained by Ubuntu, not Docker. You miss critical security patches and performance tweaks. Always use the official source. - Using
apt-key: If a guide tells you to runapt-key add, close the tab. Ubuntu 24.04 completely deprecates this tool because it exposes your server to global repository spoofing. We use isolated keyrings instead. - Downloading Compose as a standalone binary: Forcing an old
docker-composebinary into/usr/local/binis a legacy habit from Compose V1. Modern systems use thedocker-compose-plugin, which updates cleanly via apt.
Prerequisites
You only need two things before starting:
- A dedicated server running a clean install of Ubuntu 24.04 LTS.
- A user account with full
sudoprivileges.
The Step-by-Step Setup
1 Purge the Garbage
Do not assume your server is clean. Some default server images come with standard, outdated Docker packages pre-loaded. Wipe them out first.
sudo apt remove -y docker docker-engine docker.io containerd runc
Note: If the terminal says none of these packages exist, perfect. Move on.
2 Install Basic Pre-requisites
Your system needs to download keys and handle secure repositories over HTTPS. Install these foundational utilities:
sudo apt update
sudo apt install -y ca-certificates curl
3 Secure the GPG Keyring
Ubuntu 24.04 requires explicit, sandboxed security keys for external repositories. Create a dedicated folder and download Dockerās official signing key.
# Create the secure key folder
sudo install -m 0755 -d /etc/apt/keyrings
# Download the official key
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
# Give it global read access
sudo chmod a+r /etc/apt/keyrings/docker.asc
4 Map the Official Repository Source
Next, tell your system exactly where to fetch Docker updates. This command auto-detects whether your dedicated server runs on standard standard architecture (amd64) or ARM, then hooks into the correct Ubuntu noble software stream.
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
5 Install Docker Engine and Compose V2
Update your package index to read the new repository, then pull down the production-tier suite.
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
6 Start and Verify the Service
On dedicated hardware, you want the Docker engine running constantly and starting up automatically if your machine ever restarts.
# Enable the service to survive reboots, and start it right now
sudo systemctl enable --now docker
# Check the running status
sudo systemctl status docker --no-pager
Look for active (running) in the output:
ā docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; preset: enabled)
Active: active (running) since Tue 2026-06-16 12:00:00 UTC; 1min ago
Post-Installation Rules & Security
Running Docker Commands Without Sudo (Optional)
By default, you have to type sudo before every single command because the Docker daemon binds directly to a root Unix socket. If that drives you crazy, add your user account to the automatic docker group.
# Add yourself to the group
sudo usermod -aG docker $USER
# Apply the group changes instantly without logging out of SSH
newgrp docker
docker group is effectively giving them full root power on the server. If this is a shared production machine, do not give this access to non-admin users.
Testing Your Setup
1. The Container Check
Verify your system pulls and fires up containers properly by running the classic baseline image.
docker run hello-world
If everything is working, Docker downloads the file, spins up a micro-container, and prints this confirmation:
Hello from Docker!
This message shows that your installation appears to be working correctly.
2. The Compose Check
Make sure Compose works seamlessly as an integrated plugin. Note that under Compose V2, you no longer use a hyphen. It is a space instead: docker compose.
docker compose version
What you want to see:
Docker Compose version v2.x.x
Production Alert: Docker and Your UFW Firewall
Here is a massive trap that catches senior sysadmins off guard: Docker completely ignores UFW by default.
If you use Uncomplicated Firewall (UFW) to lock down your dedicated server, and you run a container with a public port mapping like -p 8080:80, Docker writes its own raw iptables rules. This opens that port to the entire public web, completely ignoring your UFW block rules.
The Professional Fix
When deploying web apps behind a reverse proxy like Nginx or Traefik, force Docker to bind exclusively to your local loopback address instead of the public network interface.
# Safe: Only accessible from inside your server via local reverse proxy
docker run -p 127.0.0.1:8080:80 nginx
If you are using a docker-compose.yml file, configure your ports like this:
ports:
- "127.0.0.1:8080:80"
Get True Performance from Your Container Workloads
Containers run only as fast as the underlying hardware allows. Virtual machines introduce hypervisor overhead that chokes high-traffic apps, database layers, and microservices under load.
When you deploy on Leo Servers Dedicated Servers, you get raw, unshared bare-metal execution power. No noisy neighbors, no CPU throttling, just unmetered network pipelines and enterprise NVMe storage built to scale your Docker ecosystem cleanly.
Deploy Your Next Workload on Leo Servers High-Performance Dedicated Hardware →