Guide for Installing Docker on Ubuntu

Written by

January 5, 2026

At Zentara, we understand that true security isn’t just about the policies you write, but the integrity of the infrastructure you run them on, so we’re working hard to eliminate every possible weak link in our software supply chain.

To address this, we treated our infrastructure setup like code, meaning it is documented, versioned, and standardized. We realized that without a written standard, our environment was drifting; engineers were installing different versions depending on which tutorial they found that day.

So, we sat down and documented the exact “happy path” for a Zentara-compliant node. We decided to ignore the default repositories and instead document a method that pulls directly from the source. This ensures that every time we deploy, we are bypassing the version lag and establishing a verifiable chain of trust.

The Prerequisite

Before we pull docker images from the internet, we need to verify the source. We need to set up a cryptographic trust relationship with Docker’s repository.

First, let’s clear out any conflicting dependencies and set up the apt repository for secure transport (HTTPS).

1. Set up the Keyring

We need to add Docker’s official GPG key. This ensures that the packages you download are actually signed by Docker. This is a critical step in supply chain security.

Shell

# Update the apt package index
sudo apt-get update

# Install packages to allow apt to use a repository over HTTPS
sudo apt-get install ca-certificates curl

# Create the directory for keyrings if it doesn't exist
sudo install -m 0755 -d /etc/apt/keyrings

# Download the official Docker GPG key
sudo curl -fsSL [https://download.docker.com/linux/ubuntu/gpg](https://download.docker.com/linux/ubuntu/gpg) -o /etc/apt/keyrings/docker.asc

# Ensure the key is readable by all users
sudo chmod a+r /etc/apt/keyrings/docker.asc

2. Configure the Repository

Now, we add the repository to your Apt sources. This command detect your architecture (e.g., amd64 or arm64) to ensure that you pull the correct binaries for your hardware.

Shell

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

# Update the package index again to recognize the new repo
sudo apt-get update

Installing the Engine Components

We are installing a few distinct components here:

  • docker-ce: The Docker Engine daemon.
  • docker-ce-cli: The cli client that communicate to the daemon.
  • containerd.io: The industry-standard container runtime.
  • Plugins: Buildx for building images and Compose for multi-container orchestration.

Execute the installation:

Shell

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

Verifying the Daemon

Once the installation completes, we need to validate that the Docker daemon (dockerd) is active and can communicate with the Docker Hub registry.

Run this verify command:

Shell

sudo docker run hello-world

What happens under the hood:

  1. Local Lookup: The daemon checks local storage for an image tagged hello-world.
  2. Pull: Failing to find it, it queries the default registry (Docker Hub) and pulls the layers.
  3. Execution: It instantiates a container, executes the binary inside, streams the stdout to your client, and then terminates.

If you see the Hello from Docker! message, your runtime environment is functional.

Post-Installation: Managing Privileges

By default, the Docker daemon binds to a Unix socket owned by the root user. This is why you constantly need sudo.

To make it easier for DevOps workflows, we can create a Unix group called docker and add your user to it.

Security Note: Adding a user to the docker group grants privileges effectively equivalent to root. If a malicious actor compromises this user, they can manipulate the Docker daemon to gain root access to the host file system. Proceed with this understanding of the threat model.

1. Create the Group and Add User

Shell

# Create the docker group (usually created automatically during install)
sudo groupadd docker

# Add your current user to the group
sudo usermod -aG docker $USER

2. Activate Group Changes

Linux group membership isn’t dynamic for active sessions. You must log out and back in, or force a session reload:

Shell

newgrp docker

Now, verify you can control the daemon without privilege escalation:

Shell

docker run hello-world

3. Troubleshooting Permission Denied Errors

If you previously ran Docker with sudo, you might have created configuration files in your home directory owned by root. This causes the client to crash with a permission denied error when reading ~/.docker/config.json.

The Fix: Reclaim ownership of the .docker directory.

Shell

# Recursively change ownership to your user
sudo chown "$USER":"$USER" /home/"$USER"/.docker -R

# Fix read/write/execute permissions
sudo chmod g+rwx "$HOME/.docker" -R

Congratulations, you have successfully installed the container runtime. However, a running container is only the first step.

The default Docker bridge network provides basic isolation, but in a distributed or hybrid environment, managing IP overlap and exposing ports indiscriminately creates a massive attack surface.

At Zentara, we believe that while Docker isolates the application, you still need to isolate the access. In production, consider bypassing the complexities of exposing Docker ports to the public internet. Instead, utilize an overlay network to bind these containers directly to a Zero Trust identity, ensuring that only authorized users or services can reach the container, regardless of the underlying network infrastructure.

Watch our FREE webinar: AI vs. Hackers - The Cyber Battle You Didn’t Know Was Happening

Marsha Widagdo, Zentara’s Head of Security Operations (Blue Team), will break down how defenders use AI to spot, triage, and contain real threats—and how attackers are weaponising it in return. Expect practical playbooks, recent cases, and clear steps you can apply.

Modern Cybersecurity Services, Built for Complexity

From threat intelligence to vulnerability assessments and incident response, Zentara helps governments and enterprises stay ahead of every attack vector