Last active
April 20, 2025 22:06
-
-
Save ScottJWalter/9ec839590f20fd4ac36d3432347a4548 to your computer and use it in GitHub Desktop.
Install 32-bit docker on rpi (3, etc.)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -e | |
######################################## | |
# π§ Configuration # | |
######################################## | |
ARCH="$(dpkg --print-architecture)" | |
VERSION_CODENAME="$(grep -oP '(?<=\bVERSION_CODENAME=)[^;]+' /etc/os-release)" | |
URL="https://download.docker.com/linux/raspbian/dists/${VERSION_CODENAME}/pool/stable/${ARCH}/" | |
DOWNLOAD_DIR="${HOME}/.downloads/docker" | |
PATTERNS="^(containerd\.io|docker\-ce|docker\-ce\-cli|docker\-buildx\-plugin|docker\-compose\-plugin)_.*_${ARCH}\.deb$" | |
######################################## | |
# π§Ύ Functions # | |
######################################## | |
print_help() { | |
cat <<EOF | |
Usage: $0 [options] | |
Options: | |
--dry-run Show which files would be downloaded | |
--no-log Skip logging to a file | |
--clean Remove existing Docker packages before installing | |
--quiet Suppress non-essential output | |
--debug Enable debug messages | |
--help Show this help message and exit | |
EOF | |
} | |
parse_flags() { | |
DRY_RUN=false | |
NO_LOG=false | |
CLEAN_FIRST=false | |
QUIET=false | |
DEBUG=false | |
for arg in "$@"; do | |
case "$arg" in | |
--dry-run) DRY_RUN=true ;; | |
--no-log) NO_LOG=true ;; | |
--clean) CLEAN_FIRST=true ;; | |
--quiet) QUIET=true ;; | |
--debug) DEBUG=true ;; | |
--help) print_help; exit 0 ;; | |
esac | |
done | |
} | |
log() { | |
if ! $QUIET; then | |
echo "$@" | |
fi | |
} | |
log_debug() { if $DEBUG; then echo "π DEBUG: $1"; fi } | |
log_info() { log "βΉοΈ $1"; } | |
log_warn() { log "β οΈ $1"; } | |
log_error() { echo "β $1" >&2; } | |
log_success() { log "β $1"; } | |
run_test_stub() { | |
log_info "Running test stub: $1" | |
return 0 | |
} | |
run_all_tests() { | |
run_test_stub "parse_flags" | |
run_test_stub "enable_logging" | |
run_test_stub "clean_existing_docker" | |
run_test_stub "prepare_download_dir" | |
run_test_stub "fetch_file_list" | |
run_test_stub "download_and_verify" | |
run_test_stub "install_packages" | |
run_test_stub "final_steps" | |
} | |
enable_logging() { | |
if ! $NO_LOG; then | |
mkdir -p "$DOWNLOAD_DIR" | |
LOGFILE="${DOWNLOAD_DIR}/install.log" | |
exec > >(tee -a "$LOGFILE") 2>&1 | |
fi | |
} | |
clean_existing_docker() { | |
if $CLEAN_FIRST; then | |
log "π§Ή Cleaning existing Docker packages..." | |
if $DRY_RUN; then | |
log " DRY-RUN: apt cleaned of docker packages here ..." | |
else | |
sudo apt remove -y docker docker-engine docker.io containerd runc docker-ce docker-ce-cli docker-compose-plugin docker-buildx-plugin containerd.io || true | |
sudo apt autoremove -y | |
fi | |
fi | |
} | |
prepare_download_dir() { | |
mkdir -p "$DOWNLOAD_DIR" | |
find "$DOWNLOAD_DIR" -type f -name '*.deb' -delete | |
find "$DOWNLOAD_DIR" -type f -name '*.sha256' -delete | |
} | |
fetch_file_list() { | |
log "π¦ Fetching latest files from: $URL" | |
log "π Download directory: $DOWNLOAD_DIR" | |
mapfile -t DPKG_FILES < <( | |
curl -s "$URL" | \ | |
grep -oP '(?<=href=")[^"]+' | \ | |
grep -v '/$' | \ | |
grep -E "$PATTERNS" | \ | |
sort | \ | |
awk -F'_' ' | |
{ | |
base = $1; | |
files[base] = $0; | |
} | |
END { | |
for (f in files) { | |
print files[f] | |
} | |
}') | |
if [[ ${#DPKG_FILES[@]} -eq 0 ]]; then | |
log_warn "No matching files found." | |
exit 0 | |
fi | |
} | |
download_and_verify() { | |
for file in "${DPKG_FILES[@]}"; do | |
if $DRY_RUN; then | |
log "DRY-RUN: $file downloaded here..." | |
else | |
log "β¬οΈ Downloading $file..." | |
wget -q --show-progress --tries=3 --timeout=15 -O "${DOWNLOAD_DIR}/${file}" "${URL}${file}" | |
SHA_FILE="${file}.sha256" | |
log -n "π Checking for checksum: $SHA_FILE... " | |
if curl --silent --fail --head "${URL}${SHA_FILE}" > /dev/null; then | |
log "found." | |
curl -s "${URL}${SHA_FILE}" -o "${DOWNLOAD_DIR}/${SHA_FILE}" | |
pushd "$DOWNLOAD_DIR" > /dev/null | |
if ! sha256sum -c "$SHA_FILE"; then | |
log_error "Checksum failed for $file!" | |
exit 1 | |
fi | |
popd > /dev/null | |
else | |
log "not found. Skipping validation." | |
fi | |
fi | |
done | |
log_success "All downloads complete." | |
} | |
install_packages() { | |
log "π οΈ Installing..." | |
pushd "$DOWNLOAD_DIR" > /dev/null | |
if $DRY_RUN; then | |
log "DRY-RUN: dpkg -i ${DPKG_FILES[@]/#/./}" | |
else | |
if sudo dpkg -i "${DPKG_FILES[@]/#/./}"; then | |
sudo rm -- "${DPKG_FILES[@]/#/./}" | |
else | |
log_error "dpkg install failed. Keeping downloaded files for inspection." | |
exit 1 | |
fi | |
fi | |
popd > /dev/null | |
} | |
final_steps() { | |
log_success "Installation complete." | |
if ! $DRY_RUN; then | |
sudo systemctl status docker | |
if ! id -nG "$USER" | grep -qw docker; then | |
log "π§ Adding user '$USER' to docker group..." | |
sudo groupadd -f docker | |
sudo usermod -aG docker "$USER" | |
log_warn "You must log out and log back in for group changes to take effect." | |
else | |
log_info "User '$USER' is already in the docker group." | |
fi | |
log "π All done! Try: 'docker run hello-world' after logging back in." | |
fi | |
} | |
report_summary() { | |
log_success "Docker components downloaded and installed successfully:" | |
for f in "${DPKG_FILES[@]}"; do | |
log_success " - $f" | |
done | |
} | |
######################################## | |
# π¦ Main Execution # | |
######################################## | |
parse_flags "$@" | |
run_all_tests | |
enable_logging | |
clean_existing_docker | |
prepare_download_dir | |
fetch_file_list | |
download_and_verify | |
install_packages | |
final_steps | |
report_summary |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Assembled from various sources, I was looking for a convenient way to get 32-bit docker on a raspberry pi 3. With gpg key updates/expirations/depracations/etc., it's almost impossible to link "older" tech into the auto management system. So, here's a script that pulls the .deb files directly.