Docker runs applications in containers, and Docker Compose describes a multi-container app in one file. Install them from Docker's official repository to get current versions; the distribution packages are often older.
1. Install on Ubuntu or Debian
sudo apt update
sudo apt install -y 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
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
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginDebian 12: use the same commands but replace both linux/ubuntu URLs with linux/debian.
On AlmaLinux or Rocky Linux instead
sudo dnf install -y dnf-plugins-core
sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker2. Check it works
sudo docker run --rm hello-world
docker compose version3. Run Docker without sudo (optional)
sudo usermod -aG docker $USERLog out and back in for it to apply.
Warning: Membership of the docker group is equivalent to root access on the server. Only add users you would trust with root.
4. Your first Compose project
Create a folder with a compose.yaml file:
services:
web:
image: nginx:stable
restart: unless-stopped
ports:
- "127.0.0.1:8080:80"
volumes:
- ./site:/usr/share/nginx/html:roStart, inspect and stop it:
docker compose up -d
docker compose ps
docker compose logs -f web
docker compose downKeep ports private
Docker writes its own firewall rules, so a port published as "8080:80" is reachable from the internet even if UFW or firewalld does not allow it. Publish to 127.0.0.1 as in the example above, and expose the app through Nginx with HTTPS. See Install Nginx and Let's Encrypt for Nginx.
Stop logs from filling the disk
By default container logs grow without limit. Create /etc/docker/daemon.json:
{
"log-driver": "json-file",
"log-opts": { "max-size": "10m", "max-file": "3" }
}Then sudo systemctl restart docker. The limit applies to containers created after the change, so recreate them with docker compose up -d --force-recreate.
Troubleshooting
- permission denied while trying to connect to the Docker daemon socket: use
sudo, or log out and back in after adding yourself to thedockergroup. - Port already allocated: another container or service uses it. Find it with
sudo ss -tlnp | grep 8080. - Disk filling up:
docker system dfshows usage;docker system pruneremoves stopped containers, unused networks and dangling images. Add-aonly if you are sure unused images can go.
Next steps
- Free up disk space on Linux
- Back up your Linux VPS (include your volumes)
