Skip to content

TutorialsContainers & Docker

How to install Docker Engine on Debian 12 and 13

Install Docker Engine with the Buildx and Compose plugins on Debian 13 Trixie or Debian 12 Bookworm from Docker's official apt repository, then secure it.

  • Beginner
  • 15 min read
  • Updated

Tested on: Debian 12, Debian 13

This guide is not available in your language yet, so it is shown in English.

On this page
  1. Prerequisites
  2. Step 1 — Remove conflicting packages
  3. Step 2 — Add Docker's apt repository
  4. Step 3 — Install Docker Engine and the plugins
  5. Step 4 — Run Docker without sudo (optional)
  6. Step 5 — Turn on log rotation
  7. Step 6 — Keep published ports behind your firewall
  8. Update Docker
  9. Back up and restore
  10. Uninstall Docker
  11. Troubleshooting
  12. sudo: command not found
  13. Package 'docker-ce' has no installation candidate
  14. permission denied while trying to connect to the Docker daemon socket
  15. Containers have no network access after changing firewall rules
  16. The disk is filling up
  17. Next steps

Docker Engine is the container runtime behind most of the self-hosted apps and AI tools in this library. On Debian, the cleanest way to get a current Docker with the Buildx and Compose plugins is Docker's own apt repository. This guide sets it up on Debian 13 (Trixie) or Debian 12 (Bookworm), then covers running Docker without sudo, log rotation, the firewall caveat for published ports, updates, backups and common errors.

Prerequisites

  • A server running Debian 13 (Trixie) or Debian 12 (Bookworm). Docker publishes Debian packages for amd64, arm64, armhf and ppc64le.
  • A non-root user with sudo rights and SSH key login. A minimal Debian install may not include sudo; Secure a new Linux server and Set up SSH keys show how to prepare the account.
  • Outbound HTTPS access to download.docker.com and to the registries you will pull images from.

Docker's documentation does not give a minimum CPU or memory size for Docker Engine; the daemon itself is small. Size the server for the containers you plan to run, using the requirements in each app guide, and keep at least 20% of the disk free for images, logs and volumes under /var/lib/docker.

Step 1 — Remove conflicting packages

Debian's archive contains Docker-related packages that conflict with Docker Engine. Remove any that are installed:

Bash
sudo apt remove $(dpkg --get-selections docker.io docker-compose docker-doc docker-buildx podman-docker containerd runc | cut -f1)

If nothing is installed, dpkg prints "no packages found" warnings and there is nothing to remove. Images, containers and volumes already in /var/lib/docker are kept.

Step 2 — Add Docker's apt repository

Install the tools for fetching the signing key, save Docker's GPG key and add the repository in deb822 format:

Bash
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/debian/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
Bash
sudo tee /etc/apt/sources.list.d/docker.sources <<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
sudo apt update

Suites becomes trixie or bookworm. Confirm that apt now offers Docker's build:

Bash
apt-cache policy docker-ce

The Candidate line should point to https://download.docker.com/linux/debian.

Step 3 — Install Docker Engine and the plugins

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

On Debian the service starts automatically and is enabled at boot. Check it and run the test container:

Bash
sudo systemctl status docker --no-pager
sudo docker run --rm hello-world
docker compose version

You should see "Hello from Docker!" followed by the Compose plugin version.

Step 4 — Run Docker without sudo (optional)

Add your admin user to the docker group, then start a new login session (or run newgrp docker):

Bash
sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker
docker run --rm hello-world

The package normally creates the group already, so groupadd may report that it exists.

Step 5 — Turn on log rotation

With the default json-file driver, container logs grow without limit. Switch new containers to the local driver, which rotates and compresses logs:

Bash
sudo tee /etc/docker/daemon.json <<'EOF'
{
  "log-driver": "local",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}
EOF
sudo systemctl restart docker
docker info | grep -i "logging driver"

The output should read Logging Driver: local. Containers created before the change keep their old settings until you recreate them, for example with docker compose up -d --force-recreate.

Step 6 — Keep published ports behind your firewall

A port published without a host address (-p 8080:80) listens on every address of the server. Docker documents that ufw and firewalld rules do not filter these ports, because Docker processes the traffic before those rules apply. Debian does not install a firewall front end by default, so install ufw first:

Bash
sudo apt install ufw
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose

Then publish app containers only on the loopback address and let a reverse proxy handle ports 80 and 443. In Compose that looks like this:

YAML
services:
  app:
    image: nginx:stable
    ports:
      - "127.0.0.1:8080:80"

Set up the proxy with Caddy, Nginx with Certbot or Traefik. From another computer, nc -vz your-server-ip 8080 should now fail to connect.

Update Docker

Docker packages update together with the rest of the system:

Bash
sudo apt update
sudo apt upgrade
docker version

An upgrade of docker-ce restarts the daemon. Containers with a restart policy such as unless-stopped come back automatically; containers without one stay stopped until you start them. Debian's unattended-upgrades, if you use it, applies Debian security updates by default and does not include Docker's repository, so schedule Docker upgrades yourself.

Updating the apps inside containers is a separate task: pull the new image and recreate the container, as each app guide explains.

Back up and restore

Back up the state, not the images (images can be pulled again):

  • named volumes in /var/lib/docker/volumes/,
  • host directories you bind-mount into containers,
  • compose.yaml and .env files,
  • /etc/docker/daemon.json.

To archive a named volume, stop the containers that write to it and run a short-lived container that packs the volume into the current directory:

Bash
docker run --rm -v app_data:/data -v "$(pwd)":/backup debian:stable-slim tar czf /backup/app_data.tar.gz -C /data .

To restore, create the volume and unpack the archive into it:

Bash
docker volume create app_data
docker run --rm -v app_data:/data -v "$(pwd)":/backup debian:stable-slim tar xzf /backup/app_data.tar.gz -C /data

Dump databases with their own tools (pg_dump, mariadb-dump) through docker exec rather than copying live database files, and keep a copy of every backup off the server.

Uninstall Docker

Bash
sudo apt purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras
Bash
sudo rm -rf /var/lib/docker /var/lib/containerd
sudo rm /etc/apt/sources.list.d/docker.sources /etc/apt/keyrings/docker.asc

Troubleshooting

sudo: command not found

The server was installed with a root password and without sudo. Log in as root, run apt install sudo, add your user with usermod -aG sudo youruser, and log in again as that user.

Package 'docker-ce' has no installation candidate

apt is not reading Docker's repository. Run cat /etc/apt/sources.list.d/docker.sources and check that Suites shows trixie or bookworm and that the URI contains /linux/debian (not /linux/ubuntu). Then run sudo apt update and look for NO_PUBKEY or 404 errors.

permission denied while trying to connect to the Docker daemon socket

Your session does not have the docker group yet. Check with id; if docker is missing, repeat Step 4 and log in again, or use sudo docker meanwhile.

Containers have no network access after changing firewall rules

Flushing the ruleset (nft flush ruleset or iptables -F) also removes Docker's rules. Restart Docker with sudo systemctl restart docker to recreate them, and add your own filtering to the DOCKER-USER chain instead of flushing tables.

The disk is filling up

Run docker system df to see what uses the space. docker system prune removes stopped containers, unused networks, dangling images and build cache; docker system prune -a also removes images that no container uses. Leave --volumes out unless you are certain no volume holds data you need, and turn on log rotation (Step 5).

Next steps

Frequently asked questions

Is Debian's docker.io package good enough?

It works, but Docker lists docker.io, docker-compose, docker-doc and podman-docker as unofficial packages that conflict with Docker Engine. Docker's own docker-ce packages follow Docker's releases and ship the Compose and Buildx plugins that most app guides use.

Which Debian releases does Docker support?

Docker currently publishes packages for Debian 13 (Trixie, stable) and Debian 12 (Bookworm, oldstable) on amd64, arm64, armhf and ppc64le. Older releases no longer receive new Docker versions.

Can I use these steps on a Debian derivative?

Docker documents Debian itself. For a derivative such as Kali Linux, Docker says to replace the codename in the repository line with the matching Debian release, for example trixie. Other derivatives may need their own instructions.

Debian 13 uses nftables. Does Docker still work?

Yes. Debian's iptables command uses the nftables backend (iptables-nft), which Docker supports. Rules you write directly with the nft command are not managed by Docker, so put your own container filtering rules in the DOCKER-USER chain with iptables.

Do I need to reboot after installing Docker?

No. The docker service starts as soon as the package is installed and is enabled at boot. You only need to log out and back in after adding your user to the docker group.

Sources

Générer un mot de passe

Please confirm