Over 10 years we help companies reach their financial and branding goals. Engitech is a values-driven technology agency dedicated.

Gallery

Contacts

411 University St, Seattle, USA

+1 -800-456-478-23

How to install Docker in Linux

This guide installs Docker Engine, Docker CLI, containerd, Docker Buildx, and Docker Compose on Debian 13 (Trixie) using Docker's official APT repository.

Docker officially supports Debian 13 Trixie.


1. Update the System

sudo apt update
sudo apt upgrade -y

Optionally install common prerequisites:

sudo apt install -y \
    ca-certificates \
    curl

2. Remove Conflicting Packages

If Docker, Podman compatibility packages, containerd, or runc were previously installed from Debian repositories, remove them first.

Docker recommends removing conflicting packages including:

  • docker.io
  • docker-compose
  • docker-doc
  • docker-buildx
  • podman-docker
  • containerd
  • runc

Run:

sudo apt remove -y \
    docker.io \
    docker-compose \
    docker-doc \
    docker-buildx \
    podman-docker \
    containerd \
    runc

It is safe if APT reports that some of these packages are not installed.

Existing Docker data under /var/lib/docker is not automatically deleted when Docker packages are removed.


Install Docker from Official Repository

3. Install Docker Engine

Run the official Docker installation script:

curl -fsSL https://get.docker.com | sudo sh

This installs Docker Engine and configures Docker's package repository automatically.


4. Verify Docker Service

Check Docker:

sudo systemctl status docker

You should see:

Active: active (running)

If it is not running:

sudo systemctl start docker

Enable Docker during boot:

sudo systemctl enable docker

Enable containerd as well:

sudo systemctl enable containerd

5. Verify Docker Installation

Check the Docker version:

docker --version

More detailed information:

sudo docker version

Check daemon information:

sudo docker info

6. Run Test Container

Run Docker's hello-world container:

sudo docker run --rm hello-world

Docker should:

  1. Contact Docker Hub.
  2. Download the hello-world image.
  3. Create a container.
  4. Execute it.
  5. Print a successful installation message.

Check existing containers:

sudo docker ps -a

Check downloaded images:

sudo docker images

Docker Compose

Docker Compose is installed as the official Docker CLI plugin when you install:

docker-compose-plugin

Docker's supported command is therefore:

docker compose

rather than the older standalone:

docker-compose

Docker documents installing the Compose plugin through the package repository.

Verify:

docker compose version

Allow Current User to Run Docker

By default, Docker commands normally require sudo.

For example:

sudo docker ps

To allow your current user to run Docker without sudo, add the user to the docker group.

Create the group if necessary:

sudo groupadd docker 2>/dev/null || true

Add the current user:

sudo usermod -aG docker $USER

Apply the new group immediately:

newgrp docker

Or log out and log back in.

Test:

docker ps

Then:

docker run --rm hello-world

Security: Membership in the docker group effectively provides root-equivalent privileges on a normal Docker Engine installation. Only trusted users should be added to this group.


Docker Service Management

Start Docker

sudo systemctl start docker

Stop Docker

sudo systemctl stop docker

Restart Docker

sudo systemctl restart docker

Check Status

sudo systemctl status docker

Enable at Boot

sudo systemctl enable docker

Disable at Boot

sudo systemctl disable docker

Docker Data Directory

Docker normally stores its runtime data under:

/var/lib/docker

containerd normally stores its data under:

/var/lib/containerd

Check Docker disk usage:

sudo du -sh /var/lib/docker

Or use Docker's built-in disk usage command:

docker system df

Example:

TYPE            TOTAL     ACTIVE    SIZE
Images          10        4         4.2GB
Containers      8         3         1.1GB
Local Volumes   5         5         10GB
Build Cache     12        0         2GB

Docker Daemon Configuration

Docker daemon configuration is normally stored at:

/etc/docker/daemon.json

The file may not exist by default.

Create the directory:

sudo mkdir -p /etc/docker

Create/edit the configuration:

sudo nano /etc/docker/daemon.json

Example:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "50m",
    "max-file": "5"
  }
}

Restart Docker:

sudo systemctl restart docker

Verify:

docker info

Configure Docker Log Rotation

Without limits, container JSON log files can become very large.

A basic server configuration:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "50m",
    "max-file": "5"
  }
}

Save as:

/etc/docker/daemon.json

Restart:

sudo systemctl restart docker

This limits each container's Docker-managed log files to approximately:

50 MB × 5 files

before old files are rotated.

Existing containers may need to be recreated before new logging settings apply to them.


Example Docker Compose Application

Create a directory:

mkdir -p ~/docker/demo
cd ~/docker/demo

Create:

nano compose.yml

Example:

services:
  nginx:
    image: nginx:alpine
    container_name: demo-nginx

    ports:
      - "8080:80"

    restart: unless-stopped

Start:

docker compose up -d

Check:

docker compose ps

View logs:

docker compose logs

Follow logs:

docker compose logs -f

Stop:

docker compose down

Recommended Compose Directory Layout

For server deployments, a useful layout is:

/opt/docker/
├── redis/
│   ├── compose.yml
│   ├── .env
│   └── data/
│
├── nginx/
│   ├── compose.yml
│   └── config/
│
├── application-1/
│   ├── compose.yml
│   ├── .env
│   └── data/
│
└── application-2/
    ├── compose.yml
    ├── .env
    └── data/

Create the root directory:

sudo mkdir -p /opt/docker

Set ownership if the current administrator should manage it:

sudo chown -R $USER:$USER /opt/docker

Common Docker Commands

List Running Containers

docker ps

List All Containers

docker ps -a

List Images

docker images

Pull an Image

docker pull redis:latest

Start Container

docker start <container>

Stop Container

docker stop <container>

Restart Container

docker restart <container>

Remove Container

docker rm <container>

Remove Image

docker rmi <image>

Container Logs

Show logs:

docker logs <container>

Follow logs:

docker logs -f <container>

Last 100 lines:

docker logs --tail 100 <container>

Follow starting from the last 100 lines:

docker logs \
    --tail 100 \
    -f \
    <container>

Enter a Container

For containers with Bash:

docker exec -it <container> bash

For Alpine/minimal containers:

docker exec -it <container> sh

Example:

docker exec -it demo-nginx sh

Inspect Container

docker inspect <container>

Example:

docker inspect demo-nginx

Get only the IP address:

docker inspect \
    -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' \
    demo-nginx

Docker Networks

List networks:

docker network ls

Create network:

docker network create backend

Inspect:

docker network inspect backend

Remove:

docker network rm backend

Docker Volumes

List volumes:

docker volume ls

Create:

docker volume create application-data

Inspect:

docker volume inspect application-data

Remove:

docker volume rm application-data

Disk Cleanup

Check Docker disk usage:

docker system df

Remove unused containers:

docker container prune

Remove unused images:

docker image prune

Remove unused networks:

docker network prune

Remove unused build cache:

docker builder prune

Clean unused Docker resources:

docker system prune

More aggressive cleanup:

docker system prune -a

Be careful with pruning commands. They can remove images and resources that are not currently attached to running containers.

Avoid running:

docker system prune -a --volumes

without verifying that unused volumes contain no important persistent data.


Docker Logs

Check Docker daemon logs:

sudo journalctl -u docker

Follow:

sudo journalctl -u docker -f

Show logs since boot:

sudo journalctl -u docker -b

containerd logs:

sudo journalctl -u containerd

Check Docker Networking

Docker bridge:

ip addr show docker0

Networks:

docker network ls

Default bridge details:

docker network inspect bridge

Firewall Considerations

Docker configures firewall rules for container networking and published ports.

For example:

ports:
  - "8080:80"

can make TCP port 8080 reachable through the host depending on host networking and firewall configuration.

Docker specifically warns that published container ports can interact with or bypass some firewall rules depending on how the host firewall is configured. Review Docker's firewall guidance when operating Internet-facing hosts.

Do not assume that:

ufw deny 8080

by itself always provides the intended Docker networking policy.

For production servers, verify the effective firewall rules and limit public port publishing.


Bind Only to a Specific Host Address

Instead of:

ports:
  - "6379:6379"

you can bind a service to a private IP:

ports:
  - "10.10.10.20:6379:6379"

Or localhost only:

ports:
  - "127.0.0.1:6379:6379"

This is useful for databases, Redis, internal APIs, and administrative interfaces.


Recommended Restart Policies

For production containers, commonly use:

restart: unless-stopped

Example:

services:
  app:
    image: example/app:latest
    restart: unless-stopped

Other policies include:

no
always
on-failure
unless-stopped

Upgrade Docker

Update package lists:

sudo apt update

See available upgrades:

apt list --upgradable

Upgrade Docker packages:

sudo apt install \
    docker-ce \
    docker-ce-cli \
    containerd.io \
    docker-buildx-plugin \
    docker-compose-plugin

Docker's APT repository is then used for normal future package updates.

Verify:

docker version
docker compose version

Check Installed Docker Packages

dpkg -l | grep -E 'docker|containerd'

Typical packages:

docker-ce
docker-ce-cli
docker-buildx-plugin
docker-compose-plugin
containerd.io

Docker Version Information

docker version

Example structure:

Client:
 Version: ...

Server:
 Engine:
  Version: ...

Compose:

docker compose version

Buildx:

docker buildx version

containerd:

containerd --version

Docker Health Check

Basic daemon test:

docker info >/dev/null && echo "Docker OK"

Container execution test:

docker run --rm hello-world

Check service:

systemctl is-active docker

Expected:

active

Check boot configuration:

systemctl is-enabled docker

Expected:

enabled

Recommended Server Configuration

A basic Debian 13 Docker host should have:

Docker Engine
Docker CLI
containerd
Docker Compose Plugin
Docker Buildx

Verify:

docker --version
docker compose version
docker buildx version

Recommended daemon configuration:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "50m",
    "max-file": "5"
  }
}

Location:

/etc/docker/daemon.json

Then:

sudo systemctl restart docker

Quick Installation

For a fresh Debian 13 server:

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/debian/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/debian \
  $(. /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-plugin

sudo systemctl enable --now docker

sudo docker run --rm hello-world

Allow the current user to use Docker:

sudo usermod -aG docker $USER

Then log out and log back in, or run:

newgrp docker

Verify:

docker version
docker compose version
docker ps

Uninstall Docker

Remove Docker Engine packages:

sudo apt purge -y \
    docker-ce \
    docker-ce-cli \
    containerd.io \
    docker-buildx-plugin \
    docker-compose-plugin \
    docker-ce-rootless-extras

Remove unused dependencies:

sudo apt autoremove -y

Docker does not automatically delete stored images, containers, volumes, and networks when packages are uninstalled.

To completely remove Docker data:

sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd

Remove repository configuration:

sudo rm -f /etc/apt/sources.list.d/docker.list
sudo rm -f /etc/apt/keyrings/docker.asc

Then:

sudo apt update

Warning: Removing /var/lib/docker and /var/lib/containerd permanently deletes local Docker container data.


References

  • Docker officially supports Debian 13 Trixie and documents installation through Docker's APT repository.
  • The official installation includes docker-ce, docker-ce-cli, containerd.io, docker-buildx-plugin, and docker-compose-plugin.
  • Docker Compose on Debian is available through the official docker-compose-plugin package and is invoked using docker compose.

Leave a comment

Your email address will not be published. Required fields are marked *