Install Docker Engine on Debian
Docker Engine provides the daemon, CLI, and runtime needed to build and run containers on Debian. This guide installs Docker Engine from Docker's official APT repository, verifies the service with a test container, and configures the current user to run Docker without sudo.
The repository method is preferable for a long-lived Debian instance because APT can receive Docker updates through the normal package workflow. Docker currently documents Debian 13 (Trixie), Debian 12 (Bookworm), and Debian 11 (Bullseye), with packages for amd64, armhf, arm64, and ppc64el. Package names and supported releases can change, so the official Docker Debian installation page remains the authority when this article is updated.
Key Takeaways
- Install Docker Engine from Docker's signed APT repository rather than mixing distribution packages with Docker packages.
- Test the daemon with
docker run hello-worldbefore configuring applications or Kubernetes tools. - Membership in the
dockergroup grants root-equivalent access to the host. Add only trusted users, or keep usingsudo.
What Is Docker Engine?
Docker Engine is the host-side service that builds images, stores container data, creates networks, and starts containers. The Docker CLI sends requests to that service through its local socket. Installing the CLI alone does not provide a working container runtime.
The installation has three separate concerns: repository trust, package installation, and daemon access. The repository's signing key lets APT verify Docker packages. The packages install the daemon and related plugins. The Unix socket controls which users can ask that daemon to perform privileged operations.
The Mental Model
Treat the setup as a chain of checks:
- Operating system: confirm the Debian release and architecture are supported.
- Conflicting packages: remove unofficial packages that can provide overlapping commands or incompatible runtime dependencies.
- APT trust: install Docker's keyring and repository definition with readable, explicit permissions.
- Engine service: install the daemon, CLI, containerd, Buildx, and Compose plugins, then confirm the service is active.
-
User access: decide whether commands should use
sudo, Docker-group membership, or rootless mode. - Network policy: review firewall behavior before publishing container ports.
A successful docker version proves that the CLI can reach the daemon. A successful docker run hello-world proves that the daemon can pull an image, create a container, start it, and report its output. Run both checks; they catch different failures.
The Incident
On a new Debian instance, I once treated Docker installation as a single package command and moved directly to a Kubernetes setup. The package installation completed, but the normal user could not access the Docker socket, so Minikube reported a driver failure that looked like a Kubernetes problem. I spent time checking cluster settings before checking docker run. The real fix was a new login session after changing group membership. The lesson was simple: validate Docker as the exact user and shell that will run the next tool.
Prerequisites
- Debian 11, 12, or 13 on a supported architecture
- A non-root user with
sudoaccess - Outbound HTTPS access to Debian mirrors and
download.docker.com - A terminal session on the target Debian instance
- A firewall plan if containers will publish ports outside the host
Before installing, identify the release and architecture:
. /etc/os-release
printf 'Debian release: %s\n' "$VERSION_ID"
printf 'Codename: %s\n' "$VERSION_CODENAME"
dpkg --print-architecture
Walkthrough
1. Remove conflicting Docker packages
Debian may provide packages such as docker.io, while other tools may install containerd or runc separately. Docker's official packages bundle compatible runtime dependencies. Remove conflicting packages if they are present:
sudo apt remove -y docker.io docker-compose docker-doc docker-buildx podman-docker containerd runc
APT may report that some packages are not installed. This command does not remove Docker's stored images, containers, volumes, or networks. Existing data may still be present under /var/lib/docker and /var/lib/containerd.
2. Configure Docker's signed APT repository
Install the keyring directory and Docker's official signing key, then create a deb822 repository definition. The architecture expression prevents APT from selecting packages for a different architecture.
If Docker was previously configured with an older .list file, remove that duplicate source before adding the .sources definition below. Keeping two entries for the same repository with different signing keys makes APT stop with a Conflicting values set for option Signed-By error. This removes repository configuration only; it does not remove Docker packages or container data.
sudo rm -f /etc/apt/sources.list.d/docker.list
sudo apt update
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/debian/gpg \
-o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
sudo tee /etc/apt/sources.list.d/docker.sources > /dev/null <<EOF
Types: deb
URIs: https://download.docker.com/linux/debian
Suites: $(. /etc/os-release && echo "$VERSION_CODENAME")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
Refresh package metadata and confirm Docker packages are visible:
sudo apt update
apt list --all-versions docker-ce 2>/dev/null | sed -n '1,5p'
On Debian testing or a derivative distribution, VERSION_CODENAME may not match a Docker repository suite. Check the official documentation before substituting the corresponding Debian codename.
3. Install Docker Engine and its standard plugins
Install the engine, command-line client, containerd, Buildx, and Compose plugin:
sudo apt install -y docker-ce docker-ce-cli containerd.io \
docker-buildx-plugin docker-compose-plugin
Check that the service is active and that the client can reach it:
sudo systemctl is-active docker
sudo docker version
sudo docker info
On a normal Debian installation, Docker starts with the service installation. If it is inactive, start it and inspect the service status:
sudo systemctl enable --now docker
sudo systemctl status docker --no-pager
4. Verify the installation with a test container
Run Docker's small verification image:
sudo docker run --rm hello-world
The command downloads the image if necessary, creates a temporary container, prints a confirmation message, and removes the container because of --rm. A failure here should be resolved before installing Minikube, Compose applications, or other Docker-dependent tooling.
5. Configure non-root Docker access deliberately
The simplest access model is to prefix Docker commands with sudo. If the instance is trusted and the workflow requires normal-user commands, add the current user to the Docker group:
sudo usermod -aG docker "$USER"
Start a new login session so the shell receives the new group membership. Then verify the exact user path:
id -nG
docker version
docker run --rm hello-world
Do not use sudo docker as a substitute for refreshing the session when testing group access. The root and non-root clients can use different configuration files and caches, which makes troubleshooting harder.
The Docker group is not equivalent to an ordinary application group. A user who can control the Docker daemon can generally gain root-level access to the host. Use the group only for trusted administrators, or investigate Docker's documented rootless mode when that privilege boundary matters.
6. Verify Compose and Buildx
The installation includes the modern Compose and Buildx plugins. Confirm both are available:
docker compose version
docker buildx version
These are plugin commands, so docker-compose and an old standalone docker-buildx command are not required for the documented workflow. Existing scripts may need updating if they depend on legacy command names.
Working with Docker Daily
Useful commands for a new instance include:
| Command | What it does |
|---|---|
docker ps |
List running containers |
docker ps -a |
List running and stopped containers |
docker images |
List locally stored images |
docker logs <container> |
Read container output |
docker exec -it <container> sh |
Open a shell in a running container |
docker inspect <container> |
Show low-level container configuration |
docker system df |
Show Docker disk usage |
docker compose up -d |
Start a Compose application in the background |
Keep the daemon healthy with systemctl is-active docker and monitor disk usage. Images, writable layers, build cache, and container logs can fill a small instance even when few containers are running.
Debugging & Common Pitfalls
docker: permission denied
The daemon may be healthy while the current user lacks permission to access /var/run/docker.sock. Check the service, socket ownership, and active groups:
sudo systemctl is-active docker
ls -l /var/run/docker.sock
id -nG
Use sudo docker ..., or start a new login session after usermod -aG docker "$USER". Avoid changing the socket to world-writable permissions.
APT cannot find docker-ce
The Docker repository may be missing, the codename may be wrong, or sudo apt update may have failed. Inspect the source definition and run the update again:
cat /etc/apt/sources.list.d/docker.sources
sudo apt update
On supported Debian releases, the Suites value should correspond to the Debian codename. Do not blindly use stable as the suite; stable belongs in Components.
Docker service fails to start
Read the service log before reinstalling packages:
sudo systemctl status docker --no-pager
sudo journalctl -u docker.service -n 100 --no-pager
Look for storage-driver, dependency, disk, or network errors. A previous installation may have left incompatible runtime packages or configuration under /etc/docker.
Published ports bypass expected firewall rules
Docker warns that ports published with -p can bypass rules managed by ufw or firewalld. Docker is compatible with iptables-nft and iptables-legacy; rules created only with unsupported native nftables workflows may not behave as expected. Review Docker's firewall documentation and place filtering rules in the DOCKER-USER chain where appropriate before exposing services.
The server runs out of disk
Inspect Docker's usage before deleting anything:
docker system df
sudo du -sh /var/lib/docker /var/lib/containerd
Remove only resources you understand. docker system prune can remove stopped containers, unused networks, dangling images, and build cache; adding --volumes can remove unused data volumes and should be treated as a destructive operation.
FAQ
Should I install docker.io or docker-ce on Debian?
Use Docker's official packages when you want Docker's documented Engine release stream: docker-ce, docker-ce-cli, containerd.io, docker-buildx-plugin, and docker-compose-plugin. Do not mix the distribution's docker.io package with those packages without checking the resulting dependency and upgrade behavior.
Can I run Docker without sudo?
Yes, but adding a user to the Docker group grants root-equivalent control over the host. A new login session is required after changing membership. Keeping sudo is simpler for a tightly controlled administrative workflow; rootless mode is another option when its limitations fit the workload.
Does installing Docker automatically start the daemon?
Docker's Debian package normally starts the service. Verify with sudo systemctl is-active docker, and use sudo systemctl enable --now docker if the service is inactive or is not enabled for boot.
Is the convenience script better than the APT repository?
The convenience script is useful for disposable development environments and automation experiments, but it provides less control over repository setup and package choices. The APT repository is the better default for a Debian instance that will be maintained over time.
How do I completely uninstall Docker?
First remove the packages:
sudo apt purge -y docker-ce docker-ce-cli containerd.io \
docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras
Then remove the repository definition and key if they are no longer needed:
sudo rm -f /etc/apt/sources.list.d/docker.sources
sudo rm -f /etc/apt/keyrings/docker.asc
Images, containers, volumes, and custom configuration are not automatically removed by package removal. Delete /var/lib/docker and /var/lib/containerd only after confirming that all required data has been backed up or discarded.
This article was originally published by DEV Community and written by spmahapatra.
Read original article on DEV Community