How to install Docker on Ubuntu the official way

Docker packages an application and everything it needs into a container, so it runs the same way everywhere. On a VPS, that means you can run a database, a web app or a bot with one command, without installing a pile of dependencies on the host. Ubuntu's own package for Docker is often older than Docker's, so it is best to install from Docker's official repository. Here is how.

Before you start

Remove old packages

If an older Docker or a distribution-supplied version was installed, remove it first:

sudo apt remove docker.io docker-doc docker-compose podman-docker containerd runc

If none are installed, it simply says so. Your existing images and containers are not deleted by this.

Add Docker's repository

sudo apt update
sudo apt install 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

Then add the repository, as a single command:

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

Install the packages

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

This installs the Docker engine, its command line tool and Compose as a plugin. Check it works:

sudo systemctl status docker
sudo docker run hello-world

The second command downloads a tiny test image and prints a short welcome message, which proves the engine can pull and run containers.

Using Docker without typing sudo

By default, only root can talk to Docker. You can add your user to the docker group:

sudo usermod -aG docker $USER

Log out and back in for it to take effect. Understand what this does: anyone in the docker group can run containers that mount the whole file system, which is effectively root access. Add only people you trust as much as an administrator.

Everyday commands

CommandWhat it does
docker psShow running containers
docker ps -aShow all containers, including stopped
docker imagesList downloaded images
docker logs nameShow a container's output
docker logs -f nameFollow the output live
docker stop name and docker start nameStop and start a container
docker rm nameDelete a stopped container
docker system pruneRemove unused data, to free space

A small example, running a web server in the background and publishing a port:

docker run -d --name web --restart unless-stopped -p 8080:80 nginx

-d runs it in the background, --restart unless-stopped brings it back after a reboot or crash, and -p 8080:80 connects port 8080 on the server to port 80 inside the container.

Docker and your firewall

This is the most important warning. When you publish a port with -p, Docker adds its own firewall rules that bypass UFW. So a port that UFW says is closed can still be open to the whole internet. Two ways to stay safe:

Keep data safe

Containers are disposable, so their inner storage disappears when the container is removed. Keep anything valuable in a volume or a mounted folder on the host:

docker run -d --name db -v dbdata:/var/lib/mysql ...

Back those folders up. See How to back up your VPS with rsync.

Cleaning up

Images and stopped containers pile up. If the disk fills, run docker system df to see the cause, then docker system prune to remove unused containers, networks and dangling images. Add -a only when you are sure you do not need the unused images.

Next steps

Running several containers together is easier with Compose, described in Docker Compose basics for small projects. And keep the system updated, as in Turn on automatic security updates.


Still stuck? Open a ticket on Discord - run /ticket in any channel, pick a department, and include your Server ID or Invoice ID so we can jump straight in.