211 lines
6.0 KiB
Bash
Executable File
211 lines
6.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -Eeuo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
INSTALL_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
|
|
|
# shellcheck source=install/lib/common.sh
|
|
source "${INSTALL_DIR}/lib/common.sh"
|
|
# shellcheck source=install/lib/logging.sh
|
|
source "${INSTALL_DIR}/lib/logging.sh"
|
|
# shellcheck source=install/lib/packages.sh
|
|
source "${INSTALL_DIR}/lib/packages.sh"
|
|
|
|
atlas_set_script_name "30-docker.sh"
|
|
atlas_install_error_trap
|
|
|
|
DOCKER_KEYRING="/etc/apt/keyrings/docker.asc"
|
|
DOCKER_SOURCE="/etc/apt/sources.list.d/docker.list"
|
|
DOCKER_PACKAGES=(docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin)
|
|
DOCKER_CONFLICTS=(docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc)
|
|
DOCKER_REPO_BASE="https://download.docker.com/linux/ubuntu"
|
|
DOCKER_USER="nick"
|
|
|
|
usage() {
|
|
cat <<'USAGE'
|
|
Usage: install/phases/30-docker.sh [options]
|
|
|
|
Install Docker Engine from Docker's official signed Ubuntu APT repository.
|
|
|
|
Options:
|
|
--help Show this help text.
|
|
--version Show script/framework version.
|
|
--dry-run Show intended actions without making changes.
|
|
--verbose Print additional diagnostic output.
|
|
|
|
USAGE
|
|
}
|
|
|
|
while [[ "$#" -gt 0 ]]; do
|
|
case "$1" in
|
|
--help)
|
|
usage
|
|
exit "${ATLAS_EXIT_OK}"
|
|
;;
|
|
--version)
|
|
atlas_print_version
|
|
exit "${ATLAS_EXIT_OK}"
|
|
;;
|
|
--dry-run)
|
|
atlas_enable_dry_run
|
|
;;
|
|
--verbose)
|
|
atlas_enable_verbose
|
|
;;
|
|
*)
|
|
atlas_usage_error "Unknown option: $1"
|
|
exit "${ATLAS_EXIT_USAGE}"
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
load_os_release() {
|
|
# shellcheck disable=SC1091
|
|
. /etc/os-release
|
|
if [[ "${ID:-}" != "ubuntu" || "${VERSION_CODENAME:-}" != "resolute" ]]; then
|
|
atlas_log_error "Unsupported OS for this Docker phase: ${PRETTY_NAME:-unknown}"
|
|
exit "${ATLAS_EXIT_PREREQ}"
|
|
fi
|
|
}
|
|
|
|
docker_repo_available() {
|
|
curl -fsSL "${DOCKER_REPO_BASE}/dists/${VERSION_CODENAME}/Release" >/dev/null
|
|
}
|
|
|
|
install_prerequisites() {
|
|
local packages=(ca-certificates curl)
|
|
local missing=()
|
|
local package_name
|
|
for package_name in "${packages[@]}"; do
|
|
atlas_package_installed "$package_name" || missing+=("$package_name")
|
|
done
|
|
if [[ "${#missing[@]}" -gt 0 ]]; then
|
|
atlas_install_packages "${missing[@]}"
|
|
else
|
|
atlas_log_ok "Docker repository prerequisites are already installed"
|
|
fi
|
|
}
|
|
|
|
remove_conflicts() {
|
|
local installed=()
|
|
local package_name
|
|
for package_name in "${DOCKER_CONFLICTS[@]}"; do
|
|
atlas_package_installed "$package_name" && installed+=("$package_name")
|
|
done
|
|
if [[ "${#installed[@]}" -eq 0 ]]; then
|
|
atlas_log_ok "No conflicting Docker packages are installed"
|
|
return 0
|
|
fi
|
|
if [[ "${ATLAS_DRY_RUN}" == "1" ]]; then
|
|
atlas_log_info "Dry-run mode: would remove conflicting packages: ${installed[*]}"
|
|
return 0
|
|
fi
|
|
atlas_log_info "Removing conflicting Docker packages: ${installed[*]}"
|
|
atlas_sudo_run apt-get remove -y "${installed[@]}"
|
|
}
|
|
|
|
configure_repository() {
|
|
local arch repo_line
|
|
arch="$(dpkg --print-architecture)"
|
|
repo_line="deb [arch=${arch} signed-by=${DOCKER_KEYRING}] ${DOCKER_REPO_BASE} ${VERSION_CODENAME} stable"
|
|
|
|
if [[ -r "$DOCKER_SOURCE" ]] && grep -Fqx "$repo_line" "$DOCKER_SOURCE" && [[ -r "$DOCKER_KEYRING" ]]; then
|
|
atlas_log_ok "Docker APT repository is already configured"
|
|
return 0
|
|
fi
|
|
|
|
if [[ "${ATLAS_DRY_RUN}" == "1" ]]; then
|
|
atlas_log_info "Dry-run mode: would install Docker GPG key to ${DOCKER_KEYRING}"
|
|
atlas_log_info "Dry-run mode: would write Docker APT source ${DOCKER_SOURCE}"
|
|
atlas_log_info "Dry-run mode: would run apt-get update"
|
|
return 0
|
|
fi
|
|
|
|
atlas_sudo_run install -m 0755 -d /etc/apt/keyrings
|
|
tmp_key="$(mktemp)"
|
|
curl -fsSL "${DOCKER_REPO_BASE}/gpg" -o "$tmp_key"
|
|
atlas_sudo_run install -m 0644 "$tmp_key" "$DOCKER_KEYRING"
|
|
rm -f "$tmp_key"
|
|
printf '%s\n' "$repo_line" | sudo -n tee "$DOCKER_SOURCE" >/dev/null
|
|
atlas_sudo_run apt-get update
|
|
}
|
|
|
|
install_docker_packages() {
|
|
local missing=()
|
|
local package_name
|
|
for package_name in "${DOCKER_PACKAGES[@]}"; do
|
|
atlas_package_installed "$package_name" || missing+=("$package_name")
|
|
done
|
|
if [[ "${#missing[@]}" -eq 0 ]]; then
|
|
atlas_log_ok "Docker packages are already installed"
|
|
else
|
|
atlas_install_packages "${missing[@]}"
|
|
fi
|
|
}
|
|
|
|
enable_docker_service() {
|
|
atlas_log_info "Ensuring Docker service is enabled and active"
|
|
atlas_sudo_run systemctl enable docker
|
|
atlas_sudo_run systemctl start docker
|
|
}
|
|
|
|
ensure_docker_group() {
|
|
if id -nG "$DOCKER_USER" | tr ' ' '\n' | grep -qx docker; then
|
|
atlas_log_ok "User ${DOCKER_USER} is already in the docker group"
|
|
return 0
|
|
fi
|
|
if [[ "${ATLAS_DRY_RUN}" == "1" ]]; then
|
|
atlas_log_info "Dry-run mode: would add ${DOCKER_USER} to docker group"
|
|
return 0
|
|
fi
|
|
atlas_sudo_run usermod -aG docker "$DOCKER_USER"
|
|
atlas_log_warn "User ${DOCKER_USER} was added to docker group; a new login may be required"
|
|
}
|
|
|
|
verify_docker() {
|
|
if [[ "${ATLAS_DRY_RUN}" == "1" ]]; then
|
|
atlas_log_info "Dry-run mode: skipping Docker runtime verification"
|
|
return 0
|
|
fi
|
|
docker --version
|
|
docker compose version
|
|
docker buildx version
|
|
systemctl is-enabled docker >/dev/null
|
|
systemctl is-active docker >/dev/null
|
|
if docker info >/dev/null 2>&1; then
|
|
atlas_log_ok "Docker is available to the current shell without sudo"
|
|
else
|
|
atlas_log_warn "Current shell cannot use Docker without sudo; a new login or sg docker may be required"
|
|
sudo -n docker info >/dev/null
|
|
fi
|
|
atlas_log_ok "Docker verification passed"
|
|
}
|
|
|
|
main() {
|
|
load_os_release
|
|
atlas_require_sudo_noninteractive || {
|
|
atlas_log_error "Passwordless non-interactive sudo is required"
|
|
exit "${ATLAS_EXIT_PREREQ}"
|
|
}
|
|
atlas_require_command curl
|
|
atlas_require_command dpkg
|
|
atlas_require_command apt-get
|
|
atlas_require_command systemctl
|
|
|
|
docker_repo_available || {
|
|
atlas_log_error "Docker official repository is not available for ${VERSION_CODENAME}"
|
|
exit "${ATLAS_EXIT_PREREQ}"
|
|
}
|
|
|
|
install_prerequisites
|
|
remove_conflicts
|
|
configure_repository
|
|
install_docker_packages
|
|
enable_docker_service
|
|
ensure_docker_group
|
|
verify_docker
|
|
}
|
|
|
|
main
|