Last active 1746373589

bash <(curl -s https://cdn.albert.lol/docker.sh)

docker.sh Raw
1#!/bin/bash
2#
3# Installs Docker Engine on Debian-based Linux distributions with colored output.
4# Runs apt operations quietly, showing high-level status messages.
5#
6# Usage:
7# ./docker.sh
8# bash <(curl -s https://cdn.albert.lol/docker.sh)
9#
10# Requires:
11# - Running on a Debian-based system (Debian, Ubuntu, etc.)
12# - User executing the script must have sudo privileges.
13# - Internet connection.
14# - A terminal that supports ANSI color codes.
15
16# Strict mode
17set -euo pipefail
18
19# --- Configuration ---
20readonly DOCKER_GPG_KEY_PATH="/etc/apt/keyrings/docker.asc"
21readonly DOCKER_APT_SOURCE_PATH="/etc/apt/sources.list.d/docker.list"
22
23# --- Colors ---
24# Reference: https://misc.flogisoft.com/bash/tip_colors_and_formatting
25readonly COLOR_RESET='\033[0m'
26readonly COLOR_RED='\033[0;31m'
27readonly COLOR_GREEN='\033[0;32m'
28readonly COLOR_YELLOW='\033[0;33m'
29readonly COLOR_BLUE='\033[0;34m'
30readonly COLOR_BOLD='\033[1m'
31
32# --- Helper Functions ---
33
34# Logs an informational message (Blue).
35# Arguments: $*: Message to log.
36log_info() {
37 echo -e "${COLOR_BLUE}[INFO]${COLOR_RESET} $*"
38}
39
40# Logs a success message (Green).
41# Arguments: $*: Message to log.
42log_success() {
43 echo -e "${COLOR_GREEN}[SUCCESS]${COLOR_RESET} $*"
44}
45
46# Logs a warning message (Yellow).
47# Arguments: $*: Message to log.
48log_warning() {
49 echo -e "${COLOR_YELLOW}[WARNING]${COLOR_RESET} $*"
50}
51
52# Logs an error message (Red) and exits.
53# Arguments: $*: Message to log.
54log_error() {
55 # Ensure error message goes to stderr
56 echo -e >&2 "${COLOR_RED}${COLOR_BOLD}[ERROR]${COLOR_RESET}${COLOR_RED} $*${COLOR_RESET}"
57 exit 1
58}
59
60# Checks if a command exists.
61# Arguments: $1: Command name.
62command_exists() {
63 command -v "$1" >/dev/null 2>&1
64}
65
66# --- Main Functions ---
67
68# Step 1: Update package lists and install prerequisite packages.
69install_prerequisites() {
70 local pkgs=("ca-certificates" "curl" "gnupg")
71 log_info "Updating package list (apt-get update)..."
72 # Run update quietly (-qq)
73 if ! sudo apt-get update -qq; then
74 log_error "Failed to update package lists."
75 fi
76
77 log_info "Installing prerequisite packages: ${pkgs[*]}..."
78 # Run install quietly (-qq) and assume yes (-y)
79 if ! sudo apt-get install -y -qq "${pkgs[@]}"; then
80 log_error "Failed to install prerequisite packages: ${pkgs[*]}."
81 fi
82 log_success "Prerequisites installed."
83}
84
85# Step 2: Set up Docker's official APT repository.
86setup_apt_repository() {
87 log_info "Setting up Docker's APT repository..."
88
89 # Create the directory for the GPG key if it doesn't exist
90 log_info "Ensuring keyring directory exists: /etc/apt/keyrings"
91 sudo install -m 0755 -d "$(dirname "${DOCKER_GPG_KEY_PATH}")"
92
93 # Download Docker's official GPG key
94 log_info "Downloading Docker GPG key to ${DOCKER_GPG_KEY_PATH}"
95 # Use curl with fail-fast, silent, show-error, location-follow flags
96 # Capture curl stderr to check for errors even with -s
97 local curl_stderr
98 if ! curl_stderr=$(sudo curl -fsSL "https://download.docker.com/linux/debian/gpg" -o "${DOCKER_GPG_KEY_PATH}" 2>&1); then
99 log_error "Failed to download Docker GPG key. Curl output: ${curl_stderr}"
100 fi
101 # Ensure the key is readable by apt
102 sudo chmod a+r "${DOCKER_GPG_KEY_PATH}"
103 log_success "Docker GPG key downloaded and permissions set."
104
105 # Detect architecture and OS codename
106 local arch
107 arch="$(dpkg --print-architecture)"
108 local codename
109 # Source os-release safely
110 if [[ -f /etc/os-release ]]; then
111 # shellcheck source=/dev/null
112 codename="$(. /etc/os-release && echo "$VERSION_CODENAME")"
113 else
114 log_error "Cannot determine OS codename. /etc/os-release not found."
115 fi
116
117 if [[ -z "$codename" ]]; then
118 log_error "Could not determine VERSION_CODENAME from /etc/os-release."
119 fi
120
121 # Add the Docker repository to Apt sources
122 log_info "Adding Docker repository source to ${DOCKER_APT_SOURCE_PATH}"
123 echo \
124 "deb [arch=${arch} signed-by=${DOCKER_GPG_KEY_PATH}] https://download.docker.com/linux/debian \
125 ${codename} stable" | sudo tee "${DOCKER_APT_SOURCE_PATH}" > /dev/null
126 log_success "Docker APT repository added."
127}
128
129# Step 3: Install Docker Engine packages.
130install_docker() {
131 local docker_pkgs=("docker-ce" "docker-ce-cli" "containerd.io" "docker-buildx-plugin" "docker-compose-plugin")
132 log_info "Updating package list after adding Docker repository..."
133 # Run update quietly (-qq)
134 if ! sudo apt-get update -qq; then
135 log_warning "Second 'apt-get update' failed. This might be okay if sources are correct, continuing installation..."
136 # Don't exit here, as sometimes transient network issues cause this but install might still work if cache is okay.
137 fi
138
139 log_info "Installing Docker packages: ${docker_pkgs[*]}..."
140 # Run install quietly (-qq) and assume yes (-y)
141 if ! sudo apt-get install -y -qq "${docker_pkgs[@]}"; then
142 log_error "Failed to install Docker packages: ${docker_pkgs[*]}."
143 fi
144 log_success "Docker packages installed."
145}
146
147# Step 4: Perform post-installation steps (add user to docker group).
148post_install() {
149 log_info "Adding current user (${USER}) to the 'docker' group..."
150 if getent group docker > /dev/null; then
151 # Use GID instead of name for group check in usermod, slightly more robust
152 local docker_gid
153 docker_gid=$(getent group docker | cut -d: -f3)
154 if ! groups "$USER" | grep -qw "$docker_gid" && ! groups "$USER" | grep -qw "docker"; then
155 if sudo usermod -aG docker "$USER"; then
156 log_success "User '${USER}' added to the 'docker' group."
157 log_warning "${COLOR_BOLD}IMPORTANT:${COLOR_RESET}${COLOR_YELLOW} You must log out and log back in for this change to take effect!${COLOR_RESET}"
158 log_info "Alternatively, run 'newgrp docker' in your current shell (may require password)."
159 else
160 log_error "Failed to add user '${USER}' to the 'docker' group."
161 fi
162 else
163 log_info "User '${USER}' is already in the 'docker' group."
164 fi
165 else
166 log_warning "The 'docker' group does not seem to exist. Skipping adding user."
167 log_warning "This might indicate an issue during Docker package installation."
168 fi
169}
170
171# --- Main Execution ---
172
173main() {
174 log_info "${COLOR_BOLD}Starting Docker installation script...${COLOR_RESET}"
175
176 # Basic checks
177 if ! command_exists sudo; then
178 log_error "'sudo' command not found. This script requires sudo privileges."
179 fi
180 # Allow running as root, but it's less common for interactive use.
181 # if [[ $EUID -eq 0 ]]; then
182 # log_warning "Running as root. It's generally recommended to run as a user with sudo privileges."
183 # fi
184 if ! command_exists dpkg || ! command_exists apt-get; then
185 log_error "'dpkg' or 'apt-get' not found. This script requires a Debian-based system."
186 fi
187 if ! [[ -f /etc/os-release ]]; then
188 log_error "File /etc/os-release not found. Cannot determine OS version. Aborting."
189 fi
190
191 # Execute steps
192 install_prerequisites
193 setup_apt_repository
194 install_docker
195 post_install
196
197 echo # Add a newline for spacing
198 log_success "-----------------------------------------------------"
199 log_success "${COLOR_BOLD}Docker installation completed successfully! 🎉${COLOR_RESET}"
200 log_warning "${COLOR_BOLD}REMEMBER TO LOG OUT AND LOG BACK IN${COLOR_RESET}${COLOR_YELLOW} to use Docker without 'sudo'.${COLOR_RESET}"
201 log_info "After logging back in, verify installation by running: ${COLOR_BOLD}docker run hello-world${COLOR_RESET}"
202 log_success "-----------------------------------------------------"
203}
204
205# Run the main function
206main