Add Docker/Compose always-check and SSH key import to AI stack setup
- Docker + Docker Compose check now runs on every invocation (not skipped on updates), installing if missing — ensures the stack can always run - Added Docker Compose plugin install as fallback if compose is missing - NVIDIA Container Toolkit check also always runs (not update-gated) - Added SSH key import wizard question: import public keys from GitHub (gh:username) and/or Launchpad (lp:username) using ssh-import-id, so the machine is accessible over SSH immediately after setup https://claude.ai/code/session_012gDnantBmFTWZGCiKyjazx
This commit is contained in:
+67
-29
@@ -137,13 +137,31 @@ fi
|
||||
$INSTALL_AI || $INSTALL_KIWIX || $INSTALL_POSTINSTALL \
|
||||
|| die "Nothing selected — run again and select at least one option."
|
||||
|
||||
# ── Q1b: SSH keys from GitHub / Launchpad ─────────────────────────────────────
|
||||
SSH_IMPORT_IDS=() # list of "gh:username" or "lp:username" entries
|
||||
|
||||
if ! $IS_UPDATE || [[ ! -f "$HOME/.ssh/authorized_keys" ]]; then
|
||||
echo ""
|
||||
echo -e " ${BOLD}[SSH] Import SSH public keys? (for passwordless SSH into this machine)${NC}"
|
||||
echo " Pulls your public keys from GitHub or Launchpad and adds them to"
|
||||
echo " ~/.ssh/authorized_keys using ssh-import-id."
|
||||
echo ""
|
||||
echo " Examples: gh:yourusername lp:yourlaunchpadid"
|
||||
echo " Multiple: gh:alice lp:alice"
|
||||
echo ""
|
||||
read -rp " Usernames (or Enter to skip): " SSH_INPUT
|
||||
if [[ -n "$SSH_INPUT" ]]; then
|
||||
read -ra SSH_IMPORT_IDS <<< "$SSH_INPUT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# ── Q2: Storage for Ollama models ─────────────────────────────────────────────
|
||||
OLLAMA_STORAGE="volume" # "volume" = Docker named volume, else a host path
|
||||
OLLAMA_HOST_PATH=""
|
||||
|
||||
if $INSTALL_AI; then
|
||||
echo ""
|
||||
echo -e " ${BOLD}[2/5] Where should Ollama models be stored?${NC}"
|
||||
echo -e " ${BOLD}[2/6] Where should Ollama models be stored?${NC}"
|
||||
echo " (Models are large — 5-50GB each. A fast SSD or large HDD is ideal.)"
|
||||
echo ""
|
||||
echo " Available mount points with >20GB free:"
|
||||
@@ -172,7 +190,7 @@ KIWIX_DIR="$BASE/kiwix" # default
|
||||
|
||||
if $INSTALL_KIWIX; then
|
||||
echo ""
|
||||
echo -e " ${BOLD}[3/5] Where should Kiwix ZIM files be stored?${NC}"
|
||||
echo -e " ${BOLD}[3/6] Where should Kiwix ZIM files be stored?${NC}"
|
||||
echo " (ZIMs are large — Wikipedia alone is ~46GB. Total collection ~130GB.)"
|
||||
echo ""
|
||||
echo " Available mount points with >50GB free:"
|
||||
@@ -191,7 +209,7 @@ if $INSTALL_KIWIX; then
|
||||
|
||||
# ── Q4: Download ZIMs now? ─────────────────────────────────────────────────
|
||||
echo ""
|
||||
echo -e " ${BOLD}[4/5] Download ZIM files? (offline Wikipedia, Stack Overflow, etc.)${NC}"
|
||||
echo -e " ${BOLD}[4/6] Download ZIM files? (offline Wikipedia, Stack Overflow, etc.)${NC}"
|
||||
echo " Downloads run in the background — safe to start now and leave overnight."
|
||||
echo " Total: ~130GB (Wikipedia 46GB, Project Gutenberg 60GB, others smaller)"
|
||||
echo ""
|
||||
@@ -211,7 +229,7 @@ if command -v ufw &>/dev/null && { [[ ! -f "$BASE/.ufw-done" ]] || $FORCE; }; th
|
||||
echo ""
|
||||
# Auto-detect likely subnet from current IP
|
||||
AUTO_SUBNET=$(echo "$LOCAL_IP" | awk -F. '{print $1"."$2"."$3".0/24"}')
|
||||
echo -e " ${BOLD}[4b] Firewall — allow LAN access to services${NC}"
|
||||
echo -e " ${BOLD}[4b/6] Firewall — allow LAN access to services${NC}"
|
||||
read -rp " LAN subnet [${AUTO_SUBNET}]: " LAN_INPUT
|
||||
LAN_SUBNET="${LAN_INPUT:-$AUTO_SUBNET}"
|
||||
[[ "$LAN_SUBNET" =~ /[0-9]+$ ]] || LAN_SUBNET="${LAN_SUBNET}/24"
|
||||
@@ -223,7 +241,7 @@ PULL_DEEPSEEK=false
|
||||
|
||||
if $INSTALL_AI; then
|
||||
echo ""
|
||||
echo -e " ${BOLD}[5/5] Download AI models now?${NC}"
|
||||
echo -e " ${BOLD}[5/6] Download AI models now?${NC}"
|
||||
echo " GPU detected: ${GPU_NAME} (${VRAM_GB}GB VRAM) → recommended tier: ${GPU_TIER}"
|
||||
echo ""
|
||||
echo " Models that will be downloaded:"
|
||||
@@ -248,6 +266,7 @@ echo -e "${BOLD}━━━━━━━━━━━━━━━━━━━━━
|
||||
echo ""
|
||||
$INSTALL_POSTINSTALL && echo " ✓ Full system setup (ubuntu-post-install.sh — interactive)"
|
||||
$INSTALL_AI && echo " ✓ AI stack (Ollama · WebUI · RAG · MCP · Gitea · InvokeAI · Portainer)"
|
||||
[[ "${#SSH_IMPORT_IDS[@]}" -gt 0 ]] && echo " ✓ SSH keys → ${SSH_IMPORT_IDS[*]}"
|
||||
$INSTALL_KIWIX && echo " ✓ Kiwix offline library"
|
||||
if $INSTALL_AI; then
|
||||
if [[ "$OLLAMA_STORAGE" == "bind" ]]; then
|
||||
@@ -297,21 +316,28 @@ fi
|
||||
# =============================================================================
|
||||
section "Prerequisites"
|
||||
# =============================================================================
|
||||
if ! $IS_UPDATE; then
|
||||
|
||||
# Docker
|
||||
if ! command -v docker &>/dev/null; then
|
||||
info "Installing Docker..."
|
||||
curl -fsSL https://get.docker.com | sh
|
||||
sudo usermod -aG docker "$USER"
|
||||
ok "Docker installed — log out/in or run: newgrp docker"
|
||||
else
|
||||
ok "Docker: $(docker --version)"
|
||||
fi
|
||||
# ── Docker (always check — required whether new install or update) ─────────────
|
||||
if ! command -v docker &>/dev/null; then
|
||||
info "Installing Docker..."
|
||||
curl -fsSL https://get.docker.com | sh
|
||||
sudo usermod -aG docker "$USER"
|
||||
warn "Added $USER to docker group — changes take effect on next login."
|
||||
warn "If docker commands fail, run: newgrp docker"
|
||||
else
|
||||
ok "Docker: $(docker --version | sed 's/Docker version //')"
|
||||
fi
|
||||
|
||||
# NVIDIA Container Toolkit
|
||||
if command -v nvidia-smi &>/dev/null && \
|
||||
! dpkg -l 2>/dev/null | grep -q nvidia-container-toolkit; then
|
||||
# Ensure Docker Compose plugin is present (included with modern Docker)
|
||||
if ! docker compose version &>/dev/null; then
|
||||
info "Installing docker-compose-plugin..."
|
||||
sudo apt-get install -y docker-compose-plugin
|
||||
fi
|
||||
ok "Docker Compose: $(docker compose version --short 2>/dev/null || echo 'ok')"
|
||||
|
||||
# ── NVIDIA Container Toolkit ───────────────────────────────────────────────────
|
||||
if command -v nvidia-smi &>/dev/null; then
|
||||
if ! dpkg -l 2>/dev/null | grep -q nvidia-container-toolkit; then
|
||||
info "Installing NVIDIA Container Toolkit..."
|
||||
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \
|
||||
| sudo gpg --dearmor --yes \
|
||||
@@ -324,20 +350,32 @@ if ! $IS_UPDATE; then
|
||||
sudo nvidia-ctk runtime configure --runtime=docker
|
||||
sudo systemctl restart docker
|
||||
ok "NVIDIA Container Toolkit installed"
|
||||
elif command -v nvidia-smi &>/dev/null; then
|
||||
ok "NVIDIA Container Toolkit already present"
|
||||
else
|
||||
warn "No NVIDIA GPU detected — CPU-only (Ollama will use CPU)"
|
||||
ok "NVIDIA Container Toolkit: already present"
|
||||
fi
|
||||
|
||||
# ripgrep (used by MCP search_code tool)
|
||||
if ! command -v rg &>/dev/null; then
|
||||
sudo apt-get install -y ripgrep
|
||||
ok "ripgrep installed"
|
||||
fi
|
||||
|
||||
else
|
||||
ok "Skipping prereq checks (update mode)"
|
||||
info "No NVIDIA GPU detected — Ollama will run on CPU"
|
||||
fi
|
||||
|
||||
# ── ripgrep (used by MCP search_code tool) ─────────────────────────────────────
|
||||
if ! command -v rg &>/dev/null; then
|
||||
sudo apt-get install -y ripgrep
|
||||
ok "ripgrep installed"
|
||||
fi
|
||||
|
||||
# ── SSH key import from GitHub / Launchpad ─────────────────────────────────────
|
||||
if [[ "${#SSH_IMPORT_IDS[@]}" -gt 0 ]]; then
|
||||
section "SSH Keys"
|
||||
if ! command -v ssh-import-id &>/dev/null; then
|
||||
info "Installing ssh-import-id..."
|
||||
sudo apt-get install -y ssh-import-id
|
||||
fi
|
||||
mkdir -p "$HOME/.ssh"
|
||||
chmod 700 "$HOME/.ssh"
|
||||
for id in "${SSH_IMPORT_IDS[@]}"; do
|
||||
info "Importing SSH keys: $id"
|
||||
ssh-import-id "$id" && ok "Keys imported: $id" || warn "Failed to import: $id"
|
||||
done
|
||||
fi
|
||||
|
||||
# =============================================================================
|
||||
|
||||
Reference in New Issue
Block a user