If you want to install Docker on Ubuntu, Docker Engine packages applications and their dependencies into isolated containers so they run the same way on a laptop, a CI runner, or a production server. Common use cases include testing releases in clean environments, running services like databases without polluting the host, and building images for deployment.
This guide covers two supported paths: the official Docker APT repository for Ubuntu 24.04 and 22.04, plus the Ubuntu docker.io packages for Ubuntu 26.04. By the end, you will have Docker, Compose, and Buildx installed, non-root access configured, and a verified test container run.
System Requirements
This guide targets Ubuntu 26.04, 24.04, and 22.04 LTS. Docker Engine for Ubuntu is compatible with x86_64/amd64, arm64, armhf, s390x, and ppc64le (ppc64el) architectures; on x86_64 and arm64 this implies a 64-bit Ubuntu install. See the Docker Engine install guide for Ubuntu for the canonical support list.
Choose Your Docker Installation Method
Docker is packaged by Docker Inc. and by Ubuntu. Pick the method that matches your Ubuntu release and the update cadence you want.
| Method | Source | Best For | Update Cadence |
|---|---|---|---|
| Official Docker APT repository (docker-ce) | download.docker.com | Ubuntu 24.04 and 22.04 users who want upstream Docker packages | Fast, direct from Docker Inc. |
Ubuntu docker.io packages | Ubuntu Universe repository | Ubuntu 26.04 users and environments where Docker’s repo is unavailable | Ubuntu-maintained, may lag behind upstream |
For Ubuntu 24.04 and 22.04, the official Docker repository is recommended because it delivers the upstream engine plus the Compose and Buildx plugins. On Ubuntu 26.04, use the Ubuntu docker.io packages because Docker’s repository does not publish resolute packages.
This guide covers Ubuntu 26.04 LTS, 24.04 LTS, and 22.04 LTS. Docker’s APT repository publishes packages for 24.04 and 22.04 only, while Ubuntu 26.04 uses the
docker.iopackages from the Ubuntu repositories. Follow the method that matches your release.
If you use ufw or firewalld, be aware that Docker manages iptables rules directly. Docker supports iptables-nft and iptables-legacy, but rules created with nft are not supported. Review Docker’s packet filtering and firewall guidance before proceeding.
Remove Previous Docker Installations
If you previously installed Docker from another source, remove older packages first to avoid conflicts. Use the Ubuntu package removal command if you installed docker.io, and the Docker Engine removal command if you installed docker-ce from Docker’s repository.
Remove Ubuntu-packaged Docker components:
sudo apt remove docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc
Remove Docker Engine packages from the Docker repository (if you installed them previously):
sudo apt remove docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
If you have not installed any of these packages, apt will report that nothing needs to be removed.
Clean up orphaned dependencies left behind by removed packages:
sudo apt autoremove
The following commands will permanently delete all Docker images, containers, volumes, and networks stored in
/var/lib/docker/and/var/lib/containerd/. Only run these if you want a completely clean Docker installation.
Delete existing Docker data if you want a fresh start:
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd
If you previously added Docker’s official repository, remove the sources file and keyring:
sudo rm /etc/apt/sources.list.d/docker.sources
sudo rm /usr/share/keyrings/docker.gpg
If these files do not exist, skip this step and continue.
Refresh your package index after cleanup:
sudo apt update
Method 1: Install Docker Engine from the official Docker APT repository (Ubuntu 24.04 and 22.04)
This method uses Docker’s upstream packages and includes the official Compose and Buildx plugins.
Add Docker’s APT repository
Install the tools needed to download the repository key. If you are new to curl, see our curl command guide for examples.
sudo apt install ca-certificates curl gpg
Download Docker’s GPG key and convert it into a keyring file that APT can use:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker.gpg
sudo chmod a+r /usr/share/keyrings/docker.gpg
The gpg --dearmor step converts the ASCII key into a binary keyring that APT can reference in the repository file.
Add the Docker repository using the modern DEB822 format:
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Signed-By: /usr/share/keyrings/docker.gpg
EOF
This file reads your Ubuntu codename automatically, so the same command works on both 24.04 and 22.04.
Refresh your package index so APT sees the new Docker repository:
sudo apt update
You should see the Docker repository in the output (Ubuntu 24.04 example):
Get:1 https://download.docker.com/linux/ubuntu noble InRelease [48.5 kB] Get:2 https://download.docker.com/linux/ubuntu noble/stable amd64 Packages [50.7 kB] Hit:3 http://archive.ubuntu.com/ubuntu noble InRelease Hit:4 http://security.ubuntu.com/ubuntu noble-security InRelease Hit:5 http://archive.ubuntu.com/ubuntu noble-updates InRelease Hit:6 http://archive.ubuntu.com/ubuntu noble-backports InRelease Fetched 99.2 kB in 1s (95.5 kB/s) Reading package lists... Building dependency tree... Reading state information... 10 packages can be upgraded. Run 'apt list --upgradable' to see them.
Confirm that APT will install Docker from download.docker.com:
apt-cache policy docker-ce
Example output (Ubuntu 24.04):
docker-ce:
Installed: (none)
Candidate: 5:29.1.5-1~ubuntu.24.04~noble
Version table:
5:29.1.5-1~ubuntu.24.04~noble 500
500 https://download.docker.com/linux/ubuntu noble/stable amd64 Packages
5:29.1.4-1~ubuntu.24.04~noble 500
500 https://download.docker.com/linux/ubuntu noble/stable amd64 Packages
5:29.1.3-1~ubuntu.24.04~noble 500
500 https://download.docker.com/linux/ubuntu noble/stable amd64 Packages
5:29.1.2-1~ubuntu.24.04~noble 500
500 https://download.docker.com/linux/ubuntu noble/stable amd64 Packages
Install Docker Engine
Install Docker Engine and the official Compose and Buildx plugins:
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Verify the installed versions:
docker --version
docker compose version
docker buildx version
Expected output (Ubuntu 24.04/22.04):
Docker version 29.1.5, build 0e6fee6 Docker Compose version v5.0.1 github.com/docker/buildx v0.30.1 9e66234aa13328a5e75b75aa5574e1ca6d6d9c01
Method 2: Install Docker from Ubuntu’s docker.io package (Ubuntu 26.04)
This method uses Ubuntu’s packaged Docker Engine. Compose and Buildx are separate packages in the Ubuntu repositories.
Update your package index:
sudo apt update
Install Docker, Compose, and Buildx from the Ubuntu repositories:
sudo apt install docker.io docker-compose-v2 docker-buildx
If apt cannot locate these packages, enable the Universe repository (common on minimal installs):
sudo apt install software-properties-common
sudo add-apt-repository universe
After enabling Universe, re-run the install command above.
Verify the installed versions:
docker --version
docker compose version
docker buildx version
Expected output (Ubuntu 26.04):
Docker version 29.1.3, build 29.1.3-0ubuntu1 Docker Compose version 2.40.3+ds1-0ubuntu1 github.com/docker/buildx 0.30.1 0.30.1-0ubuntu1
Run a Test Container
After either installation method, run the hello-world container to confirm the Docker daemon can pull images and start containers:
sudo docker run --rm hello-world
Successful output looks like:
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
The docker command requires root privileges by default. The next section covers configuring non-root user access so you can run Docker without sudo.
Managing Docker with systemd on Ubuntu
Docker installs systemd unit files at /usr/lib/systemd/system/docker.service and /usr/lib/systemd/system/docker.socket, so you can manage the daemon with standard systemctl commands.
sudo systemctl start docker.service
This starts the Docker service immediately for the current session. Use the enable command below if you want it to start automatically at boot.
sudo systemctl stop docker.service
This stops the Docker service until you start it again or reboot. It does not change whether Docker auto-starts on boot.
sudo systemctl restart docker.service
Restarts the Docker service.
sudo systemctl status docker.service
Displays the current status of the Docker service.
sudo systemctl enable docker.service
Enables the Docker service to start automatically on system boot. Docker installs with this enabled by default, but use this command if you previously disabled auto-start.
sudo systemctl disable docker.service
Disables automatic startup of the Docker service on system boot. The service remains available for manual start with systemctl start docker.service, but won’t launch during boot.
Docker Configuration and Usage
Manage Docker as a non-root user on Ubuntu
When running Docker, avoid using the root user to prevent security risks and accidental changes to the host system. Instead, manage Docker as a non-root user by adding users to the docker group, or consider rootless mode for tighter isolation.
If you want to add a new user for Docker management, use the following command:
sudo useradd -m dockeruser
Verify the new account exists:
id dockeruser
uid=1001(dockeruser) gid=1001(dockeruser) groups=1001(dockeruser)
If the user already exists, skip this step.
To add your current user to the docker group, run:
sudo usermod -aG docker $USER
The Docker group grants root-equivalent privileges to users. Members can access the Docker daemon socket, which provides full control over the host system. Only add trusted users to this group, as they can escape container isolation and modify host files. For production environments, consider using rootless Docker mode or implementing proper access controls.
If you want to grant access to a different account, replace $USER with that username.
After adding a user to the Docker group, you have two options to activate the group membership:
Option 1: Activate immediately without logging out using the newgrp command:
newgrp docker
This starts a new shell session with the docker group active, allowing you to run Docker commands immediately.
Option 2: Log out and back in, or reboot your system for the changes to take effect system-wide.
To ensure the user can run Docker commands, use the following command:
docker ps
If Docker is working correctly with your user account, you should see an empty container list:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
This confirms Docker commands run without sudo. If you see a permission error instead, verify the group membership activated correctly or try logging out and back in.
If you encounter permission errors when running Docker commands (such as errors accessing ~/.docker/config.json), fix the ownership and permissions on the Docker configuration directory:
sudo chown "$USER":"$USER" "$HOME/.docker" -R
sudo chmod -R g+rwx "$HOME/.docker"
These commands set the correct ownership and permissions for your user’s Docker configuration directory, resolving common permission-related issues. If you want a refresher on chmod flags, see our chmod command guide.
Configure Log Rotation
By default, Docker logs to the JSON file format without size limits. This can consume unlimited disk space over time.
Docker’s default json-file logging driver does not limit log file size or implement automatic rotation. Without proper configuration, containers can consume unlimited disk space through logging, potentially filling your filesystem. Always configure log rotation with
max-sizeandmax-fileoptions in production environments to prevent disk exhaustion.
To configure log rotation, create the Docker daemon configuration file:
sudo nano /etc/docker/daemon.json
If /etc/docker/daemon.json already exists, merge these log settings with your current JSON instead of replacing the file.
Add the following configuration to limit log file size and count:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
This configuration limits each container’s log file to 10 megabytes and keeps a maximum of 3 rotated log files. Adjust these values based on your storage capacity and logging requirements.
After creating the file, restart the Docker daemon to apply the changes:
sudo systemctl restart docker.service
Existing containers retain their original logging configuration. Only containers created after this change will use the new log rotation settings.
Docker Command Reference
The following table summarizes commonly used Docker commands for managing containers, images, networks, and volumes:
| Command | Description |
|---|---|
docker run | Run a new container from an image. |
docker ps | List all running containers. |
docker images | List all available images. |
docker build | Build a new image from a Dockerfile. |
docker stop | Stop a running container. |
docker rm | Remove a container. |
docker rmi | Remove an image. |
docker network | Manage Docker networks. |
docker volume | Manage Docker volumes. |
docker info | Display system-wide Docker information. |
docker search | Search Docker Hub for images. |
View Docker System Information
The docker info command displays comprehensive system-wide information about your Docker installation, including the number of containers and images, storage driver details, and system resources.
docker info
This displays detailed information about your Docker environment, helping you verify configuration and troubleshoot issues. The output includes container and image counts, storage driver type, kernel version, and available plugins.
Search Docker Hub for Images
The docker search command searches Docker Hub for publicly available images matching your search term. This helps you discover official images and community-maintained alternatives before pulling them.
docker search ubuntu
This searches Docker Hub for images containing “ubuntu” in their name or description. The results include the image name, description, star count, and whether it’s an official image. Official images are labeled as “Official” and typically have clearer maintenance and documentation signals.
Run Containers from Images
The docker run command creates and starts a new container from an image. For example, to run a container from the ubuntu image:
docker run -it ubuntu:latest /bin/bash
This starts a new container from the ubuntu image and opens a shell inside the container.
List Running Containers
The docker ps command lists all running containers and provides information about each, including container ID, image name, and status.
docker ps
This displays a list of all running containers.
List Downloaded Images
The docker images command lists all available images and supplies information about each image, including image ID, repository, and tag.
docker images
This displays a list of all available images.
Build Images from Dockerfiles
The docker build command builds a new image from a Dockerfile, a script containing instructions for building an image.
docker build -t myimage:latest .
This builds a new image called myimage using the Dockerfile in the current directory.
Stop Running Containers
The docker stop command stops a running container. For example, to stop a container with the ID abcdefg:
docker stop abcdefg
This stops the container with the ID abcdefg.
Remove Containers
Use the docker rm command to remove a container. For example, to eliminate a container with the ID abcdefg:
docker rm abcdefg
This removes the container with the ID abcdefg.
Remove Images
The docker rmi command removes an image. For example, to eliminate an image with the ID 1234567:
docker rmi 1234567
This removes the image with the ID 1234567.
Manage Docker Networks
The docker network command manages Docker networks. It offers options to create, list, and remove networks.
docker network create mynetwork
This creates a new network called mynetwork.
Manage Docker Volumes
The docker volume command manages Docker volumes, providing options to create, list, and remove volumes.
docker volume create myvolume
This creates a new volume called myvolume.
Save Container Changes as Images
When working with Docker containers, changing the container you want to save as a new image is common. You can use the docker commit command to commit changes in a container to a Docker image.
First, start a new container from the base image and make any necessary changes to the container. For example, to start a new container from the ubuntu image and open a shell inside the container, you can use the following command:
docker run -it --name mycontainer ubuntu:latest /bin/bash
This command will start a new container from the ubuntu image and open a shell inside the container. You can make any necessary changes to the container, such as installing new software or modifying configuration files.
Once you have made the necessary changes, you can use the docker commit command to create a new image from the container. For example, to create a new image called myimage with the changes made in the mycontainer container, you can use the following command:
docker commit mycontainer myimage:latest
This command will create a new image called myimage with the changes made in the mycontainer container. You can now use this new image to create and run new containers with the updated software or configuration.
It’s important to note that the docker commit command only saves changes made to the container’s file system and does not save changes to the container’s networking or storage. If you need to save changes to these areas, use other Docker commands, such as docker network or docker volume.
Security Best Practices
Securing your Docker installation protects both containers and the host system from potential vulnerabilities. Follow these essential security practices when working with Docker on Ubuntu:
Run containers with least privilege: Avoid running containers as root when possible. Use the --user flag to specify a non-root user inside containers, limiting potential damage if a container is compromised.
Keep Docker updated: Regularly update Docker and the host system to receive security patches and bug fixes. Subscribe to Docker security advisories and apply updates promptly.
Docker CE packages (official repository):
sudo apt update && sudo apt install --only-upgrade docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Ubuntu docker.io packages:
sudo apt update && sudo apt install --only-upgrade docker.io docker-compose-v2 docker-buildx
These sequences refresh the package lists and upgrade only the Docker components, leaving the rest of your system untouched.
Consider configuring unattended-upgrades to automatically apply security updates to Docker and the host system, ensuring your environment stays protected against known vulnerabilities.
Enable Docker Content Trust: Docker Content Trust uses digital signatures to verify the publisher and integrity of images. See the Content Trust documentation for details, then enable it by setting the environment variable:
export DOCKER_CONTENT_TRUST=1
This ensures you only pull signed and verified images from trusted publishers.
Limit network exposure: Only expose necessary ports when running containers. Use specific port mappings instead of exposing all ports, and bind to localhost (127.0.0.1) instead of 0.0.0.0 when services don’t need external access. For remote management, use SSH tunneling to access container services securely.
docker run -p 127.0.0.1:8080:80 nginx
This runs an Nginx container with port 80 only accessible from the local machine on port 8080.
Scan images for vulnerabilities: Use Docker Scout or third-party tools to scan images for known security vulnerabilities before deploying them to production.
Implement resource limits: Prevent containers from consuming excessive system resources by setting memory and CPU limits using the --memory and --cpus flags.
Monitor for intrusion attempts: Use Fail2ban on your host system to detect and block repeated unauthorized access attempts to services running in containers.
Troubleshooting Common Issues
These fixes cover the most common Docker issues on Ubuntu.
Docker daemon is not running
If the Docker daemon is not running, Docker CLI commands report a connection error. Run docker info and look for the server error below:
docker info
Client: Docker Engine - Community
Version: 29.1.5
Context: default
Debug Mode: false
Plugins:
buildx: Docker Buildx (Docker Inc.)
Version: v0.30.1
Path: /usr/libexec/docker/cli-plugins/docker-buildx
compose: Docker Compose (Docker Inc.)
Version: v5.0.1
Path: /usr/libexec/docker/cli-plugins/docker-compose
Server:
failed to connect to the docker API at unix:///var/run/docker.sock; check if the path is correct and if the daemon is running: dial unix /var/run/docker.sock: connect: no such file or directory
Start and enable the Docker service:
sudo systemctl start docker
sudo systemctl enable docker
Verify the fix by re-running the hello-world test container from the earlier verification step.
Permission denied connecting to the Docker socket
If you run Docker commands without sudo and see a socket permission error, the output looks like:
permission denied while trying to connect to the docker API at unix:///var/run/docker.sock
Check whether your user is in the docker group:
groups $USER
joshua adm dialout cdrom floppy sudo audio dip video plugdev users netdev docker
If docker is missing, add your user to the group and activate it:
sudo usermod -aG docker $USER
newgrp docker
If you prefer not to use newgrp, log out and back in to apply group changes system-wide.
Confirm the socket permissions are owned by root:docker:
ls -l /var/run/docker.sock
srw-rw---- 1 root docker 0 Jan 14 19:56 /var/run/docker.sock
Verify access by listing containers:
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Container networking issues
If containers cannot reach external networks or other containers, verify Docker’s network configuration:
docker network ls
NETWORK ID NAME DRIVER SCOPE e0f4b42f45f7 bridge bridge local 2b92e331d2c7 host host local 359d4c681ec9 none null local
If the bridge network is missing, restart Docker with sudo systemctl restart docker to recreate the default networks. If you use ufw or firewalld, review the firewall warning at the beginning of this guide, as these firewalls may block container traffic by default.
Test container networking by running a simple network test:
docker run --rm busybox ping -c 3 google.com
Unable to find image 'busybox:latest' locally latest: Pulling from library/busybox e59838ecfec5: Pulling fs layer 0f4360cf3c3e: Download complete e59838ecfec5: Download complete e59838ecfec5: Pull complete Digest: sha256:2383baad1860bbe9d8a7a843775048fd07d8afe292b94bd876df64a69aae7cb1 Status: Downloaded newer image for busybox:latest PING google.com (142.250.124.138): 56 data bytes 64 bytes from 142.250.124.138: seq=0 ttl=63 time=38.637 ms 64 bytes from 142.250.124.138: seq=1 ttl=63 time=37.094 ms 64 bytes from 142.250.124.138: seq=2 ttl=63 time=37.385 ms --- google.com ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max = 37.094/37.705/38.637 ms
If this fails, check your host’s DNS configuration and ensure Docker can access /etc/resolv.conf.
Remove Docker from Ubuntu
Use the removal path that matches how you installed Docker.
Remove Docker Engine packages (official Docker repository)
Uninstall Docker Engine, the CLI, containerd, and the plugin packages:
sudo apt purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras
Remove unused dependencies:
sudo apt autoremove
Remove the Docker repository and keyring:
sudo rm /etc/apt/sources.list.d/docker.sources
sudo rm /usr/share/keyrings/docker.gpg
Refresh the package index:
sudo apt update
Verify the Docker CE packages are gone:
dpkg -l docker-ce
dpkg-query: no packages found matching docker-ce
Remove Ubuntu docker.io packages
Uninstall the Ubuntu-packaged engine and plugins:
sudo apt purge docker.io docker-compose-v2 docker-buildx
Remove unused dependencies:
sudo apt autoremove
Verify the packages are gone:
dpkg -l docker.io
dpkg-query: no packages found matching docker.io
The following commands permanently delete all Docker images, containers, volumes, and custom networks. This action cannot be undone. Back up any important container data before proceeding.
Delete Docker data directories:
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd
Removing
/etc/dockerdeletes daemon configuration files such asdaemon.json. Back up any custom settings before deleting this directory.
Remove custom Docker daemon configuration:
sudo rm -rf /etc/docker
Docker Documentation and Resources
Explore these official Docker resources for further learning:
- Docker Documentation: Comprehensive guides for configuring and using Docker.
- Install Docker Engine on Ubuntu: Official installation and repository reference.
- Post-installation Steps: Official guide for configuring Docker after installation.
- Docker Security: Best practices for securing Docker deployments.
- Docker Compose: Define and run multi-container applications.
Conclusion
You now have Docker installed on Ubuntu using the method that matches your release, along with Compose and Buildx for modern workflows. The setup includes systemd service management, non-root user access through the docker group, and security best practices like log rotation. From here, explore Docker Compose for multi-container applications and expand your container networking as needed.