Installing Docker on AlmaLinux or Ubuntu
This guide walks you through installing Docker Engine on AlmaLinux 9 or Ubuntu 24.04 using Docker's official repositories rather than distro packages. You will configure a non-root user to run Docker commands, understand the security implications, and learn why the convenience installation script is unsuitable for production servers.
This picks up from a server you can already reach over SSH.
You install Docker on AlmaLinux 9 or Ubuntu 24.04 by using Docker’s own package repository rather than the distro package. On Ubuntu you remove any conflicting packages first, then add Docker’s GPG key and repository, install the engine and plugins, and verify with hello-world. On AlmaLinux you add Docker’s RPM repository, install, enable the service, and verify.
Before you start
- This guide uses Docker’s official repositories for AlmaLinux 9 and Ubuntu 24.04. They receive updates first and avoid version mismatches.
- You need a user with sudo on the VPS. If you are on our London VPS or US VPS ranges, you manage the VPS itself in Virtualizor through your Hostworld client area. SSH access is to the operating system inside that VPS.
- Ubuntu only: uninstall any distro Docker packages before switching to Docker’s repository. Docker’s docs call out these specifically: docker.io, docker-compose, podman-docker, containerd and runc. Removing them avoids daemon breakage from mismatched components.
- Ubuntu only: Docker now documents the keyring-and-.sources workflow. apt-key is deprecated. The GPG key must live in /etc/apt/keyrings/docker.asc and be world readable, or apt will ignore the repo.
- AlmaLinux only: Docker does not auto-enable itself on RPM-based systems after install. You need to enable and start the service or docker commands will fail.
- Repository integrity on AlmaLinux: when prompted, check the Docker repo GPG fingerprint is 060A 61C5 1B55 8A7F 742B 77AA C52F EB6B 621E 9F35 before accepting.
- Data and uninstall risk: removing the conflicting packages on Ubuntu does not remove /var/lib/docker. Images, containers and volumes remain. If you later remove /var/lib/docker, that permanently deletes your containers, images and volumes. Do not do that on a live server unless you intend to wipe Docker state and have backups of named volumes.
- Security model: adding a user to the docker group grants root-level privileges on that host. Treat membership of that group as root-equivalent. If you need to avoid this trust model, consider Docker’s rootless mode.
- Firewall behaviour: when you publish container ports, Docker’s NAT happens before ufw or firewalld’s usual chains. Put any custom filtering rules in the DOCKER-USER chain, or use the documented nftables backend if you need nftables specifically.
- Logs: the default json-file logs grow without bounds. Plan log rotation or use an alternative logging driver after install.
- Avoid the convenience script: Docker’s get.docker.com script is not recommended for production. It runs as root, auto-detects and installs dependencies without prompting, offers little customisation, installs the latest stable which can trigger unexpected major version upgrades, and it is not designed to upgrade an existing install.
Step 1: Remove conflicting packages on Ubuntu
This removes Ubuntu’s own Docker and related packages so they do not conflict with Docker’s repository packages. It does not remove images or volumes under /var/lib/docker.
Ubuntu 24.04
sudo apt-get remove docker.io docker-compose podman-docker containerd runc
AlmaLinux 9
There is no action here for AlmaLinux 9 in Docker’s instructions. Move on to adding the Docker repository.
Step 2: Add Docker’s official repository
Ubuntu 24.04
This creates the keyrings directory if it does not exist yet.
sudo mkdir -p /etc/apt/keyrings
This ensures the Docker GPG key file is world readable. If you skip this, apt may ignore the Docker repository.
sudo chmod a+r /etc/apt/keyrings/docker.asc
Now add Docker’s GPG key to /etc/apt/keyrings/docker.asc and create /etc/apt/sources.list.d/docker.sources using the new “.sources” format documented by Docker for Ubuntu 24.04. Follow the commands exactly as shown in Docker’s documentation for Ubuntu:
AlmaLinux 9
This installs the DNF plugins package so you can use dnf config-manager to add repositories.
sudo dnf install dnf-plugins-core
Use dnf config-manager to add Docker’s official CentOS repository for EL9 as shown in Docker’s documentation for CentOS and EL9. When prompted during the first install from this repo, verify the GPG fingerprint matches 060A 61C5 1B55 8A7F 742B 77AA C52F EB6B 621E 9F35.
Step 3: Install Docker Engine and plugins
This installs the engine, CLI, container runtime, Buildx and the Compose plugin from Docker’s repository.
Ubuntu 24.04
This refreshes apt’s package lists to include the Docker repository you added.
sudo apt-get update
This installs Docker Engine, CLI, containerd, Buildx and the Compose plugin from Docker’s repository.
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
AlmaLinux 9
This installs Docker Engine, CLI, containerd, Buildx and the Compose plugin from Docker’s repository for EL9.
sudo dnf install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Step 4: Enable, start and verify the Docker service
This starts the Docker service and runs the hello-world image to confirm the install worked.
Ubuntu 24.04
This starts the Docker service if it is not already running.
sudo systemctl start docker
This pulls and runs the hello-world test image in a temporary container, then removes it. You should see a message confirming your installation appears to be working correctly.
sudo docker run --rm hello-world
AlmaLinux 9
This enables Docker to start on boot and starts it now.
sudo systemctl enable --now docker
This pulls and runs the hello-world test image in a temporary container, then removes it. You should see a message confirming your installation appears to be working correctly.
sudo docker run --rm hello-world
Step 5: Allow your non-root user to run Docker
This creates the docker group if it does not exist and adds your current user to it. Membership of this group grants root-level privileges via the Docker daemon on this host. Only add users you fully trust. If you need to avoid that, look at Docker’s rootless mode.
Ubuntu 24.04
This creates the docker group if absent.
sudo groupadd docker
This adds your current user to the docker group.
sudo usermod -aG docker "$USER"
This applies your new group membership to your current shell session so you can use Docker without logging out and in.
newgrp docker
This verifies you can run Docker commands without sudo.
docker run --rm hello-world
AlmaLinux 9
This creates the docker group if absent.
sudo groupadd docker
This adds your current user to the docker group.
sudo usermod -aG docker "$USER"
This applies your new group membership to your current shell session so you can use Docker without logging out and in.
newgrp docker
This verifies you can run Docker commands without sudo.
docker run --rm hello-world
Security note: Docker’s own documentation states that the docker group grants root-level privileges. Treat it as equivalent to sudo on that host. If that is not acceptable for your use case, prefer Docker’s rootless mode instead.
Step 6: Confirm Docker Compose is available
This checks that Docker Compose is installed as the modern CLI plugin. Going forward you use docker compose, not the old docker-compose binary.
Ubuntu 24.04
docker compose version
AlmaLinux 9
docker compose version
Step 7: Know what not to do on a server you care about
- Do not use the convenience script from get.docker.com on a production VPS. Docker’s own docs say it is not recommended for production. It runs as root, auto-detects and installs dependencies without prompting, gives you little control, and by default installs the latest stable which can trigger unexpected major version upgrades. It is not designed to upgrade an existing install and may leave dependencies outdated. Use the repository method above instead.
- Plan your firewall. Docker’s published ports are DNATed before ufw or firewalld’s usual chains, so services can be reachable when you expect them to be blocked. Put custom rules in the DOCKER-USER chain. If you need nftables, use Docker’s documented nftables backend and follow its guidance.
- Plan your logs. The default json-file driver grows without bounds. Enable log rotation or choose a different logging driver to keep disk usage under control.
What next
If you would like us to check your VPS install or you hit errors during repository setup or service start, open a support ticket and tell us which step you reached. If you are shopping for a VPS that runs AlmaLinux or Ubuntu, see our Linux VPS in London or New York. For more server administration topics, browse our VPS guides.
The next step in most playbooks is to put a simple workload behind Docker Compose and publish it safely. Continue with container networking and firewall rules, or add log rotation in your Docker daemon settings.
Common questions
Why install from Docker’s repository instead of my distro’s package?
Docker’s repository keeps the engine and its components consistent and current. Mixing Ubuntu’s docker.io with Docker’s docker-ce, or leaving older containerd and runc in place, can cause version mismatches and daemon breakage. Using one source avoids that.
Does removing docker.io on Ubuntu delete my images or volumes?
No. Removing the packages does not remove /var/lib/docker. Your images, containers and volumes remain. If you delete /var/lib/docker yourself, that permanently deletes them.
Why did Docker not start after install on AlmaLinux?
On RPM-based systems Docker is not auto-enabled. You need to enable and start it: sudo systemctl enable --now docker. Without that the docker client cannot reach the daemon.
Is adding my user to the docker group safe?
It depends on your threat model. The docker group grants root-level privileges on that host. Only add fully trusted users. If you need to avoid that, prefer Docker’s rootless mode as documented by Docker.
Where did docker-compose go?
Compose is installed as the docker compose CLI plugin through the docker-compose-plugin package. Use docker compose going forward and verify with docker compose version.
Why do my ufw or firewalld rules not block a published container port?
Docker’s DNAT happens before those tools’ usual chains. Put custom rules in the DOCKER-USER chain, or configure the nftables backend if you need nftables. Docker’s networking docs explain the flow.