#!/usr/bin/env bash

set -euo pipefail

SUDO=()

if [[ $EUID -ne 0 ]]; then
    if command -v sudo >/dev/null 2>&1; then
        SUDO=(sudo)
    else
        echo "Error: this script must be run as root or sudo must be installed." >&2
        exit 1
    fi
fi

# Detect OS.
if [[ ! -r /etc/os-release ]]; then
    echo "Error: /etc/os-release not found." >&2
    exit 1
fi

. /etc/os-release

case "$ID" in
    debian)
        DOCKER_DISTRO="debian"
        DOCKER_CODENAME="$VERSION_CODENAME"
        ;;
    ubuntu)
        DOCKER_DISTRO="ubuntu"
        DOCKER_CODENAME="${UBUNTU_CODENAME:-$VERSION_CODENAME}"
        ;;
    *)
        echo "Error: unsupported distribution: $ID" >&2
        echo "Supported distributions: Debian, Ubuntu" >&2
        exit 1
        ;;
esac

ARCH="$(dpkg --print-architecture)"

echo "Detected OS: $PRETTY_NAME"
echo "Docker repository: $DOCKER_DISTRO/$DOCKER_CODENAME"
echo "Architecture: $ARCH"

# Packages that may conflict with Docker Engine.
CONFLICTING_PACKAGES=(
    docker.io
    docker-compose
    docker-compose-v2
    docker-doc
    docker-buildx
    podman-docker
    containerd
    runc
)

INSTALLED_PACKAGES=()

for package in "${CONFLICTING_PACKAGES[@]}"; do
    if dpkg-query -W -f='${Status}' "$package" 2>/dev/null \
        | grep -q '^install ok installed$'; then
        INSTALLED_PACKAGES+=("$package")
    fi
done

if ((${#INSTALLED_PACKAGES[@]} > 0)); then
    echo "Removing conflicting packages: ${INSTALLED_PACKAGES[*]}"
    "${SUDO[@]}" apt-get remove -y "${INSTALLED_PACKAGES[@]}"
fi

# Install prerequisites.
"${SUDO[@]}" apt-get update
"${SUDO[@]}" apt-get install -y ca-certificates curl

# Add Docker's official GPG key.
"${SUDO[@]}" install -m 0755 -d /etc/apt/keyrings

"${SUDO[@]}" curl -fsSL \
    "https://download.docker.com/linux/${DOCKER_DISTRO}/gpg" \
    -o /etc/apt/keyrings/docker.asc

"${SUDO[@]}" chmod a+r /etc/apt/keyrings/docker.asc

# Add Docker's official repository.
cat <<EOF | "${SUDO[@]}" tee /etc/apt/sources.list.d/docker.sources >/dev/null
Types: deb
URIs: https://download.docker.com/linux/${DOCKER_DISTRO}
Suites: ${DOCKER_CODENAME}
Components: stable
Architectures: ${ARCH}
Signed-By: /etc/apt/keyrings/docker.asc
EOF

# Install Docker.
"${SUDO[@]}" apt-get update

"${SUDO[@]}" apt-get install -y \
    docker-ce \
    docker-ce-cli \
    containerd.io \
    docker-buildx-plugin \
    docker-compose-plugin

# Add current user to docker group when script wasn't run as root.
if [[ $EUID -ne 0 ]]; then
    CURRENT_USER="$(id -un)"

    if ! id -nG "$CURRENT_USER" | grep -qw docker; then
        echo "Adding $CURRENT_USER to the docker group..."
        "${SUDO[@]}" usermod -aG docker "$CURRENT_USER"

        echo
        echo "User $CURRENT_USER was added to the docker group."
        echo "Log out and back in for the group membership to take effect."
    fi
fi

echo
echo "Docker installed successfully:"
docker --version
docker compose version

Revision history

2 saved

Oct 1, 2026

  1. 18:51
  2. 18:48