Install Docker on Ubuntu
Learn how to install Docker on Ubuntu using Docker’s official repository. This practical guide covers Docker Engine, Docker Compose, Buildx, verification, permissions, troubleshooting and security.
Installing Docker on Ubuntu does not require a complicated server setup. However, choosing the right installation method matters because several Docker packages are available for Ubuntu.
For most users, the best approach is to use Docker’s official APT repository. As a result, you get Docker-maintained packages along with the current Docker Compose and Buildx plugins.
In this guide, you will install Docker on Ubuntu, test the installation, run a real web container and configure Docker so you can use it more easily. In addition, you will learn how to solve several common Docker errors.
First, add Docker’s signing key and official Ubuntu repository. Next, install
docker-ce, docker-ce-cli,
containerd.io, docker-buildx-plugin and
docker-compose-plugin. Finally, verify the installation with
docker run hello-world.
What you’ll have when you’re finished
Installed from Docker’s official repository.
Modern
docker compose support.
Docker’s modern image-building plugin.
Tested with Hello World and Nginx.
You should have Ubuntu running on a VPS, virtual machine, home server or computer. You also need an account with administrative privileges.
The examples below use sudo. However, if you are already logged
in as root, you can omit it.
Docker Terminology in Plain English
Before running commands, it helps to understand what the main Docker components actually do.
The core background service responsible for creating, starting, stopping and managing containers.
A reusable package containing an application, its filesystem and everything required to start a container.
A running instance created from an image. One image can create many separate containers.
The docker compose command used to define and manage
multi-container applications from a YAML file.
A package source used by Ubuntu. Adding Docker’s repository lets APT download Docker packages directly from Docker.
A signing key that helps Ubuntu verify the source of downloaded Docker packages.
How to Install Docker on Ubuntu
We are going to install Docker using its official Ubuntu repository rather
than relying on the Ubuntu docker.io package or Snap version.
This method also gives you the Docker Compose and Buildx plugins.
The installation is straightforward. However, complete each step in order so Ubuntu can verify and retrieve the correct Docker packages.
Step 1
Update Ubuntu and install the prerequisites
First, refresh Ubuntu’s package index. Then install the certificate and download utilities needed to communicate securely with Docker’s repository.
sudo apt-get update
sudo apt-get install -y ca-certificates curl
Next, create the directory where Ubuntu stores repository signing keys.
sudo install -m 0755 -d /etc/apt/keyrings
Step 2
Add Docker’s official signing key
Next, download Docker’s signing key. Afterward, make sure APT can read it.
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
Ubuntu uses the key to verify that packages downloaded from Docker’s repository came from the expected publisher. Therefore, APT can reject packages that fail verification.
Step 3
Add the Docker APT repository
The following command automatically detects your processor architecture
and Ubuntu release codename. Therefore, you do not need to manually enter
a release name such as jammy or noble.
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
sudo apt-get update
After the second apt-get update, Ubuntu should now see
Docker’s repository as one of its available software sources.
Step 4
Install Docker Engine, Compose and Buildx
Now install Docker Engine, the command-line client, containerd and the main Docker plugins.
sudo apt-get install -y \
docker-ce \
docker-ce-cli \
containerd.io \
docker-buildx-plugin \
docker-compose-plugin
Once the installation finishes, Docker should already be available as a system service.
Check the installed Docker components
Next, confirm that Docker, Compose and Buildx are available.
docker --version
docker compose version
docker buildx version
Do not worry if your version numbers differ from older tutorials. Docker releases updates regularly. The important result is that each command returns a valid version instead of an error.
Check the Docker service
In addition, verify that Docker is running and enabled at startup.
sudo systemctl is-active docker
sudo systemctl is-enabled docker
Ideally, you should see:
active
enabled
Active means the Docker daemon is running now. Meanwhile, enabled means systemd will start Docker automatically after a reboot.
Verify That Docker Actually Works
Seeing a Docker version number only proves that the command-line client is installed. Therefore, it is better to test the Docker daemon with a real container.
Run Docker’s Hello World container
First, run Docker’s small test image.
sudo docker run hello-world
Docker should download the hello-world image and print a
successful greeting. As a result, you know the client can communicate
with the daemon and retrieve images.
Run an actual web server
The Hello World container exits immediately. Therefore, it is useful to perform a second test with software that stays online and serves HTTP traffic.
sudo docker run -d \
--name docker-test-web \
-p 8080:80 \
nginx:alpine
Next, check that the container is running.
sudo docker ps
Test the Nginx response
Then test the local HTTP endpoint.
curl -I http://localhost:8080
An HTTP response from Nginx proves that Docker can create a networked container and publish a port.
If hello-world succeeds and your Nginx container responds
on port 8080, your Docker installation is ready for normal use.
Finally, remove the temporary web container.
sudo docker rm -f docker-test-web
Run Docker Without Sudo
On a typical Ubuntu installation, normal users cannot access Docker’s
Unix socket by default. Therefore, commands such as docker ps
may fail unless you use sudo.
Add your account to the Docker group
You can add your current account to Docker’s Unix group with this command:
sudo usermod -aG docker $USER
Next, log out and sign back in. If this is a remote VPS, disconnect your SSH session and reconnect.
Refresh Docker permissions immediately
Alternatively, you can start a new shell without reconnecting.
newgrp docker
Then test Docker again:
docker ps
Membership in the docker group should be treated as
administrator-level access. Therefore, add only accounts you trust.
Why Use Docker’s Official Repository?
Ubuntu users will encounter several Docker installation methods online. However, they do not all provide the same package versions or behavior.
| Method | Compose? | Advantages | Considerations |
|---|---|---|---|
|
Docker official APT repository Recommended |
Yes | Docker-maintained packages, Compose plugin, Buildx and normal APT upgrades. | Requires adding Docker’s repository and signing key first. |
apt install docker.io
|
Depends on Ubuntu packaging | Very simple to install from Ubuntu’s own repositories. | Package versions may differ from Docker’s official releases. |
snap install docker
|
Usually | Easy Snap-based installation. | Snap confinement and different file paths can make some tutorials harder to follow. |
| Convenience installation script | Usually | Fast for temporary development environments. | A manual repository installation gives you more visibility and control. |
For a server you expect to maintain for months or years, the official repository is useful because you know where your Docker packages come from. In addition, upgrades remain part of the normal APT workflow.
Useful Docker resources
Keep these authoritative resources nearby while you deploy applications. They are also useful references for checking newer Docker options.
Common Docker Installation Errors
Most failed installations are caused by repository configuration, permissions or a stopped Docker service. Fortunately, these problems are usually easy to diagnose.
Permission denied while connecting to docker.sock
You may see a message that mentions /var/run/docker.sock
when running Docker as a normal user.
sudo usermod -aG docker $USER
docker-compose: command not found
Modern Docker installations use the Compose plugin. Therefore, the current syntax contains a space:
docker compose version
In other words, use docker compose instead of the older
docker-compose command.
Docker repository returns 404 Not Found
A common reason is an incorrect Ubuntu release codename in
/etc/apt/sources.list.d/docker.list.
First, display the actual codename:
. /etc/os-release && echo "$VERSION_CODENAME"
Then correct the repository entry if necessary and run
sudo apt-get update again.
NO_PUBKEY or repository is not signed
This error means APT cannot verify Docker’s packages because the signing key is missing or unreadable.
Therefore, repeat the signing-key commands near the beginning of this
tutorial. In addition, confirm that
/etc/apt/keyrings/docker.asc exists.
Cannot connect to the Docker daemon
First, check whether the service is running.
sudo systemctl status docker
If Docker is stopped, start it:
sudo systemctl start docker
However, if Docker immediately stops again, inspect the recent system log.
sudo journalctl -u docker --no-pager -n 50
Docker Ports and Ubuntu Firewall Security
Installing Docker is easy. However, publishing container ports safely requires more attention.
For example, this command publishes a container port:
docker run -d -p 8080:80 nginx:alpine
Understand what published ports do
The -p 8080:80 option maps the host’s port 8080 to port 80
inside the container. As a result, the container may become reachable from
outside your server.
Therefore, do not assume that every Docker service should be published directly to the internet.
Keep private applications private
Database ports, administration panels and internal APIs should usually stay private. Instead, use Docker networks, reverse proxies and access controls.
Do not publish private services to 0.0.0.0 unless they are
intentionally meant to be reachable from the internet.
Bind a port only to localhost
If a service should be accessible only from the same server or through a reverse proxy, bind it to the loopback interface instead.
docker run -d \
-p 127.0.0.1:8080:80 \
nginx:alpine
This small change can help prevent an internal service from being exposed directly to the public internet.
Useful Docker Commands After Installation
Once Docker is installed, you will use several commands repeatedly. Therefore, the following list is useful as a quick reference.
List running containers
docker ps
List all containers
docker ps -a
List downloaded images
docker images
View container logs
docker logs CONTAINER_NAME
Follow logs continuously
docker logs -f CONTAINER_NAME
Stop a container
docker stop CONTAINER_NAME
Remove a container
docker rm CONTAINER_NAME
Check Docker disk usage
docker system df
View Docker system information
docker info
Confirm Docker Compose With a Simple Stack
Because we installed docker-compose-plugin, use
docker compose with a space.
Create a Docker Compose project folder
First, create a directory for the example.
mkdir ~/docker-example
cd ~/docker-example
Create the compose.yaml file
Next, create compose.yaml with this configuration:
services:
web:
image: nginx:alpine
ports:
- "8080:80"
restart: unless-stopped
Start the Docker Compose stack
Then start the stack in the background.
docker compose up -d
Afterward, check the container status:
docker compose ps
Finally, remove the example stack:
docker compose down
How to Update Docker on Ubuntu
Because Docker was installed through APT, normal package-management commands can retrieve newer Docker releases.
Refresh Ubuntu’s package list
First, update APT.
sudo apt-get update
Install available Docker updates
Next, run the Docker package installation command again.
sudo apt-get install \
docker-ce \
docker-ce-cli \
containerd.io \
docker-buildx-plugin \
docker-compose-plugin
Verify the updated versions
Finally, check the versions again.
docker --version
docker compose version
docker buildx version
Uninstall Docker Completely
Removing Docker’s data directories deletes local images, containers, volumes and other Docker state. Therefore, back up anything important first.
Remove Docker packages
First, remove the installed Docker packages.
sudo apt-get purge -y \
docker-ce \
docker-ce-cli \
containerd.io \
docker-buildx-plugin \
docker-compose-plugin
Remove Docker data
Package removal does not necessarily erase stored container data. Therefore, if you intentionally want a completely clean removal, delete the data directories as well.
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd
Remove the Docker repository
Finally, remove the repository files and refresh APT.
sudo rm -f /etc/apt/sources.list.d/docker.list
sudo rm -f /etc/apt/keyrings/docker.asc
sudo apt-get update
What Should You Learn After Installing Docker?
Installation is only the foundation. Next, learn how Docker stores data, connects containers and manages multi-container applications.
Docker images
Learn how images are pulled, tagged, built and updated. In addition, become familiar with Docker Hub and image versions.
Docker volumes
Containers can be replaced easily. Therefore, persistent application data should normally live in a volume or bind mount.
Docker networks
Docker networks let containers communicate privately. As a result, you do not need to expose every internal service to the internet.
Docker Compose
Compose is especially useful for applications that need several services. For example, a typical stack may include a web server, database and cache.
Frequently Asked Questions
Yes. Docker provides Ubuntu packages through its official repository. Therefore, Ubuntu 24.04 is a good choice for a modern Docker server.
Yes. The same general repository method works on Ubuntu 22.04. In addition, the repository command automatically detects your Ubuntu release codename.
Both provide Docker functionality. However, this tutorial uses
docker-ce from Docker’s official repository because it includes
Docker-maintained Engine packages and modern plugins.
No. You can add your account to the docker group and then start
a new login session. However, Docker group membership gives the user powerful
system access.
Current Docker installations use docker compose with a space.
In contrast, docker-compose is the older standalone command.
First, run docker run hello-world. Then, for a stronger test,
launch an Nginx container and verify that its HTTP port responds.
Normally, yes. However, you can confirm it with
systemctl is-enabled docker.
A standard installation commonly stores Docker data below
/var/lib/docker. Meanwhile, containerd commonly uses
/var/lib/containerd.
Yes. Docker itself can run on relatively small servers. However, the applications inside your containers determine how much RAM, CPU and disk space you need.
No. Docker Engine is the server-side container runtime used in this guide. Docker Desktop, on the other hand, is a desktop-focused product with extra tools and a graphical interface.
Final Thoughts on Installing Docker on Ubuntu
You now know how to install Docker on Ubuntu through Docker’s official repository. In addition, you know how to install Docker Compose, verify the daemon, run containers without sudo and solve several common Docker problems.
Next, learn Docker volumes, networks and Compose in more detail. After that, you will be ready to deploy more complete self-hosted applications on your Ubuntu server.
Docker Is Installed. What Comes Next?
You now have the foundation needed to self-host websites, databases, automation tools, AI applications and complete Docker stacks. Therefore, the next practical step is learning Docker Compose, persistent volumes, networking and reverse proxies.