Installing Docker and Docker Compose on Ubuntu (Using Docker’s Official Repository)
Remove old Docker packages and install Docker Engine and the Compose plugin on Ubuntu Server using Docker’s official repository.
When I first started with Docker, I used to just run apt install docker.io
and call it a day. It worked – but not always well.
The Docker and Compose versions from Ubuntu's default repositories were often outdated, and I quickly ran into missing features and annoying compatibility issues.
One example: the newer Docker Compose v2 plugin (which integrates with the docker
command) wasn’t available at all – Ubuntu’s repo still had the old, now-deprecated docker-compose
v1 binary.
After a bit of digging, I found the better way: installing Docker Engine and the Compose plugin straight from Docker’s official repository. It’s what the Docker team recommends, and it ensures you're always running the latest stable versions.
In this guide, I’ll walk you through the steps I now use – a clean setup that keeps things up-to-date and future-proof.
Subscribe for occasional updates – installation guides, practical tips, and lessons learned.
Uninstall Old Packages
Before installing Docker from the official repository, it’s a good idea to remove any old or conflicting packages that might be lingering from a previous setup.
You can uninstall them all in one go with this loop:
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do
sudo apt remove -y $pkg
done
This command iterates through common legacy Docker and container packages – such as docker.io
, docker-compose
, containerd
, and more – and uninstalls each one.
Once that’s done, clean up any leftover dependencies:
sudo apt autoremove -y
This step ensures any libraries or packages that were only needed by the old Docker binaries are removed, leaving you with a clean slate for the new installation.
Install Docker from Official Docker Repository
Now it’s time to install Docker Engine and the Docker Compose plugin using Docker’s official APT repository – not the outdated packages from Ubuntu’s default sources.
This ensures you get the latest version of Docker CE (Community Edition) along with the integrated Compose v2 plugin.
Run the following commands to add Docker’s GPG key and repository:
# Update your package list and install tools needed for the setup
sudo apt update
sudo apt install -y ca-certificates curl gnupg
# Create a keyring directory (best practice for modern APT key management)
sudo install -m 0755 -d /etc/apt/keyrings
# Download Docker’s official GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
| sudo tee /etc/apt/keyrings/docker.asc > /dev/null
# Set correct permissions
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the Docker repository to APT sources
echo \
"deb [arch=$(dpkg --print-architecture) \
signed-by=/etc/apt/keyrings/docker.asc] \
https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" \
| sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Refresh package list again
sudo apt update
Let’s break down what this does:
- Installs required packages like
curl
andgnupg
(if not already present) for handling HTTPS and GPG keys. - Downloads Docker’s official GPG key and saves it in
/etc/apt/keyrings/docker.asc
(a secure location for APT keys). - Adds Docker’s APT repository to your server’s software sources (pointing to your Ubuntu release codename).
- Updates the package list to include Docker’s repository.
Once the repo is set up, install Docker and its core components:
sudo apt install -y docker-ce docker-ce-cli containerd.io \
docker-buildx-plugin docker-compose-plugin
This installs the Docker daemon (docker-ce
) along with:
docker-ce-cli
: The command-line interface for Docker.containerd.io
: The container runtime Docker uses under the hood.docker-buildx-plugin
: Docker’s Buildx plugin (for extended build capabilities).docker-compose-plugin
: The Docker Compose v2 plugin, which adds thedocker compose
subcommand.
Sometimes Docker doesn’t start automatically after installation. To ensure it’s running, start the service and check its status:
sudo systemctl start docker.service
sudo systemctl status docker.service
If the service is listed as active (running)
, Docker is ready to use – otherwise, you can inspect its logs with sudo journalctl -u docker.service --no-pager
to diagnose any startup issues.
Run Docker Hello-World
To verify that Docker Engine is installed and working properly, run the classic hello-world
container:
sudo docker run hello-world
This command downloads a test image and runs it in a container. When the container runs, it prints a Hello from Docker!
confirmation message and then exits.
If you see this message, congrats – your Docker installation is successful.
Manage Docker as a non-root user
By default, you need to use sudo
for all Docker commands. If you’d prefer to run Docker as your normal user (without sudo
):
sudo usermod -aG docker $USER
After running this, log out and SSH back in (or reboot) for the group change to take effect.
Once you’ve SSHed in again, test it by running docker info
or docker run hello-world
again – this time without the sudo
prefix.
Verify Docker Compose Plugin
Now that Docker and the Compose plugin are installed, let’s confirm that Docker Compose v2 is working properly.
Run the following command to see if Docker Compose is recognized:
sudo docker compose version
If everything was set up correctly, this will display the Compose plugin’s version, for example:
Docker Compose version v2.x.x
The important part is that you see a version starting with v2
, confirming that you have Docker Compose V2 installed as a plugin.
If you see an error:
- Double-check that you installed the
docker-compose-plugin
package. - Make sure you're running the command as
sudo
or that your user is part of thedocker
group.
Now, rerun the previous command and verify whether Docker Compose is recognized.
Run a Quick Docker Compose Test
Let’s test Docker Compose by launching a simple container.
Create a test directory:
mkdir docker-compose-test && cd docker-compose-test
Create a docker-compose.yml
file with the following content:
services:
hello:
image: hello-world
This defines a Compose app with one service named hello
, using Docker’s tiny hello-world
image.
Run the application:
sudo docker compose up
Docker (via the Compose plugin) will pull the hello-world
image (if not already pulled) and start the container.
You should see output indicating that Docker is creating and running the container, and then the Hello from Docker!
message from the hello-world
container.
Compose will manage the container’s lifecycle. Since hello-world
exits after printing its message, you’ll likely see Compose stop the container once it’s done.
For example, the output may look like:
[+] Running 2/2
✔ Network test_default Created 0.1s
✔ Container test-hello-1 Created 0.1s
Attaching to hello-1
hello-1 |
hello-1 | Hello from Docker!
hello-1 | This message shows that your installation appears to be working correctly.
...
hello-1 exited with code 0
Success! This confirms that docker compose
is working, and the Compose plugin is running correctly.
In a real-world app, your containers would typically stay running – like a web service using NGINX or a database – but for testing, hello-world
is a simple and safe way to verify the setup.
Conclusion and Final Thoughts
By installing Docker from Docker’s official APT repository, you’ve set yourself up with:
- The latest Docker Engine
- The official Docker Compose v2 plugin
- A setup that follows current best practices for Ubuntu servers
This approach not only gives you access to the newest features (like docker compose
instead of the old docker-compose
binary), but also ensures smoother upgrades moving forward.
💬 Found this guide helpful?
I’d love to hear your thoughts, questions, or suggestions in the discussion section below. Your feedback helps improve future guides and supports others on their server journey.
Prefer a more direct conversation? Feel free to contact me anytime.
Discussion