Docker Rootless on Ubuntu (2026 Guide)
Why This Matters
When I first started with Docker, I ran everything as root. It was easy, it worked, and I didn't think twice about it. Then I learned that a container escape vulnerability could give an attacker full root access to my entire system. That's when I switched to rootless Docker — and you should too.
Rootless Docker runs the Docker daemon entirely under your regular user account. No sudo required. No root privileges for container operations. If a container gets compromised, the attacker is stuck with your user's permissions — not root.
You asked, I delivered: This guide was the #1 request in my LinkedIn poll (Ubuntu/Linux Mint won with 50% of votes).
Planning Disk Space
In rootless mode, Docker stores all images, containers, volumes, and build cache under your home directory at ~/.local/share/docker. This means your home directory needs enough space to hold everything you work with.
For following along with this guide, plan for at least 20 GB of free space in your home directory. If you are setting up a dedicated Docker host, consider giving the home partition 50 GB or more to accommodate larger images and persistent data volumes.
You can check your available space with:
df -h ~
Prerequisites
- Operating System: Ubuntu 22.04 or higher (also works on Linux Mint, Pop!_OS)
- Disk Space: At least 20 GB free in your home directory
- Time: 15-20 minutes
- Access: Sudo privileges for initial installation only
Step 1: Remove Old Docker Packages
Remove any old or conflicting Docker packages that may have been installed from the distribution repositories:
sudo apt remove docker.io docker-compose docker-compose-v2 \
docker-doc podman-docker containerd runc
This ensures a clean starting point before installing Docker from the official repository.
Step 2: Set Up Docker's APT Repository
Install prerequisites and add Docker's official GPG key:
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/ubuntu/gpg \
-o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
Add the Docker repository to your APT sources:
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Signed-By: /etc/apt/keyrings/docker.asc
EOF
sudo apt update
Step 3: Install Docker Packages
sudo apt install docker-ce docker-ce-cli containerd.io \
docker-buildx-plugin docker-compose-plugin
Step 5: Install Rootless Prerequisites
Rootless Docker requires uidmap (for user namespace mapping) and dbus-user-session (for systemd user services):
sudo apt install uidmap dbus-user-session
Step 6: Set Up Rootless Docker
From this point on, no sudo is required.
First, make sure the system-wide Docker daemon is not running. Rootless Docker runs its own daemon under your user account:
sudo systemctl disable --now docker.service docker.socket
Now run the rootless setup script as your regular user:
dockerd-rootless-setuptool.sh install
You should see output ending with:
[INFO] Installed docker.service successfully. [INFO] To control docker.service, run: `systemctl --user (start|stop|restart) docker.service` [INFO] To run docker.service on system startup, run: `sudo loginctl enable-linger [username]`
Enable your user's Docker service to start automatically on boot:
systemctl --user enable --now docker
Enable lingering so your user services start at boot even without a login session:
sudo loginctl enable-linger [username]
Replace [username] with your actual username.
Verification
Here's how to confirm everything worked:
1. Test with the hello-world image:
docker run hello-world
This command downloads a small test image from Docker Hub and runs it. You should see a message starting with:
Hello from Docker! This message shows that your installation appears to be working correctly.
2. Confirm rootless mode:
docker info | grep -i context
You should see:
Context: rootless
3. Test with a real container (jq demo):
Instead of the usual hello-world, let's verify with something useful. We'll create a sample JSON file and use Docker to parse it with jq — without installing anything locally:
First, create the sample JSON file:
echo '{"name":"David","company":"Transcend Solutions","role":"DevOps Engineer","skills":["Docker","Kubernetes","Linux"],"location":"Singapore","experience_years":15}' > sample.json
Now parse it with Docker and jq:
cat sample.json | docker run --rm -i ghcr.io/jqlang/jq '.'
First time, you'll see:
Unable to find image 'ghcr.io/jqlang/jq:latest' locally Downloaded newer image for ghcr.io/jqlang/jq:latest
Then the output — beautifully formatted JSON:
{
"name": "David",
"company": "Transcend Solutions",
"role": "DevOps Engineer",
"skills": [
"Docker",
"Kubernetes",
"Linux"
],
"location": "Singapore",
"experience_years": 15
}
No installation. No sudo. Same command on any system with Docker.
4. List running containers:
docker ps -a
This shows all containers, including stopped ones (with status Exited):
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a1b2c3d4e5f6 hello-world "/hello" 5 minutes ago Exited (0) 5 minutes ago peaceful_hofstadter
Rootless Limitations
Running Docker in rootless mode has a few limitations to be aware of:
- No ports below 1024 — rootless containers cannot bind to privileged ports (like 80 or 443) directly. We address this in Chapter 7 using a rootful nginx proxy container.
- Storage in home directory — all images and data live under
~/.local/share/docker, so ensure your home directory has adequate space. - No
pingfrom containers — ICMP packets require root privileges. Usecurlorwgetto test connectivity instead.
These are minor tradeoffs for the significant security benefit of never running the Docker daemon as root.
Exercise
- Run
docker infoand identify how many containers are running, paused, and stopped on your system. Confirm the output showsContext: rootless. - Run the hello-world test image again and verify it appears in the stopped containers list:
docker run hello-world docker ps -a
You should see the hello-world container with status "Exited". - Check how much disk space Docker is using in your home directory with
du -sh ~/.local/share/docker.
What's Next
Now that you have a secure rootless Docker environment on Ubuntu, you're ready to:
- Pull and run your first containers
- Learn about Docker volumes for persistent data
- Set up multi-container applications with Docker Compose
Want more? This guide is adapted from Chapter 1: Preparing Docker Host in my book "Levelling Up with Docker" — 14 chapters covering volumes, networking, Compose, production deployments, and more.
Found this helpful? Share it with someone learning Docker!
📚 Want to Go Deeper?
Levelling Up with Docker by David Tio
14 chapters of practical Docker guides
Published: 4 March 2026
Author: David Tio
Source: Chapter 1: Preparing Docker Host
Tags: Docker, Ubuntu, Linux, Rootless, DevOps, Tutorial
Poll Winner: Ubuntu / Linux Mint(57% of LinkedIn poll votes)
Comments
Post a Comment