Install and Configure Docker on Ubuntu
Docker is a powerful platform that allows developers and system administrators to build, ship, and run distributed applications inside lightweight containers. Containers are isolated environments that bundle the application and its dependencies, ensuring consistency across different systems. This blog post provides a step-by-step guide to installing and configuring Docker on Ubuntu, covering everything from adding the official Docker repository to setting up user permissions and employing Docker Compose for multi-container orchestration.
Why Use Docker?
- Portability: Containers encapsulate all dependencies, providing a consistent environment across development, testing, and production.
- Efficiency: Containers share the host OS kernel, reducing overhead compared to virtual machines.
- Scalability: Docker makes it easy to scale applications horizontally by running multiple container instances.
- Modularity: You can break complex applications into discrete services, managed independently.
Prerequisites
- A server or virtual machine running Ubuntu 20.04 LTS or later.
- A user account with sudo privileges.
- Internet access to download Docker packages and dependencies.
Note: Commands in this guide assume you are working in a Bash shell.
Uninstall Old Docker Versions (Optional) {#uninstall-old-docker-versions-optional}
If you have previously installed Docker components named docker, docker-engine, or docker.io, it’s recommended to remove them to avoid conflicts:
sudo apt-get remove docker docker-engine docker.io containerd runc
This command uninstalls old versions without removing images, containers, or volumes.
Set Up the Docker Repository
Docker’s official APT repository includes the latest stable Docker packages. Before adding the repository, install packages to allow apt to use repositories over HTTPS.
4.1. Install Required Packages
sudo apt-get update
sudo apt-get install \
ca-certificates \
curl \
gnupg \
lsb-release -y4.2. Add Docker’s Official GPG Key
sudo mkdir -p /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
Verify the fingerprint:
gpg --show-keys --with-fingerprint /etc/apt/keyrings/docker.gpg
Expected fingerprint:
9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
4.3. Add the Docker APT Repository
Use the following command to set up the stable repository:
echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \ https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Install Docker Engine
With the repository set up, update your package index and install Docker Engine, containerd, and the Docker CLI:
sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
This installs the following components:
- docker-ce: Docker Community Edition.
- docker-ce-cli: The command-line interface.
- containerd.io: The container runtime.
- docker-buildx-plugin: Extended build capabilities.
- docker-compose-plugin: Docker Compose v2 plugin.
Verify Docker Installation
To confirm Docker is installed and running:
sudo systemctl status docker
You should see active (running) in the output. Alternatively, run:
docker version
Sample output:
Client: Version: 24.0.2 API version: 1.42 Go version: go1.21.0 Git commit: d8739a96 Built: Wed May 7 08:32:52 2025 OS/Arch: linux/amd64 Context: default Server: Engine: Version: 24.0.2 API version: 1.42 (minimum version 1.12) Go version: go1.21.0 Git commit: 7b11f21 Built: Wed May 7 08:21:45 2025 OS/Arch: linux/amd64 Experimental: false
Post-Installation Steps
7.1. Manage Docker as a Non-Root User
By default, Docker commands must be run with sudo. To avoid this, add your user to the docker group:
sudo usermod -aG docker $USER
Log out and log back in (or execute newgrp docker) for changes to take effect. Test by running:
docker run hello-world
If non-root management is successful, you should see a message: Hello from Docker!.
7.2. Configure the Docker Daemon
You can customize Docker’s daemon configuration by editing /etc/docker/daemon.json. For example:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"storage-driver": "overlay2"
}After saving changes, restart the Docker daemon:
sudo systemctl restart docker
Using Docker Commands
- List images: docker images
- List containers: docker ps -a
- Pull an image: docker pull nginx:latest
- Run a container:
docker run -d --name webserver -p 80:80 nginx:latest
- Stop a container: docker stop webserver
- Remove a container: docker rm webserver
- Remove an image: docker rmi nginx:latest
Installing Docker Compose
Docker Compose v2 is included as the docker compose command. No separate binary is required if you installed the plugin earlier. Verify the installation:
docker compose version
Sample output:
Docker Compose version v2.16.0
Basic Docker Compose Example
Create a file named docker-compose.yml in your project directory:
version: "3.8"
services:
web:
image: nginx:latest
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html:ro
redis:
image: redis:alpineLaunch the services:
docker compose up -d
Verify running containers:
docker compose ps
Stop and remove containers, networks, and volumes:
docker compose down
Service Configuration and Networking
- Custom networks: Define in docker-compose.yml:
networks: front-tier: back-tier: services: web: networks: - front-tier - back-tier db: networks: - back-tier- Environment variables: Use an .env file or environment: block.
- Health checks:
healthcheck: test: ["CMD-SHELL", "curl -f http://localhost/ || exit 1"] interval: 30s timeout: 10s retries: 3
Security Best Practices
- Least privilege: Avoid running containers as root. Use USER in Dockerfile.
- Image provenance: Pull images from verified repositories.
- Regular updates: Keep Docker and images up to date to patch vulnerabilities.
- Enable Docker Content Trust:
export DOCKER_CONTENT_TRUST=1
- Limit container capabilities:
docker run --cap-drop ALL --cap-add NET_BIND_SERVICE ...
- Use resource constraints:
docker run -m 256m --cpus="0.5" ...
Troubleshooting Tips
- Docker daemon not starting:
journalctl -u docker.service --no-pager | tail -n 50
- Permission errors: Ensure your user is in the docker group.
docker network ls
docker network inspect
- **Disk space**: Prune unused objects: ```bash docker system prune -a
Conclusion
Docker streamlines application deployment by encapsulating dependencies in portable containers. This guide walked through installing Docker Engine and Compose on Ubuntu, configuring daemon settings, managing user permissions, and applying security best practices. With these steps, you can confidently build, run, and scale containerized applications on Ubuntu servers.