Autoinstall lays down a thin base (sshd, key, DHCP, Docker CE, /srv) and hands
off to this repo on first boot. Everything interesting stays in git so it is
reviewable and re-runnable, rather than frozen onto a USB nobody can diff.
Stages, all idempotent:
00-preflight asserts hardware/BIOS state, changes nothing. Catches a BIOS
update having silently re-enabled Secure Boot, which would stop
the NVIDIA DKMS module loading on a box with no keyboard.
10-secrets ADD-ONLY seeder for /srv/secrets/stacks.env. Never overwrites an
existing key. Verified against a pre-populated file: existing
values, unrelated keys, the operator tier and existing manifest
lines all survive byte-for-byte; a second run is a no-op.
20-cifs the 8 shares Plex actually uses (Share is excluded, it is not a
library root). \040 escaping, nofail + x-systemd.automount +
_netdev. Managed-block rewrite verified not to duplicate or to
drop the root fstab entry.
30-nvidia nvidia-driver-580 explicitly: 580 is the LAST branch supporting
Pascal, and the -open modules need Turing+. Pins against newer
branches. Not in late-commands because DKMS needs the installed
kernel, not the installer's.
40-shell-mcp builds the native MCP locally for amd64; refuses to finish
unless /sse returns 401 without a token.
50-plex run by hand: PLEX_CLAIM expires in 4 minutes. Refuses to start
against missing mounts and disables autoEmptyTrash, which with
read-write NAS credentials is the most dangerous default here.
shell-mcp was built on arm64 originally. It builds clean on amd64 (whole dep
tree resolves to prebuilt manylinux x86_64 wheels, no compiler needed), but
dependencies are now pinned - the original installed mcp/starlette/uvicorn
unpinned and starlette has since gone 1.x. Port moved to 8103 so NPM host 42
can simply be repointed, and the tool description now says media box rather
than arrsstack.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
92 lines
4.0 KiB
Bash
Executable File
92 lines
4.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# =============================================================================
|
|
# 30-nvidia — NVIDIA driver + container toolkit for the GTX 1070
|
|
#
|
|
# WHY THIS IS NOT IN late-commands:
|
|
# The driver is a DKMS module. It must build against the kernel that is
|
|
# actually running on the installed system, with that kernel's headers, on a
|
|
# real boot. Building it inside the installer environment produces a module
|
|
# for the installer's kernel, which is not the kernel that boots.
|
|
#
|
|
# DRIVER BRANCH — this is the part that will bite later:
|
|
# The GTX 1070 is Pascal. NVIDIA's 580 branch is the LAST branch that supports
|
|
# Maxwell, Pascal and Volta; it is now a frozen legacy branch receiving
|
|
# security fixes only. There will be no 590 for this card. Two consequences:
|
|
# 1. We install nvidia-driver-580 explicitly. Never `ubuntu-drivers autoinstall`,
|
|
# which will happily pick a newer branch that does not support the card.
|
|
# 2. We install the PROPRIETARY module, not `-open`. The open kernel modules
|
|
# require Turing or newer. On Pascal they will not load at all.
|
|
#
|
|
# Secure Boot must be OFF (verified 2026-07-27). With it on, the DKMS module is
|
|
# unsigned as far as the firmware is concerned and requires interactive MOK
|
|
# enrollment at a physical console — on a box with no keyboard.
|
|
#
|
|
# Plex is targeted at Quick Sync, not NVENC, so this stage failing does NOT
|
|
# block Plex. It fails soft.
|
|
# =============================================================================
|
|
set -uo pipefail
|
|
|
|
DRIVER_BRANCH=580
|
|
|
|
if ! lspci -nn | grep -qi nvidia; then
|
|
echo " no NVIDIA device on the PCI bus — skipping"
|
|
exit 0
|
|
fi
|
|
|
|
if command -v nvidia-smi >/dev/null 2>&1 && nvidia-smi >/dev/null 2>&1; then
|
|
echo " driver already working:"
|
|
nvidia-smi --query-gpu=name,driver_version --format=csv,noheader | sed 's/^/ /'
|
|
else
|
|
echo " installing nvidia-driver-${DRIVER_BRANCH} (proprietary; Pascal cannot use -open)"
|
|
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
apt-get update -qq
|
|
|
|
# Explicit branch, explicit proprietary flavour. No ubuntu-drivers autoinstall.
|
|
if ! apt-get install -y \
|
|
"nvidia-driver-${DRIVER_BRANCH}" \
|
|
"nvidia-utils-${DRIVER_BRANCH}" \
|
|
"linux-headers-$(uname -r)" \
|
|
dkms; then
|
|
echo " [FAIL] driver install failed — Plex/Quick Sync is unaffected, fix later"
|
|
exit 1
|
|
fi
|
|
|
|
# Persistence mode avoids a multi-second GPU init on every container start.
|
|
systemctl enable --now nvidia-persistenced 2>/dev/null || true
|
|
echo " driver installed — a REBOOT is required before nvidia-smi will work"
|
|
fi
|
|
|
|
# --- NVIDIA Container Toolkit ------------------------------------------------
|
|
if [ -f /etc/apt/sources.list.d/nvidia-container-toolkit.list ] \
|
|
&& command -v nvidia-ctk >/dev/null 2>&1; then
|
|
echo " container toolkit already present"
|
|
else
|
|
echo " installing NVIDIA container toolkit"
|
|
install -m 0755 -d /usr/share/keyrings
|
|
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \
|
|
| gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
|
|
curl -fsSL https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list \
|
|
| sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' \
|
|
> /etc/apt/sources.list.d/nvidia-container-toolkit.list
|
|
apt-get update -qq
|
|
apt-get install -y nvidia-container-toolkit || {
|
|
echo " [FAIL] container toolkit install failed"; exit 1; }
|
|
|
|
nvidia-ctk runtime configure --runtime=docker
|
|
systemctl restart docker
|
|
fi
|
|
|
|
# --- guard rail --------------------------------------------------------------
|
|
# If a newer driver branch is ever pulled in, it will silently drop this card.
|
|
cat > /etc/apt/preferences.d/nvidia-pascal.pref <<EOF
|
|
# The GTX 1070 is Pascal. Branch ${DRIVER_BRANCH} is the last one that supports it.
|
|
# Anything newer will install cleanly and then fail to drive the card.
|
|
Package: nvidia-driver-6* nvidia-driver-59*
|
|
Pin: release *
|
|
Pin-Priority: -1
|
|
EOF
|
|
|
|
echo " pinned against post-${DRIVER_BRANCH} branches (Pascal EOL guard)"
|
|
exit 0
|