#!/bin/bash # # Installs Docker Engine on Debian-based Linux distributions. # # Usage: # ./docker.sh # curl -fsSL https://cdn.albert.lol/docker.sh | bash # # Requires: # - Running on a Debian-based system (Debian, Ubuntu, etc.) # - User executing the script must have sudo privileges. # - Internet connection. # Strict mode set -euo pipefail # --- Configuration --- readonly DOCKER_GPG_KEY_PATH="/etc/apt/keyrings/docker.asc" readonly DOCKER_APT_SOURCE_PATH="/etc/apt/sources.list.d/docker.list" # --- Helper Functions --- # Logs an informational message. # Arguments: # $*: Message to log. log_info() { echo "[INFO] $*" } # Logs an error message and exits. # Arguments: # $*: Message to log. log_error() { echo >&2 "[ERROR] $*" exit 1 } # Checks if a command exists. # Arguments: # $1: Command name. command_exists() { command -v "$1" >/dev/null 2>&1 } # --- Main Functions --- # Step 1: Update package lists and install prerequisite packages. install_prerequisites() { log_info "Updating package list and installing prerequisites..." sudo apt-get update sudo apt-get install -y \ ca-certificates \ curl \ gnupg log_info "Prerequisites installed." } # Step 2: Set up Docker's official APT repository. setup_apt_repository() { log_info "Setting up Docker's APT repository..." # Create the directory for the GPG key if it doesn't exist log_info "Creating keyring directory: /etc/apt/keyrings" sudo install -m 0755 -d "$(dirname "${DOCKER_GPG_KEY_PATH}")" # Download Docker's official GPG key log_info "Downloading Docker GPG key to ${DOCKER_GPG_KEY_PATH}" # Use curl with fail-fast, silent, show-error, location-follow flags sudo curl -fsSL "https://download.docker.com/linux/debian/gpg" -o "${DOCKER_GPG_KEY_PATH}" # Ensure the key is readable by apt sudo chmod a+r "${DOCKER_GPG_KEY_PATH}" # Detect architecture and OS codename local arch arch="$(dpkg --print-architecture)" local codename # Source os-release safely if [[ -f /etc/os-release ]]; then # shellcheck source=/dev/null codename="$(. /etc/os-release && echo "$VERSION_CODENAME")" else log_error "Cannot determine OS codename. /etc/os-release not found." fi if [[ -z "$codename" ]]; then log_error "Could not determine VERSION_CODENAME from /etc/os-release." fi # Add the Docker repository to Apt sources log_info "Adding Docker repository source to ${DOCKER_APT_SOURCE_PATH}" echo \ "deb [arch=${arch} signed-by=${DOCKER_GPG_KEY_PATH}] https://download.docker.com/linux/debian \ ${codename} stable" | sudo tee "${DOCKER_APT_SOURCE_PATH}" > /dev/null log_info "Docker APT repository setup complete." } # Step 3: Install Docker Engine packages. install_docker() { log_info "Updating package list after adding Docker repository..." sudo apt-get update log_info "Installing Docker packages..." sudo apt-get install -y \ docker-ce \ docker-ce-cli \ containerd.io \ docker-buildx-plugin \ docker-compose-plugin log_info "Docker packages installed." } # Step 4: Perform post-installation steps (add user to docker group). post_install() { log_info "Adding current user (${USER}) to the 'docker' group..." if getent group docker > /dev/null; then sudo usermod -aG docker "$USER" log_info "User '${USER}' added to the 'docker' group." log_info "IMPORTANT: You need to log out and log back in for the group change to take effect." log_info "Alternatively, you can run 'newgrp docker' in your current shell, but logging out is recommended." else log_info "The 'docker' group does not exist. Skipping user addition." log_info "This might happen if Docker installation failed earlier." fi } # --- Main Execution --- main() { log_info "Starting Docker installation script..." # Basic checks if ! command_exists sudo; then log_error "'sudo' command not found. This script requires sudo privileges." fi if [[ $EUID -eq 0 ]]; then log_info "Script is running as root. Using sudo is recommended for specific commands only." # Consider adapting script if root execution should behave differently, # but for now, relying on internal sudo calls is fine. fi if ! command_exists dpkg; then log_error "'dpkg' command not found. This script is intended for Debian-based systems." fi if ! [[ -f /etc/os-release ]]; then log_error "File /etc/os-release not found. This script is intended for Debian-based systems." fi # Execute steps install_prerequisites setup_apt_repository install_docker post_install log_info "-----------------------------------------------------" log_info "Docker installation completed successfully! 🎉" log_info "REMEMBER TO LOG OUT AND LOG BACK IN to use Docker without sudo." log_info "Verify installation by running: docker run hello-world" log_info "-----------------------------------------------------" } # Run the main function main