lefteros_by SomniusX
EN ↗Πες ένα γεια

23 Οκτωβρίου 2025 / Lefteris Iliadis (SomniusX)

Lazydocker - Διαχείριση Docker από το Terminal με Στυλ! 🐳

Γεια σας παιδιά, μέσα στο σύνολο των θεμάτων που ανοίγω τελευταία, για αυτοματισμούς και δικές μου διαδικασίες που εξυπηρετούν, είναι και ακόμα ένα….

Lazydocker - Διαχείριση Docker από το Terminal με Στυλ! 🐳

Γεια σας παιδιά, μέσα στο σύνολο των θεμάτων που ανοίγω τελευταία, για αυτοματισμούς και δικές μου διαδικασίες που εξυπηρετούν, είναι και ακόμα ένα….

image Εικόνα από pimylifeup.com/raspberry-pi-lazydocker

Σήμερα θέλω να μοιραστώ μαζί σας ένα εργαλείο που μου άλλαξε τον τρόπο που δουλεύω με το Docker - το lazydocker.

Τι είναι το Lazydocker;

Το lazydocker είναι ένα TUI (Terminal User Interface) για το Docker. Με απλά λόγια, είναι σαν να έχεις ένα γραφικό περιβάλλον μέσα στο terminal σου! Αντί να γράφεις ατελείωτες εντολές docker ps, docker logs, docker stats κλπ, ανοίγεις το lazydocker και έχεις όλα αυτά μπροστά σου σε ένα όμορφο και λειτουργικό interface.

Γιατί είναι καλύτερο από άλλες λύσεις;

Ας το συγκρίνουμε με το γνωστό Portainer:

  • Portainer: Χρειάζεται να τρέξεις ένα container, να καταναλώνει resources, να ανοίξεις browser, να θυμηθείς το port…
  • Lazydocker: Γράφεις lzd, πατάς Enter, και είσαι μέσα! Zero overhead, zero setup μετά την εγκατάσταση.

Το lazydocker είναι ιδανικό όταν:

  • Δουλεύεις σε SSH σε κάποιο server (σούπερ εργαλείο λέμε)
  • Θέλεις γρήγορη πρόσβαση χωρίς να ανοίγεις browser
  • Προτιμάς keyboard navigation (πολύ πιο γρήγορο!)
  • Δεν θέλεις να τρέχεις extra containers για management

Φυσικά το Portainer έχει το δικό του κοινό για production environments με teams, αλλά για προσωπική χρήση ή development, το lazydocker είναι ακαταμάχητο!

Το Installation Script

Έφτιαξα ένα universal installation script που λειτουργεί σε όλες τις distros:

  • Fedora, Nobara, RHEL
  • Arch, CachyOS, Omarchy, Manjaro
  • Ubuntu, Debian
  • OpenSUSE
  • και οποιαδήποτε άλλη!

Το script:

  • Ανιχνεύει αυτόματα το σύστημα και την αρχιτεκτονική σου
  • Κατεβάζει την τελευταία έκδοση από το GitHub
  • Κάνει την εγκατάσταση στο /usr/local/bin
  • Προσθέτει το alias lzd στο shell σου (bash/zsh/fish)
  • Σου δίνει οδηγίες για το Docker αν δεν το έχεις

Bonus: Δουλεύει και σε Windows!

Αν χρησιμοποιείς WSL (Windows Subsystem for Linux), μπορείς να το τρέξεις κανονικά εκεί! Είναι ίσως ο καλύτερος τρόπος να διαχειριστείς Docker Desktop στα Windows χωρίς να πατάς GUI buttons.

Πώς το εγκαθιστώ;

# Κατέβασε το script
nano install-lazydocker.sh

# Κάντο executable
chmod +x install-lazydocker.sh

# Τρέξτο
./install-lazydocker.sh

Μετά απλά κάνε source ~/.bashrc και είσαι έτοιμος!

Εάν δεν έχετε nano τότε τον text editor της επιλογής σας (vim/micro/κλπ)

Χρήση

lzd  # ή lazydocker

Πλοήγηση με βέλη, Enter για details, x για menu, q για έξοδο.


Προσωπικά από όταν το ανακάλυψα, δεν έχω ξανανοίξει Portainer ούτε Docker Desktop UI. Το lzd είναι πάντα ένα Alt+T μακριά!

Δοκιμάστε το και πείτε μου τι λέτε! 🚀


Πάρτε και το actual bash script :

#!/bin/bash

# Script to install lazydocker on any Linux distribution
# Supports all major distros and their forks (Nobara, CachyOS, Omarchy, etc.)
# Includes shell integration for bash, zsh, and fish

set -e

# --- Configuration ---
LAZYDOCKER_INSTALL_DIR="/usr/local/bin"
GITHUB_API_URL="https://api.github.com/repos/jesseduffield/lazydocker/releases/latest"
TMP_DIR="/tmp/lazydocker_install"

# --- Colors for output ---
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# --- Helper Functions ---
verbose() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

error() {
    echo -e "${RED}[ERROR]${NC} $1"
    exit 1
}

check_command() {
    if ! command -v "$1" &> /dev/null; then
        return 1
    fi
    return 0
}

# --- Check for required dependencies ---
check_dependencies() {
    verbose "Checking for required dependencies..."
    
    local missing_deps=()
    
    if ! check_command curl && ! check_command wget; then
        missing_deps+=("curl or wget")
    fi
    
    if ! check_command tar; then
        missing_deps+=("tar")
    fi
    
    if ! check_command jq; then
        warning "jq is not installed. Will use fallback method for JSON parsing."
    fi
    
    if [ ${#missing_deps[@]} -ne 0 ]; then
        error "Missing required dependencies: ${missing_deps[*]}"
    fi
    
    success "All required dependencies are available"
}

# --- Detect system architecture ---
detect_architecture() {
    local arch=$(uname -m)
    
    case "$arch" in
        x86_64|amd64)
            echo "x86_64"
            ;;
        aarch64|arm64)
            echo "arm64"
            ;;
        armv7l|armhf)
            echo "armv7"
            ;;
        i386|i686)
            echo "i386"
            ;;
        *)
            error "Unsupported architecture: $arch"
            ;;
    esac
}

# --- Detect operating system ---
detect_os() {
    if [ -f /etc/os-release ]; then
        . /etc/os-release
        echo "$ID"
    else
        error "Cannot detect operating system"
    fi
}

# --- Download file with fallback ---
download_file() {
    local url="$1"
    local output="$2"
    local show_progress="${3:-false}"
    
    if check_command curl; then
        if [ "$show_progress" = "true" ]; then
            curl -fL --progress-bar "$url" -o "$output" || error "Failed to download from $url"
        else
            curl -fsSL "$url" -o "$output" || error "Failed to download from $url"
        fi
    elif check_command wget; then
        if [ "$show_progress" = "true" ]; then
            wget --show-progress "$url" -O "$output" || error "Failed to download from $url"
        else
            wget -q "$url" -O "$output" || error "Failed to download from $url"
        fi
    else
        error "Neither curl nor wget is available"
    fi
}

# --- Get latest release info from GitHub ---
get_latest_version() {
    verbose "Fetching latest lazydocker version from GitHub..." >&2
    
    local json_file="$TMP_DIR/release.json"
    download_file "$GITHUB_API_URL" "$json_file"
    
    if check_command jq; then
        # Use jq for proper JSON parsing
        local version=$(jq -r '.tag_name' "$json_file" | sed 's/^v//')
        local download_url=$(jq -r ".assets[] | select(.name | contains(\"Linux_$1.tar.gz\")) | .browser_download_url" "$json_file")
    else
        # Fallback to grep/sed parsing
        local version=$(grep -o '"tag_name": *"[^"]*"' "$json_file" | head -1 | sed 's/.*"v\?\([^"]*\)".*/\1/')
        local download_url=$(grep -o '"browser_download_url": *"[^"]*Linux_'"$1"'.tar.gz"' "$json_file" | head -1 | sed 's/.*"\(http[^"]*\)".*/\1/')
    fi
    
    if [ -z "$version" ] || [ -z "$download_url" ]; then
        error "Failed to parse release information"
    fi
    
    echo "$version|$download_url"
}

# --- Compare version numbers (returns 0 if v1 >= v2, 1 if v1 < v2) ---
compare_versions() {
    local v1="$1"
    local v2="$2"
    
    # Remove 'v' prefix if present
    v1="${v1#v}"
    v2="${v2#v}"
    
    # Split versions into arrays
    IFS='.' read -ra v1_parts <<< "$v1"
    IFS='.' read -ra v2_parts <<< "$v2"
    
    # Compare each part
    local max_len=${#v1_parts[@]}
    if [ ${#v2_parts[@]} -gt $max_len ]; then
        max_len=${#v2_parts[@]}
    fi
    
    for ((i=0; i<max_len; i++)); do
        local v1_part=${v1_parts[i]:-0}
        local v2_part=${v2_parts[i]:-0}
        
        if [ "$v1_part" -gt "$v2_part" ]; then
            return 0  # v1 > v2
        elif [ "$v1_part" -lt "$v2_part" ]; then
            return 1  # v1 < v2
        fi
    done
    
    return 0  # v1 == v2
}

# --- Get currently installed version ---
get_installed_version() {
    if check_command lazydocker; then
        # Try to get version from lazydocker --version output
        local version_output=$(lazydocker --version 2>&1)
        local version=$(echo "$version_output" | grep -oP 'Version: \K[0-9.]+' || echo "")
        
        if [ -z "$version" ]; then
            # Try alternative format
            version=$(echo "$version_output" | grep -oP 'version=\K[0-9.]+' || echo "")
        fi
        
        if [ -n "$version" ]; then
            echo "$version"
            return 0
        fi
    fi
    return 1
}

# --- Check if lazydocker is already installed and compare versions ---
# Returns: 0 if upgrade needed, 1 if already latest, 2 if not installed
check_existing_installation() {
    local installed_version=""
    
    if get_installed_version > /dev/null 2>&1; then
        installed_version=$(get_installed_version)
        verbose "Lazydocker is already installed (version: $installed_version)"
        
        # Get latest version for comparison
        local arch=$(detect_architecture)
        mkdir -p "$TMP_DIR"
        local release_info=$(get_latest_version "$arch")
        local latest_version=$(echo "$release_info" | cut -d'|' -f1)
        
        verbose "Latest available version: $latest_version"
        
        # Compare versions
        if compare_versions "$installed_version" "$latest_version"; then
            if [ "$installed_version" = "$latest_version" ]; then
                success "You already have the latest version ($installed_version) installed!"
                read -p "Do you want to reinstall anyway? (y/n): " -n 1 -r
                echo
                if [[ ! $REPLY =~ ^[Yy]$ ]]; then
                    rm -rf "$TMP_DIR"
                    return 1  # Already latest, exit
                fi
                return 0  # User wants to reinstall
            else
                warning "Installed version ($installed_version) is newer than latest release ($latest_version)."
                warning "This shouldn't happen, but continuing anyway..."
                return 0  # Continue with installation
            fi
        else
            success "Update available: $installed_version -> $latest_version"
            verbose "Will automatically upgrade to the latest version..."
            return 0  # Upgrade needed
        fi
    else
        verbose "Lazydocker is not currently installed. Proceeding with fresh installation..."
        return 2  # Not installed
    fi
}

# --- Install docker if not present (optional) ---
check_docker() {
    if ! check_command docker; then
        warning "Docker is not installed. Lazydocker requires Docker to be useful."
        read -p "Do you want to continue anyway? (y/n): " -n 1 -r
        echo
        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
            exit 0
        fi
    fi
}

# --- Main installation function ---
install_lazydocker() {
    local arch=$(detect_architecture)
    verbose "Detected architecture: $arch"
    
    local os=$(detect_os)
    verbose "Detected OS: $os"
    
    # Create temporary directory
    mkdir -p "$TMP_DIR"
    
    # Get latest version and download URL
    local release_info=$(get_latest_version "$arch")
    local version=$(echo "$release_info" | cut -d'|' -f1)
    local download_url=$(echo "$release_info" | cut -d'|' -f2)
    
    verbose "Latest version: $version"
    verbose "Download URL: $download_url"
    
    # Download tarball
    local tarball="$TMP_DIR/lazydocker.tar.gz"
    verbose "Downloading lazydocker v$version..."
    download_file "$download_url" "$tarball" "true"
    success "Downloaded successfully"
    
    # Extract tarball
    verbose "Extracting archive..."
    tar -xzf "$tarball" -C "$TMP_DIR" || error "Failed to extract archive"
    
    # Remove old binary if it exists
    local old_binary_path=""
    if check_command lazydocker; then
        old_binary_path=$(command -v lazydocker)
        verbose "Found existing lazydocker at: $old_binary_path"
        
        if [ -f "$old_binary_path" ]; then
            verbose "Removing old binary..."
            if [ -w "$(dirname "$old_binary_path")" ]; then
                rm -f "$old_binary_path" || warning "Could not remove old binary (may need sudo)"
            else
                sudo rm -f "$old_binary_path" || warning "Could not remove old binary"
            fi
        fi
    fi
    
    # Install binary
    verbose "Installing lazydocker to $LAZYDOCKER_INSTALL_DIR..."
    if [ -w "$LAZYDOCKER_INSTALL_DIR" ]; then
        mv "$TMP_DIR/lazydocker" "$LAZYDOCKER_INSTALL_DIR/" || error "Failed to move binary"
        chmod +x "$LAZYDOCKER_INSTALL_DIR/lazydocker" || error "Failed to set permissions"
    else
        sudo mv "$TMP_DIR/lazydocker" "$LAZYDOCKER_INSTALL_DIR/" || error "Failed to move binary"
        sudo chmod +x "$LAZYDOCKER_INSTALL_DIR/lazydocker" || error "Failed to set permissions"
    fi
    
    success "Lazydocker installed successfully!"
    
    # Cleanup
    verbose "Cleaning up temporary files..."
    rm -rf "$TMP_DIR"
}

# --- Setup shell integration ---
setup_shell_integration() {
    verbose "Setting up shell integration..."
    
    # Check which shells are available
    local shells=()
    [ -f "$HOME/.bashrc" ] && shells+=("bash")
    [ -f "$HOME/.zshrc" ] && shells+=("zsh")
    check_command fish && [ -d "$HOME/.config/fish" ] && shells+=("fish")
    
    if [ ${#shells[@]} -eq 0 ]; then
        warning "No shell configuration files found"
        return
    fi
    
    verbose "Detected shells: ${shells[*]}"
    
    read -p "Do you want to add lazydocker alias 'lzd' to your shell config? (y/n): " -n 1 -r
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]; then
        for shell in "${shells[@]}"; do
            case "$shell" in
                bash)
                    if ! grep -q "alias lzd=" "$HOME/.bashrc"; then
                        echo "" >> "$HOME/.bashrc"
                        echo "# Lazydocker alias" >> "$HOME/.bashrc"
                        echo "alias lzd='lazydocker'" >> "$HOME/.bashrc"
                        success "Added alias to ~/.bashrc"
                    else
                        verbose "Alias already exists in ~/.bashrc"
                    fi
                    ;;
                zsh)
                    if ! grep -q "alias lzd=" "$HOME/.zshrc"; then
                        echo "" >> "$HOME/.zshrc"
                        echo "# Lazydocker alias" >> "$HOME/.zshrc"
                        echo "alias lzd='lazydocker'" >> "$HOME/.zshrc"
                        success "Added alias to ~/.zshrc"
                    else
                        verbose "Alias already exists in ~/.zshrc"
                    fi
                    ;;
                fish)
                    local fish_config="$HOME/.config/fish/config.fish"
                    if [ -f "$fish_config" ]; then
                        if ! grep -q "alias lzd=" "$fish_config"; then
                            echo "" >> "$fish_config"
                            echo "# Lazydocker alias" >> "$fish_config"
                            echo "alias lzd='lazydocker'" >> "$fish_config"
                            success "Added alias to $fish_config"
                        else
                            verbose "Alias already exists in $fish_config"
                        fi
                    fi
                    ;;
            esac
        done
        
        warning "Please restart your shell or run 'source ~/.bashrc' (or ~/.zshrc) to use the alias"
    fi
}

# --- Verify installation ---
verify_installation() {
    verbose "Verifying installation..."
    
    if check_command lazydocker; then
        local version=$(lazydocker --version 2>&1 | head -1)
        success "Lazydocker is installed and working!"
        echo ""
        echo -e "${GREEN}$version${NC}"
        echo ""
        echo "You can now run 'lazydocker' or 'lzd' (if you set up the alias) to start using it."
    else
        error "Installation verification failed. Lazydocker command not found."
    fi
}

# --- Main script execution ---
main() {
    echo ""
    echo -e "${BLUE}╔════════════════════════════════════════╗${NC}"
    echo -e "${BLUE}║   Lazydocker Universal Installer       ║${NC}"
    echo -e "${BLUE}║   Supports all Linux distributions     ║${NC}"
    echo -e "${BLUE}╚════════════════════════════════════════╝${NC}"
    echo ""
    
    # Check if running as root
    if [ "$EUID" -eq 0 ]; then
        warning "Running as root. This is not recommended."
        read -p "Continue anyway? (y/n): " -n 1 -r
        echo
        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
            exit 0
        fi
    fi
    
    check_dependencies
    check_existing_installation
    check_docker
    install_lazydocker
    setup_shell_integration
    verify_installation
    
    echo ""
    success "Installation complete!"
    echo ""
    echo -e "${YELLOW}Note:${NC} If Docker is not installed, you can install it using your distro's package manager:"
    echo "  - Debian/Ubuntu/Nobara/Fedora: sudo dnf install docker (or apt install docker.io)"
    echo "  - Arch/CachyOS/Omarchy: sudo pacman -S docker"
    echo "  - OpenSUSE: sudo zypper install docker"
    echo ""
    echo "After installing Docker, enable and start the service:"
    echo "  sudo systemctl enable --now docker"
    echo "  sudo usermod -aG docker \$USER  # Add yourself to docker group"
    echo ""
}

# Run main function
main