Files
Homelab/portainerup.sh
2026-02-04 22:12:07 +01:00

229 lines
8.4 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
set -e
# --- Colors and Formatting ---
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
BOLD='\033[1m'
RESET='\033[0m'
info() { echo -e "${CYAN} $*${RESET}"; }
success() { echo -e "${GREEN}$*${RESET}"; }
warn() { echo -e "${YELLOW}$*${RESET}"; }
error() { echo -e "${RED}$*${RESET}"; }
step() { echo -e "${BOLD}${BLUE}$*${RESET}"; }
# Prompt for sudo password upfront, so it caches for script duration
if ! sudo -v; then
error "This script requires sudo privileges. Please run again with a sudo-capable user."
exit 1
fi
# Keep-alive to update sudo timestamp until script finishes
while true; do sudo -n true; sleep 60; kill -0 "$$" || exit; done 2>/dev/null &
# --- Detect distribution ---
if [ -f /etc/os-release ]; then
. /etc/os-release
DISTRO_ID="$ID"
DISTRO_VERSION="$VERSION_ID"
DISTRO_CODENAME="$VERSION_CODENAME"
else
error "Cannot detect Linux distribution."
exit 1
fi
# Fallback for older Debian/Ubuntu releases
if [[ "$DISTRO_ID" == "debian" ]]; then
if [[ -z "$DISTRO_CODENAME" || ! -f "/usr/share/keyrings/docker-archive-keyring.gpg" ]]; then
DISTRO_CODENAME="bookworm" # Fallback to Debian 12
fi
elif [[ "$DISTRO_ID" == "ubuntu" ]]; then
if [[ -z "$DISTRO_CODENAME" || ! -f "/usr/share/keyrings/docker-archive-keyring.gpg" ]]; then
DISTRO_CODENAME="jammy" # Fallback to Ubuntu 22.04 LTS
fi
fi
install_docker() {
step "Installing Docker for ${BOLD}$DISTRO_ID $DISTRO_VERSION${RESET}..."
case "$DISTRO_ID" in
ubuntu|debian|raspbian|linuxmint)
info "Adding Docker repository and installing Docker for Debian/Ubuntu..."
sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl gnupg lsb-release
curl -fsSL https://download.docker.com/linux/"$DISTRO_ID"/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/$DISTRO_ID $DISTRO_CODENAME stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker
;;
fedora)
info "Installing Docker from Fedora repositories..."
sudo dnf remove -y podman-docker || true
sudo dnf install -y dnf-plugins-core
sudo dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo
sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker
;;
centos|rhel|rocky|almalinux|ol|oracle)
info "Adding Docker repository and installing Docker for CentOS/RHEL..."
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker
;;
arch|manjaro|endeavouros|garuda|artix|arcolinux|antergos|chakra|kaos)
info "Installing Docker with pacman (Arch-based)..."
sudo pacman -Sy --noconfirm docker docker-compose
sudo systemctl enable --now docker
;;
opensuse*|suse|sles)
info "Installing Docker with zypper..."
sudo zypper install -y docker docker-compose
sudo systemctl enable --now docker
;;
alpine)
info "Installing Docker with apk..."
sudo apk add --update docker docker-compose
sudo rc-update add docker boot
sudo service docker start
;;
*)
error "Unsupported or unrecognized Linux distribution: $DISTRO_ID"
exit 1
;;
esac
# Fix permissions for current user
sudo chown -R "$USER":"$USER" "$HOME/.docker" || true
sudo chmod -R g+rwx "$HOME/.docker" || true
if ! groups "$USER" | grep -qw docker; then
sudo usermod -aG docker "$USER"
warn "User '$USER' has been added to the 'docker' group."
error "IMPORTANT: Docker group permissions will NOT be active in this current session."
error "Please LOG OUT completely and LOG BACK IN (or reboot the machine) then re-run this script."
exit 1
else
success "User '$USER' is already in the 'docker' group."
fi
}
install_docker_compose_standalone() {
step "Installing Docker Compose standalone..."
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
success "Docker Compose installed."
}
step "Checking for Docker..."
if ! command -v docker &>/dev/null; then
warn "Docker not found. Starting installation..."
install_docker
else
success "Docker is already installed."
fi
step "Verifying Docker daemon access permissions for current user..."
if ! docker info &>/dev/null; then
error "Permission denied: Cannot connect to Docker daemon."
error "Your user ('$USER') does not have correct permissions for Docker in this session."
info "Current groups for user: $(groups "$USER")"
info "Docker socket permissions: $(ls -l /var/run/docker.sock 2>/dev/null || echo 'Socket not found')"
error "Try running this command to refresh group membership in this terminal:"
echo -e "${YELLOW} newgrp docker${RESET}"
error "Or LOG OUT completely and LOG BACK IN (or reboot the machine) then re-run this script."
exit 1
else
success "Docker daemon is accessible with current user permissions."
fi
step "Checking for Docker Compose..."
if ! docker compose version &>/dev/null; then
if ! command -v docker-compose &>/dev/null; then
warn "Docker Compose not found. Installing standalone version..."
install_docker_compose_standalone
else
success "Docker Compose (standalone) is already installed."
fi
else
success "Docker Compose (plugin) is already installed."
fi
step "Ensuring Docker service is running..."
if [[ "$DISTRO_ID" == "alpine" ]]; then
if ! sudo service docker status 2>/dev/null | grep -q 'status: started'; then
info "Starting Docker service..."
sudo service docker start || true
sleep 5 # Give Docker time to start
else
success "Docker service is running."
fi
else
if ! sudo systemctl is-active --quiet docker; then
info "Starting Docker service..."
sudo systemctl start docker || true
sleep 5 # Give Docker time to start
else
success "Docker service is running."
fi
fi
# --- Portainer Installation/Update ---
UPDATE_PORTAINER=${1:-""}
step "Checking for existing Portainer container..."
if docker ps -a --format '{{.Names}}' | grep -q "^portainer$"; then
if [[ "$UPDATE_PORTAINER" == "--update" ]]; then
warn "Updating Portainer container..."
docker stop portainer || true
docker rm portainer || true
else
warn "Portainer container already exists. Use '--update' to force an update."
exit 0
fi
else
info "No existing Portainer container found. Proceeding with installation."
fi
step "Pulling latest Portainer image..."
docker pull portainer/portainer-ce:latest
step "Starting Portainer container..."
if [[ "$DISTRO_ID" == "fedora" ]]; then
docker run -d \
--privileged \
-p 8000:8000 -p 9443:9443 \
--name portainer \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-ce:latest
else
docker run -d \
-p 8000:8000 -p 9443:9443 \
--name portainer \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-ce:latest
fi
success "Portainer is now installed and running!"
# --- IP Detection ---
IP=$(hostname -I 2>/dev/null | awk '{print $1}' || ip route get 1 | awk '{print $7}' || echo "localhost")
echo -e "${BOLD}${CYAN}🌐 Access your Portainer dashboard at:${RESET} ${GREEN}https://$IP:9443${RESET}"
echo -e "${YELLOW}Note: You may need to accept a self-signed certificate in your browser for HTTPS.${RESET}"