
Table of Contents
By Khimananda Oli | Last reviewed: August 2026
Getting a reliable container runtime is the first step for any modern DevOps workflow, but outdated tutorials often lead to broken dependencies or insecure defaults. To correctly install Docker on Ubuntu 24.04 LTS (Noble Numbat), you must use the official Docker CE repository rather than the older docker.io package found in Ubuntu’s default archives. This guide walks you through the verified installation process, post-install security hardening, and validation steps required for production-grade infrastructure.
docker-ce, docker-ce-cli, and containerd.io. Always verify the service status and configure rootless mode for non-root user access in production environments.How do I prepare my system before I install Docker on Ubuntu?
Before running any installation commands, you must clean up conflicting packages. Ubuntu’s default repositories contain an older docker.io package that conflicts with Docker’s official Community Edition (CE). If you have previously installed Docker from the Ubuntu archives or via snap, those versions will prevent the official packages from functioning correctly.
Run the following command to remove all legacy Docker components. This is safe even if you have never installed Docker before; apt will simply report that the packages are not installed.
sudo apt-get remove -y docker docker-engine docker.io containerd runc docker-compose-plugin Next, update your local package index and install the prerequisite dependencies required for adding external HTTPS repositories. These tools allow apt to securely fetch packages and verify signatures.
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg lsb-release A common mistake at this stage is skipping the cleanup and proceeding directly to repository configuration. This leads to version mismatches where docker compose commands fail because the system is mixing the official CLI with the older Ubuntu-managed daemon. Always start with a clean slate. For teams managing multiple servers, consider automating this preparation phase using the patterns described in our guide to automate server setup with Ansible playbooks.
What are the exact commands to install Docker on Ubuntu 24.04?
The most reliable method to install Docker on Ubuntu is via the official Docker CE repository. This ensures you receive the latest stable releases, security patches, and compatibility updates directly from Docker Inc., rather than waiting for Ubuntu maintainers to backport fixes.
Add the official Docker GPG key and repository
Docker now uses a signed-by mechanism for repository verification, which is more secure than the legacy global keyring approach. Create the keyrings directory and download the GPG key:
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc Add the repository to your apt sources. This command dynamically detects your Ubuntu codename (e.g., noble for 24.04) and architecture:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null Install the Docker Engine packages
Update the package index again to include the new Docker repository, then install the three core packages. The docker-compose-plugin is included here as it provides the modern docker compose V2 command:
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin After installation completes, verify the service is active and enabled to start on boot:
sudo systemctl enable --now docker
sudo systemctl status docker You should see active (running) in the output. If the service fails to start, check journalctl -xeu docker.service for errors related to storage drivers or conflicting configurations.
Should I use rootless Docker or add users to the docker group?
This is one of the most important security decisions you make when you install Docker on Ubuntu. By default, the Docker daemon binds to a Unix socket owned by root. Adding a user to the docker group grants them full root-equivalent privileges on the host, because they can mount host filesystems and escape containers trivially.
For development machines and CI runners where convenience outweighs isolation risk, the docker group is acceptable:
sudo usermod -aG docker $USER
newgrp docker However, for production servers, multi-tenant environments, or compliance-scoped systems (SOC 2, ISO 27001), rootless mode is strongly preferred. Rootless Docker runs the daemon and containers entirely under a non-root user namespace, eliminating the privilege escalation vector.
To enable rootless mode after installation:
sudo apt-get install -y uidmap dbus-user-session
dockerd-rootless-setuptool.sh install Rootless mode has trade-offs: no binding to privileged ports (<1024) without additional configuration, no ICMP ping by default, and slightly higher overhead for network namespace setup. Evaluate these against your security requirements. For teams building CI pipelines, understanding these trade-offs is essential when configuring self-hosted CI runners.
| Criteria | Docker Group | Rootless Mode |
|---|---|---|
| Security Isolation | Root-equivalent access | User namespace isolation |
| Privileged Ports | Yes | No (requires net.ipv4.ip_unprivileged_port_start) |
| Setup Complexity | Single command | Additional packages + config |
| Compliance Friendly | No | Yes (SOC 2 / ISO 27001) |
| Best For | Dev laptops, trusted CI | Production, multi-tenant |
How do I optimize Docker daemon settings for production?
The default Docker configuration works for local development but lacks the guardrails needed for production. After you install Docker on Ubuntu, create or edit the daemon configuration file at /etc/docker/daemon.json.
A production-ready configuration should include log rotation, live restore, and explicit storage driver settings:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"live-restore": true,
"default-address-pools": [
{
"base": "172.30.0.0/16",
"size": 24
}
],
"storage-driver": "overlay2"
} - Log rotation prevents container logs from filling your root partition — a frequent cause of outages in Nepal-based hosting environments where disk monitoring may be limited.
- Live restore keeps containers running when the Docker daemon restarts for updates, reducing maintenance window impact.
- Address pools prevent subnet conflicts when running Docker alongside VPNs or other overlay networks.
- Overlay2 is the recommended storage driver for Ubuntu 24.04’s ext4/xfs filesystems; avoid deprecated drivers like aufs or devicemapper.
After editing the configuration, validate the JSON syntax and reload the daemon:
sudo dockerd --validate
sudo systemctl reload docker For teams adopting infrastructure-as-code practices, managing this configuration declaratively is far superior to manual edits. Our guide on infrastructure as code with Terraform covers patterns for provisioning Docker hosts with pre-configured daemon settings.
How do I verify Docker is working correctly after installation?
Verification goes beyond running hello-world. A proper validation confirms networking, volume mounts, DNS resolution, and permission boundaries are all functional.
- Basic connectivity: Run
docker run --rm hello-worldto confirm image pull and execution. - Network stack: Run
docker run --rm alpine wget -qO- http://ifconfig.meto verify outbound NAT and DNS. - Volume mounts: Run
docker run --rm -v /tmp:/host alpine ls /hostto confirm bind mount permissions. - Compose integration: Run
docker compose versionto verify the V2 plugin is installed and functional. - Resource limits: Run
docker run --rm --memory=64m alpine free -mto confirm cgroup memory enforcement works.
If any step fails, isolate the issue systematically. Network failures usually indicate firewall or proxy misconfiguration. Volume mount failures suggest AppArmor or SELinux restrictions. Memory limit failures indicate missing cgroup v2 support in your kernel parameters.
Final Steps After You Install Docker on Ubuntu
A successful installation is just the starting point. Ensure your setup remains maintainable by pinning package versions in automation scripts, enabling automatic security updates via unattended-upgrades, and integrating container scanning into your CI pipeline. Monitor disk usage regularly with docker system df and prune unused resources weekly to prevent storage exhaustion.
If you are setting up Docker as part of a larger infrastructure initiative or need help hardening your container runtime for compliance audits, reach out to discuss your specific requirements. Properly configured Docker foundations save countless hours of debugging downstream.