Debian 12 terminal with Docker Engine installed and running, showing docker version output

How to Install Docker on Debian 12 (Bookworm)

Debian 13 or Debian 12? Debian 13 (Trixie) has been the stable release since August 2025, and Debian 12 (Bookworm) is now oldstable: its regular security support ended on 12 July 2026, and it is covered by Debian LTS until 30 June 2028. For a new Docker host, install Debian 13. Every command in this guide works unchanged on both, because the repository line picks up your release codename (trixie or bookworm) automatically, and Docker’s repository supports both.

Why Debian 12 for Docker

Debian is what Ubuntu is built on, but without the extras. No snap packages, no Ubuntu Pro nag screens, no Canonical telemetry, and no systemd-resolved stub resolver enabled by default. It’s a leaner, more predictable base for a Docker host, and there’s a reason it’s the default choice for most serious self-hosting deployments.

From the homelab: Debian is my go-to server OS for anything that needs to be rock-solid. Most of my Proxmox LXC containers run Debian, and Docker on Debian just works once it is set up correctly.

I run Debian 12 on most of my Proxmox VMs that serve as Docker hosts. Proxmox itself is Debian-based (Proxmox VE 9 is built on Debian 13, Proxmox VE 8 on Debian 12), so if you’re running Proxmox and creating VMs or LXC containers for Docker workloads, matching the Debian release keeps your entire stack on the same foundation. No surprises when you’re troubleshooting at 2am.

This guide covers installing Docker Engine from Docker’s official repository on Debian 12 (Bookworm), the post-install configuration you shouldn’t skip, and the specific differences from our Ubuntu 24.04 Docker guide. If you’re coming from Ubuntu, I’ll call out where things differ so you’re not caught off guard.

Why Not Ubuntu?

Ubuntu is perfectly fine for Docker. I have an entire guide on it. But Debian has specific advantages for a dedicated Docker host:

  • No snap. Ubuntu’s push towards snap packages adds complexity and resource overhead. Docker via snap is particularly problematic, with sandboxing that breaks volume mounts and networking. Debian doesn’t have snap at all.
  • Lighter footprint. A minimal Debian 12 server install uses less RAM and disk than Ubuntu Server. On a VM where you’re allocating resources deliberately, that matters.
  • No systemd-resolved stub. Debian doesn’t enable the DNS stub resolver on 127.0.0.53 by default, so /etc/resolv.conf lists your real DNS servers. (On Ubuntu this matters less than often claimed: Docker detects the stub and gives containers the upstream servers instead.)
  • Longer track record for stability. Debian’s release cycle is slower and more conservative. Packages are older but thoroughly tested. For a Docker host where you want the platform to be boring and reliable, this is a feature.
  • Proxmox alignment. If your hypervisor is Proxmox, your VMs being Debian means one set of knowledge, one set of package management patterns, one set of troubleshooting skills.

The trade-off is that Debian’s base packages are older than Ubuntu’s. The kernel, systemd, and other system components will be behind Ubuntu LTS. For a Docker host this rarely matters because your workloads run inside containers with their own dependencies. The host OS just needs to run Docker reliably, and Debian excels at that.

Prerequisites

  • A machine running Debian 12 (Bookworm), either bare metal, VM, or LXC container
  • Root access or a user with sudo privileges
  • A working internet connection
  • At least 2 GB RAM and 20 GB disk space

If you’re running Docker inside a Proxmox LXC container rather than a VM, you need to enable specific container features. In the Proxmox web UI, go to the container’s Options > Features and enable keyctl and nesting. Without these, Docker won’t be able to manage its own containers inside the LXC. Some people also need to enable fuse depending on their storage driver. VMs don’t have this issue.

Step 1: Remove Debian’s Default Docker Packages

Debian 12 ships docker.io in its default repositories. This is an older, Debian-maintained build of Docker that lags behind the official releases. Remove it, even if you don’t think it’s installed:

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

This is the command from Docker’s install docs: dpkg --get-selections only passes on packages that are actually installed. (Naming packages directly with apt remove fails outright if any one of them does not exist, so it would remove nothing.)

Unlike Ubuntu, you don’t need to worry about removing snap packages here. Debian doesn’t ship snap.

Step 2: Install Prerequisites

sudo apt update
sudo apt install -y ca-certificates curl gnupg

These may already be installed on a Debian 12 system, but it’s worth running to be sure. The gnupg package is needed for verifying Docker’s repository signing key.

Step 3: Add Docker’s Official Repository

This is where the process diverges from Ubuntu. The repository URL uses debian instead of ubuntu, and the codename will be trixie on Debian 13 or bookworm on Debian 12.

Add Docker’s GPG key

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

Add the repository

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
  $(. /etc/os-release && echo "${VERSION_CODENAME}") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Update the package index:

sudo apt update

You should see download.docker.com appear in the apt output. If the codename detection doesn’t work (rare, but possible on minimal installs), you can hardcode trixie (or bookworm) in place of the $(. /etc/os-release && echo "${VERSION_CODENAME}") substitution.

Step 4: Install Docker Engine

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

This installs the same set of packages as on Ubuntu:

  • docker-ce – Docker Engine daemon
  • docker-ce-cli – The docker command-line tool
  • containerd.io – The container runtime
  • docker-buildx-plugin – Extended build capabilities
  • docker-compose-plugin – Docker Compose v2 as docker compose

Step 5: Verify the Installation

sudo systemctl status docker

Look for Active: active (running). Then test with hello-world:

sudo docker run hello-world

If you see the “Hello from Docker!” message, the installation is complete. Check your versions:

docker version
docker compose version

Post-Install Configuration

These steps apply regardless of which Linux distro you’re running Docker on, but I’ll note where Debian behaves differently from Ubuntu.

Add your user to the docker group

sudo usermod -aG docker $USER

Log out and back in, then test without sudo:

docker run hello-world

On a fresh Debian 12 install, your user might not have sudo access by default. If sudo isn’t found or your user isn’t in the sudoers file, log in as root and run: apt install sudo && usermod -aG sudo yourusername. Then log back in as your user. This is a Debian-specific gotcha that Ubuntu users won’t expect, since Ubuntu configures sudo during installation.

Enable Docker on boot

sudo systemctl enable docker.service
sudo systemctl enable containerd.service

Configure log rotation

This is critical on any Docker host. Without it, container logs grow without limit and will eventually fill your disk. I’ve seen it happen on production servers, and it’s always at the worst possible time.

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json > /dev/null <<'EOF'
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  },
  "storage-driver": "overlay2"
}
EOF

sudo systemctl restart docker

This caps each container’s log at 10 MB with 3 rotated files. Adjust to suit your disk space.

Configure DNS (usually not needed on Debian)

On Debian there is usually nothing to do here. (Ubuntu runs the systemd-resolved stub on 127.0.0.53, but Docker detects it and hands containers the real upstream servers, so explicit DNS servers in daemon.json are only needed there when those upstreams are unreachable from the container network.)

Debian doesn’t enable the stub resolver by default. Your containers will inherit the host’s DNS settings from /etc/resolv.conf, and those settings will typically point to your network’s actual DNS server, not a loopback address. DNS inside containers just works.

If you do experience DNS issues (unlikely but possible depending on your network configuration), add DNS servers to your daemon.json:

{
  "dns": ["1.1.1.1", "8.8.8.8"]
}

If you run your own DNS server (Pi-hole, AdGuard Home), point Docker at that instead of public resolvers. That way your containers benefit from the same ad blocking and local DNS resolution as the rest of your network.

Differences from the Ubuntu Guide

If you’ve already followed the Ubuntu 24.04 guide and are now setting up a Debian host, here’s a quick reference of what’s different:

Aspect Ubuntu 24.04 Debian 12 / 13
Snap removal May need sudo snap remove docker Not applicable, no snap
Repository URL download.docker.com/linux/ubuntu download.docker.com/linux/debian
Codename noble bookworm / trixie
DNS in containers Stub resolver on 127.0.0.53; Docker works around it No stub by default
sudo access Configured during install May need manual setup

For Proxmox Users

If you’re running Proxmox and creating Docker hosts, Debian is the natural choice since Proxmox itself is Debian-based (Debian 13 for Proxmox VE 9). Here are some specific considerations:

VM vs LXC for Docker

Both work, but VMs are simpler. Docker in an LXC container requires the keyctl and nesting features enabled, and some storage backends can be problematic. If you’re not constrained on resources, a VM avoids these issues entirely.

For an LXC container, use a privileged container or ensure the unprivileged container has the right feature flags. In the Proxmox UI: Container > Options > Features > check keyctl, nesting, and optionally fuse.

Recommended VM sizing for Docker

  • Light use (1-5 containers): 2 CPU cores, 2 GB RAM, 32 GB disk
  • Medium use (5-15 containers): 4 CPU cores, 4 GB RAM, 64 GB disk
  • Heavy use (15+ containers): 4-8 CPU cores, 8 GB RAM, 100+ GB disk

Use virtio for both disk and network interfaces in Proxmox. The performance difference over IDE or E1000 emulation is significant, particularly for the I/O patterns Docker generates.

Create a Debian 12 VM template in Proxmox with Docker pre-installed. Then you can clone new Docker hosts in seconds. I have a template called “debian12-docker” that I clone whenever I need a new host. It has Docker installed, log rotation configured, and my SSH key already deployed. A new Docker host goes from zero to running containers in under two minutes.

Firewall Configuration

Debian 12 doesn’t ship with a firewall enabled by default, which means all your container ports are exposed to your network. If this Docker host is accessible from the internet, or even from an untrusted network segment, configure a firewall.

sudo apt install -y ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw enable

Docker modifies iptables directly and bypasses UFW rules by default. This means a container publishing port 8080 will be reachable even if UFW doesn’t allow port 8080. This is a well-documented issue. The simplest mitigation is to bind container ports to 127.0.0.1 (e.g., -p 127.0.0.1:8080:80) and use a reverse proxy like Nginx to control external access. Alternatively, set "iptables": false in daemon.json, but be aware this breaks container-to-internet networking unless you add your own iptables rules.

Unattended Security Updates

For a server that runs continuously, enable automatic security updates so you’re not manually patching every Debian host in your fleet:

sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades

This configures Debian to automatically install security patches. It won’t upgrade Docker itself (that comes from Docker’s repo, not Debian’s), but it keeps the base OS patched without intervention.

Debian is one of the most widely used server distributions, the base Ubuntu is built on, and the base of many official container images. If you’re building infrastructure skills for your career, being comfortable with Debian gives you a broader base than knowing only Ubuntu. The differences are subtle but they come up in interviews: “Why would you choose Debian over Ubuntu for a server?” is a question I’ve been asked twice. Having an answer that references resource overhead, packaging choices, and release stability demonstrates real operational experience.

Practitioner tip: If you are running inside a Proxmox LXC container, enable nesting in the container options first. Without it, Docker will not start and the error messages will not tell you why.

Key Takeaways

  • Debian is a lighter, more predictable Docker host than Ubuntu, with no snap and no DNS stub resolver by default. Use Debian 13 for new hosts; Debian 12 is oldstable and on LTS until June 2028
  • The installation process is nearly identical to Ubuntu, with debian replacing ubuntu in the repository URL and trixie or bookworm as the codename
  • Always install from Docker’s official repository, never from Debian’s default docker.io package
  • DNS inside containers normally works out of the box on Debian; add servers to daemon.json only if your network needs it
  • Proxmox users should prefer Debian for Docker VMs to keep the entire stack on the same distribution (Debian 13 alongside Proxmox VE 9)
  • For Docker in Proxmox LXC containers, enable keyctl and nesting features
  • Configure log rotation immediately and be aware that Docker bypasses UFW firewall rules by default
  • Create a Proxmox VM template with Docker pre-installed to spin up new hosts in minutes

Related Guides

If you found this useful, these guides continue the journey:

The RTM Essential Stack - Gear I Actually Use

Enjoyed this guide?

New articles on Linux, homelab, cloud, and automation every 2 days. No spam, unsubscribe anytime.

Scroll to Top