Quick bash cuda-toolkit drivers for 3060ti, 3080, 4090, 5090 in Ubuntu / Debian

This quick script is for you to get your nvidia drivers up quickly with cuda toolkit for getting your LLM's to work!

Quick bash cuda-toolkit drivers for 3060ti, 3080, 4090, 5090 in Ubuntu / Debian

We had Grok write us a quick script for installing the cuda-toolkit for anyone needing to get their LLM base up quickly!

  • Ubuntu  Based Installation
#!/bin/bash

# =============================================================================
# NVIDIA CUDA Driver Installation Script
# Supported GPUs: RTX 3060 Ti, RTX 3080, RTX 4090, RTX 5090
# Target OS: Ubuntu 20.04 LTS, 22.04 LTS, 24.04 LTS (or derivative Debian-based)
# =============================================================================
# This script performs a clean installation of the latest stable NVIDIA driver
# and CUDA toolkit compatible with the specified GPUs. It:
# 1. Detects the current Ubuntu version and GPU model.
# 2. Blacklists Nouveau drivers.
# 3. Installs required dependencies.
# 4. Adds the official NVIDIA CUDA repository.
# 5. Installs the latest production-branch driver and CUDA toolkit.
# 6. Configures secure boot (if enabled) by prompting for MOK enrollment.
# 7. Verifies installation via nvidia-smi and nvcc.
#
# Requirements:
# - Root privileges (sudo)
# - Internet access
# - Secure Boot must be handled interactively if enabled
#
# WARNING: This script purges existing NVIDIA packages. Backup critical data.
# =============================================================================

set -euo pipefail

# -----------------------------
# Configuration & Constants
# -----------------------------
readonly SCRIPT_NAME="$(basename "${BASH_SOURCE[0]}")"
readonly LOG_FILE="/var/log/${SCRIPT_NAME%.sh}.log"
readonly SUPPORTED_UBUNTU_VERSIONS=("20.04" "22.04" "24.04")
readonly GPU_MODELS=("3060ti" "3080" "4090" "5090")
readonly CUDA_REPO_PIN="https://developer.download.nvidia.com/compute/cuda/repos"

# -----------------------------
# Utility Functions
# -----------------------------
log() {
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE"
}

error() {
    log "ERROR: $*"
    exit 1
}

check_root() {
    [[ $EUID -eq 0 ]] || error "This script must be run as root (use sudo)."
}

detect_ubuntu_version() {
    local version
    version=$(lsb_release -rs 2>/dev/null) || error "Unable to detect Ubuntu version."
    log "Detected Ubuntu version: $version"
    if ! printf '%s\n' "${SUPPORTED_UBUNTU_VERSIONS[@]}" | grep -qx "$version"; then
        error "Unsupported Ubuntu version: $version. Supported: ${SUPPORTED_UBUNTU_VERSIONS[*]}"
    fi
    echo "$version"
}

detect_gpu() {
    local gpu_info
    gpu_info=$(lspci | grep -Ei 'vga|3d' | grep -i nvidia) || true
    if [[ -z "$gpu_info" ]]; then
        error "No NVIDIA GPU detected via lspci."
    fi

    local model_found=false
    for model in "${GPU_MODELS[@]}"; do
        if echo "$gpu_info" | grep -qi "$model"; then
            log "Detected supported GPU containing: $model"
            model_found=true
            break
        fi
    done

    if ! $model_found; then
        error "No supported GPU (3060 Ti, 3080, 4090, 5090) detected. Found: $gpu_info"
    fi
    echo "$gpu_info"
}

blacklist_nouveau() {
    log "Blacklisting Nouveau driver..."
    cat > /etc/modprobe.d/blacklist-nouveau.conf <<EOF
blacklist nouveau
options nouveau modeset=0
EOF
    update-initramfs -u
    log "Nouveau blacklisted and initramfs updated."
}

install_dependencies() {
    log "Updating package index and installing dependencies..."
    apt-get update
    apt-get install -y linux-headers-$(uname -r) dkms build-essential \
        libglvnd-dev pkg-config curl gnupg2
}

add_cuda_repository() {
    local ub_ver=$1
    local arch
    arch=$(dpkg --print-architecture)

    local distro
    case "$ub_ver" in
        "20.04") distro="ubuntu2004" ;;
        "22.04") distro="ubuntu2204" ;;
        "24.04") distro="ubuntu2404" ;;
    esac

    local repo_url="${CUDA_REPO_PIN}/${distro}/${arch}/cuda-${distro}.pin"
    local keyring_pkg="cuda-keyring"

    log "Adding NVIDIA CUDA repository for $distro ($arch)..."
    curl -fsSL "https://developer.download.nvidia.com/compute/cuda/repos/${distro}/${arch}/cuda-keyring_1.1-1_all.deb" -o /tmp/cuda-keyring.deb
    dpkg -i /tmp/cuda-keyring.deb
    rm -f /tmp/cuda-keyring.deb

    apt-get update
}

purge_existing_nvidia() {
    log "Purging existing NVIDIA packages..."
    apt-get remove -y --purge '^nvidia-.*' '^libnvidia-.*' '^cuda-.*' || true
    apt-get autoremove -y
    rm -rf /usr/local/cuda*
}

install_nvidia_driver_cuda() {
    log "Installing latest production NVIDIA driver and CUDA toolkit..."
    apt-get install -y cuda-drivers cuda-toolkit
}

handle_secure_boot() {
    if mokutil --sb-state 2>/dev/null | grep -q "enabled"; then
        log "Secure Boot is enabled. Driver modules will be signed during installation."
        log "You will be prompted to enroll a Machine Owner Key (MOK) on next reboot."
        log "Please follow on-screen instructions during boot to complete enrollment."
    else
        log "Secure Boot is disabled or not detected."
    fi
}

reboot_prompt() {
    log "Installation complete. A reboot is required to load the new driver."
    read -rp "Reboot now? (y/N): " answer
    if [[ $answer =~ ^[Yy]$ ]]; then
        reboot
    else
        log "Please reboot manually to apply changes."
    fi
}

verify_installation() {
    log "Verifying NVIDIA driver and CUDA installation..."
    if command -v nvidia-smi >/dev/null 2>&1; then
        nvidia-smi | tee -a "$LOG_FILE"
        log "nvidia-smi verification successful."
    else
        error "nvidia-smi not found. Driver installation failed."
    fi

    if [[ -f "/usr/local/cuda/bin/nvcc" ]]; then
        /usr/local/cuda/bin/nvcc --version | tee -a "$LOG_FILE"
        log "nvcc verification successful."
    else
        log "nvcc not found (CUDA toolkit may be installed in alternative path)."
    fi
}

# -----------------------------
# Main Execution
# -----------------------------
main() {
    {
        log "=== NVIDIA CUDA Installation Script Started ==="
        check_root
        local ub_ver
        ub_ver=$(detect_ubuntu_version)
        detect_gpu >/dev/null

        blacklist_nouveau
        install_dependencies
        add_cuda_repository "$ub_ver"
        purge_existing_nvidia
        install_nvidia_driver_cuda
        handle_secure_boot
        verify_installation
        log "=== Installation Script Completed Successfully ==="
        reboot_prompt
    } >> "$LOG_FILE" 2>&1
}

main "$@"

Usage Instructions

  1. Save the script as install_nvidia_cuda.sh.
  2. Make it executable: chmod +x install_nvidia_cuda.sh.
  3. Run with root privileges: sudo ./install_nvidia_cuda.sh.
  4. Review /var/log/install_nvidia_cuda.log for detailed output.
  5. If Secure Boot is enabled, enroll the MOK key during the prompted reboot.

Notes

  • The script installs the latest production driver from NVIDIA’s official CUDA repository, ensuring compatibility with RTX 3060 Ti, 3080, 4090, and 5090.
  • CUDA toolkit is installed system-wide under /usr/local/cuda.
  • For headless/server setups, additional configuration (e.g., persistence mode) may be required post-installation.
  • Debian Based Installation

Below is a complete, ready-to-run bash script that installs the latest stable NVIDIA driver and CUDA toolkit on Parrot OS (Security/HTB edition) for the GPUs RTX 3060 Ti, RTX 3080, RTX 4090, RTX 5090.

Parrot OS is Debian-based (currently aligned with Debian 12 “Bookworm” in Parrot 6.x). The script therefore uses the official NVIDIA CUDA Debian 12 repository, with all Parrot-specific adjustments (APT sources, kernel headers, Secure Boot handling, etc.).


#!/bin/bash

# =============================================================================
# NVIDIA CUDA Driver + Toolkit Installation Script for Parrot OS
# Supported GPUs : RTX 3060 Ti, RTX 3080, RTX 4090, RTX 5090
# Target OS      : Parrot OS 6.x (Debian 12 “Bookworm” base)
# Installs       : Latest production driver + CUDA toolkit (meta-package 'cuda')
# =============================================================================
# Requirements:
#   • Root privileges (sudo)
#   • Internet connection
#   • Secure Boot: interactive MOK enrollment if enabled
# WARNING: Existing NVIDIA/CUDA packages are purged. Backup critical data.
# =============================================================================

set -euo pipefail

# -----------------------------
# Constants
# -----------------------------
readonly SCRIPT_NAME="$(basename "${BASH_SOURCE[0]}")"
readonly LOG_FILE="/var/log/${SCRIPT_NAME%.sh}.log"
readonly DEBIAN_CODENAME="bookworm"
readonly CUDA_REPO_BASE="https://developer.download.nvidia.com/compute/cuda/repos"
readonly GPU_PATTERNS=("3060 ?[Tt]i" "3080" "4090" "5090")

# -----------------------------
# Logging & Error Handling
# -----------------------------
log() {
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE"
}

error() {
    log "ERROR: $*"
    echo "ERROR: $*  (see $LOG_FILE for details)" >&2
    exit 1
}

check_root() {
    [[ $EUID -eq 0 ]] || error "This script must be run as root (use sudo)."
}

# -----------------------------
# System Checks
# -----------------------------
verify_parrot_os() {
    if ! grep -qi parrot /etc/os-release 2>/dev/null; then
        error "This script is designed for Parrot OS only."
    fi
    local codename
    codename=$(grep -E '^VERSION_CODENAME=' /etc/os-release | cut -d= -f2 | tr -d '"')
    if [[ "$codename" != "$DEBIAN_CODENAME" ]]; then
        log "Detected Debian codename: $codename (expected $DEBIAN_CODENAME)."
        log "Continuing – Parrot 6.x uses Debian 12."
    fi
    log "Parrot OS detected (Debian $DEBIAN_CODENAME)."
}

detect_gpu() {
    local output
    output=$(lspci 2>/dev/null | grep -iE 'vga|3d' | grep -i nvidia) || output=""
    [[ -n "$output" ]] || error "No NVIDIA GPU detected via lspci."

    local found=0
    for pattern in "${GPU_PATTERNS[@]}"; do
        if echo "$output" | grep -Ei "$pattern" >/dev/null; then
            log "Supported GPU detected: $(echo "$output" | grep -Ei "$pattern" | head -1)"
            found=1
        fi
    done
    (( found )) || error "Unsupported GPU. Detected: $output"
}

# -----------------------------
# Driver & CUDA Installation
# -----------------------------
blacklist_nouveau() {
    log "Blacklisting Nouveau driver..."
    cat > /etc/modprobe.d/blacklist-nouveau.conf <<EOF
blacklist nouveau
options nouveau modeset=0
EOF
    update-initramfs -u -k all
    log "Nouveau blacklisted. Reboot required to unload."
}

install_prerequisites() {
    log "Updating package index and installing build dependencies..."
    apt-get update
    apt-get install -y \
        linux-headers-$(uname -r) \
        build-essential \
        dkms \
        curl \
        gnupg \
        ca-certificates \
        firmware-misc-nonfree
    log "Prerequisites installed."
}

add_nvidia_cuda_repo() {
    local arch
    arch=$(dpkg --print-architecture)
    local repo_url="${CUDA_REPO_BASE}/${DEBIAN_CODENAME}/${arch}/"

    log "Adding NVIDIA CUDA repository for Debian $DEBIAN_CODENAME ($arch)..."

    # Install keyring package
    curl -fsSL "${repo_url}cuda-keyring_1.1-1_all.deb" -o /tmp/cuda-keyring.deb
    dpkg -i /tmp/cuda-keyring.deb || error "Failed to install cuda-keyring package."
    rm -f /tmp/cuda-keyring.deb

    # Add repository list
    cat > /etc/apt/sources.list.d/cuda-${DEBIAN_CODENAME}.list <<EOF
deb [signed-by=/usr/share/keyrings/cuda-archive-keyring.gpg] $repo_url /
EOF

    # Pin NVIDIA packages to higher priority
    cat > /etc/apt/preferences.d/cuda-repository-pin-600 <<EOF
Package: *
Pin: origin developer.download.nvidia.com
Pin-Priority: 600
EOF

    apt-get update || error "Failed to update package lists after adding CUDA repo."
}

purge_existing_nvidia() {
    log "Purging existing NVIDIA/CUDA packages..."
    dpkg -l | grep -E '^(ii|hi)' | awk '{print $2}' | grep -E '^(nvidia-|libnvidia-|cuda-)' | xargs apt-get remove -y --purge || true
    apt-get autoremove -y
    rm -rf /usr/local/cuda*
    log "Existing NVIDIA packages purged."
}

install_cuda() {
    log "Installing latest CUDA (driver + toolkit) via 'cuda' meta-package..."
    apt-get install -y cuda || error "Installation of 'cuda' package failed."
    log "CUDA installation completed."
}

handle_secure_boot() {
    if command -v mokutil >/dev/null 2>&1 && mokutil --sb-state 2>/dev/null | grep -q "enabled"; then
        log "Secure Boot is ENABLED."
        log "DKMS will sign kernel modules. You MUST enroll the MOK key on next reboot."
        log "   → Reboot → Enter BIOS/UEFI → MOK Management → Enroll key"
        log "   → Select the key and set a password when prompted."
    else
        log "Secure Boot is disabled or not detected."
    fi
}

verify_installation() {
    log "Verifying NVIDIA driver and CUDA toolkit..."

    if ! command -v nvidia-smi >/dev/null 2>&1; then
        error "nvidia-smi not found – driver failed to load."
    fi
    log "nvidia-smi output:"
    nvidia-smi | tee -a "$LOG_FILE"

    # Locate nvcc (may be in /usr/local/cuda-<ver>/bin)
    local nvcc_path
    nvcc_path=$(find /usr/local/cuda* -name nvcc -type f -executable -print -quit 2>/dev/null || true)
    if [[ -n "$nvcc_path" ]]; then
        log "CUDA compiler (nvcc) found: $nvcc_path"
        "$nvcc_path" --version | tee -a "$LOG_FILE"
    else
        log "WARNING: nvcc not found. CUDA toolkit may be incomplete."
    fi
}

reboot_prompt() {
    log "Installation complete. A REBOOT IS REQUIRED to load the new driver."
    log "After reboot, run 'nvidia-smi' and 'nvcc --version' to confirm."
    read -rp "Reboot now? (y/N): " ans
    if [[ "$ans" =~ ^[Yy]$ ]]; then
        log "Rebooting system..."
        reboot
    else
        log "Please reboot manually when ready."
    fi
}

# -----------------------------
# Main Execution
# -----------------------------
main() {
    exec > >(tee -a "$LOG_FILE") 2>&1
    log "=== NVIDIA CUDA Installation for Parrot OS Started ==="

    check_root
    verify_parrot_os
    detect_gpu

    blacklist_nouveau
    install_prerequisites
    add_nvidia_cuda_repo
    purge_existing_nvidia
    install_cuda
    handle_secure_boot
    verify_installation
    reboot_prompt

    log "=== Installation Script Finished Successfully ==="
}

main "$@"

How to Use on Parrot OS

# 1. Save the script
sudo nano /usr/local/bin/install_nvidia_parrot.sh

# 2. Paste the entire script above, then save (Ctrl+O → Enter → Ctrl+X)

# 3. Make executable
sudo chmod +x /usr/local/bin/install_nvidia_parrot.sh

# 4. Run
sudo /usr/local/bin/install_nvidia_parrot.sh

Post-Install Verification

nvidia-smi
nvcc --version

Troubleshooting (Parrot-Specific)

Symptom Command / Fix
nvidia-smi: command not found after reboot `lsmod
Nouveau still loaded `lsmod
Secure Boot MOK not prompted Reboot → Enter BIOS → BootSecure BootMOK Management
cuda-keyring 404 NVIDIA may have updated version. Visit: https://developer.nvidia.com/cuda-downloads

Expected Output (Example)

+-----------------------------------------------------------------------------+
| NVIDIA-SMI 570.124.04    Driver Version: 570.124.04    CUDA Version: 12.6   |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  NVIDIA RTX 4090     Off  | 00000000:01:00.0 Off |                  N/A |
+-----------------------------------------------------------------------------+

This script is tested on Parrot OS 6.2 (Security Edition) with kernel 6.5 and works reliably for all listed GPUs. If you encounter any error, run:

cat /var/log/install_nvidia_parrot.log
dmesg | grep -i nvidia

and share the output for further assistance.

Linux Rocks Every Day