Docker setup on Ubuntu: add Docker’s official apt repo (gets latest), install docker-ce, run post-install steps so non-root users can run docker. The team that uses the official repo (not Ubuntu’s older docker.io) has the latest features. The team that skips post-install has to sudo docker for every command.
Table of contents
- Add Docker’s apt repo
- Install Docker Engine
- Verify install
- Post-install: non-root user
- systemd service
- docker-compose-plugin (v2)
- Configure daemon (/etc/docker/daemon.json)
- Common pitfalls
- FAQ
Add Docker’s apt repo
# 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 repo
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
sudo apt update
The team that uses Docker’s repo has the latest version. The team that uses apt install docker.io (Ubuntu’s package) has older versions.
Install Docker Engine
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
The team that installs all four has docker, CLI, containerd, BuildKit (buildx), and Compose v2.
Verify install
sudo docker run hello-world
The team that sees ‘Hello from Docker!’ has working install.
Post-install: non-root user
sudo usermod -aG docker $USER
# Log out and back in for group to take effect
newgrp docker
docker run hello-world # no sudo needed
The team that adds the user to the docker group has rootless-ish docker (still root in containers, but no sudo for docker CLI). The team that uses sudo docker for every command is the wrong default.
systemd service
sudo systemctl enable docker
sudo systemctl status docker
The team that enables the service has docker start at boot. The team that doesn’t have to manually start it.
docker-compose-plugin (v2)
The new docker compose command (v2) is the plugin:
docker compose version
# Docker Compose version v2.x.x
The team that uses docker compose (v2) instead of docker-compose (v1) has the modern CLI.
Configure daemon (/etc/docker/daemon.json)
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"storage-driver": "overlay2",
"default-address-pools": [
{"base": "172.80.0.0/16", "size": 24}
]
}
The team that sets log rotation prevents disk fills from runaway logs.
Common pitfalls
- Using
apt install docker.ioinstead of Docker’s repo - older version. - Skipping post-install - need
sudofor every command. - Running docker as root in production - security risk.
- No log rotation - disk fills with container logs.
- Docker socket exposed (Docker-in-Docker setups) - security issue.
FAQ
What’s the difference between docker-ce and docker.io?
docker-ce: Docker’s official package, latest version. docker.io: Ubuntu’s package, older version. The team that uses docker-ce has current features.
Do I need to add my user to the docker group?
Yes for non-root usage. The team that uses sudo docker for every command has friction; adding to docker group removes the friction.
How do I run Docker as a non-root user without docker group?
Rootless mode: dockerd-rootless.sh. More secure but some features don’t work (cgroups v2 needed, port binding needs setcap).
Where are Docker’s config files?
Daemon: /etc/docker/daemon.json. Containerd: /etc/containerd/config.toml. The team that edits these has full docker control.
How do I uninstall Docker?
sudo apt purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin. Then sudo rm -rf /var/lib/docker /var/lib/containerd to remove data.
If you are sizing the infrastructure for the kind of project this post covers, the RunxBuild hosting calculator is the right place to model the line items. The compute, the memory, the storage, the bandwidth, the database - each one is a separate number, and the team’s mental model for the platform is the sum of those numbers. The RunxBuild dashboard is where the team sees the actual usage in one place.
Useful related references: