Skip to content

Instantly share code, notes, and snippets.

@tmasjc
Last active February 3, 2026 02:07
Show Gist options
  • Select an option

  • Save tmasjc/1065706f784850d9ec2ce540249ac6c7 to your computer and use it in GitHub Desktop.

Select an option

Save tmasjc/1065706f784850d9ec2ce540249ac6c7 to your computer and use it in GitHub Desktop.
compute server setup
#!/usr/bin/env bash
set -euo pipefail
# Ubuntu bootstrap: base tools + Docker + Python (deadsnakes) + optional GPU utils + Ollama
# Usage:
# ./bootstrap.sh
# ./bootstrap.sh --with-nvidia --nvidia-version 535
# ./bootstrap.sh --with-amd
# ./bootstrap.sh --no-snap
# ./bootstrap.sh --no-ollama
# ./bootstrap.sh --python 3.11
#
# Notes:
# - Docker group change requires logout/login (or: newgrp docker) to take effect.
# - Script is idempotent: safe to re-run.
WITH_NVIDIA=0
WITH_AMD=0
NO_SNAP=0
NO_OLLAMA=0
PY_VER="3.11"
NVIDIA_VER="535"
log() { printf "\n==> %s\n" "$*"; }
have_cmd() { command -v "$1" >/dev/null 2>&1; }
apt_install() {
# Install only packages that aren't already installed (reduces noise + speeds reruns)
local pkgs=("$@")
local missing=()
for p in "${pkgs[@]}"; do
dpkg -s "$p" >/dev/null 2>&1 || missing+=("$p")
done
if ((${#missing[@]})); then
sudo apt-get install -y "${missing[@]}"
fi
}
ensure_snap() {
if (( NO_SNAP )); then
log "Skipping snap (per --no-snap)"
return 0
fi
if ! have_cmd snap; then
log "Installing snapd"
sudo apt-get update -y
apt_install snapd
fi
}
snap_install_if_missing() {
local name="$1"
if (( NO_SNAP )); then return 0; fi
if ! snap list 2>/dev/null | awk '{print $1}' | grep -qx "$name"; then
sudo snap install "$name"
fi
}
add_docker_repo() {
log "Setting up Docker APT repo"
apt_install ca-certificates gnupg
sudo install -m 0755 -d /etc/apt/keyrings
if [[ ! -f /etc/apt/keyrings/docker.gpg ]]; then
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
fi
local codename
codename="$(. /etc/os-release && echo "${VERSION_CODENAME}")"
local arch
arch="$(dpkg --print-architecture)"
local listfile="/etc/apt/sources.list.d/docker.list"
local line="deb [arch=${arch} signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu ${codename} stable"
if [[ ! -f "$listfile" ]] || ! grep -qxF "$line" "$listfile"; then
echo "$line" | sudo tee "$listfile" >/dev/null
fi
sudo apt-get update -y
}
install_docker() {
log "Installing Docker Engine"
add_docker_repo
apt_install docker-ce docker-ce-cli containerd.io
# Ensure service is enabled/started (no error if already running)
sudo systemctl enable --now docker >/dev/null 2>&1 || true
# Add current user to docker group
if id -nG "$USER" | tr ' ' '\n' | grep -qx docker; then
:
else
sudo usermod -aG docker "$USER"
fi
}
install_base_tools() {
log "Updating system + installing base tools"
sudo apt-get update -y
sudo apt-get upgrade -y
apt_install \
curl wget git vim htop unzip net-tools \
build-essential software-properties-common \
tmux tree fd-find ripgrep
}
install_python() {
log "Installing Python (system + deadsnakes ${PY_VER})"
apt_install python3 python3-pip python3-venv
# Add deadsnakes PPA once
if [[ ! -f /etc/apt/sources.list.d/deadsnakes-ubuntu-ppa*.list ]] && \
! grep -Rqs "^deb .\+deadsnakes/ppa" /etc/apt/sources.list /etc/apt/sources.list.d/*; then
sudo add-apt-repository -y ppa:deadsnakes/ppa
sudo apt-get update -y
fi
apt_install "python${PY_VER}" "python${PY_VER}-venv" "python${PY_VER}-dev"
}
install_gpu_utils() {
if (( WITH_NVIDIA )); then
log "Installing NVIDIA utilities (nvidia-utils-${NVIDIA_VER})"
apt_install "nvidia-utils-${NVIDIA_VER}"
fi
if (( WITH_AMD )); then
log "Installing AMD ROCm SMI (rocm-smi)"
apt_install rocm-smi
fi
}
install_ollama() {
if (( NO_OLLAMA )); then
log "Skipping Ollama (per --no-ollama)"
return 0
fi
if have_cmd ollama; then
log "Ollama already installed"
return 0
fi
log "Installing Ollama"
curl -fsSL https://ollama.com/install.sh | sh
}
usage() {
cat <<'EOF'
bootstrap.sh [options]
Options:
--with-nvidia Install nvidia-utils (default off)
--nvidia-version N NVIDIA utils version (default: 535)
--with-amd Install rocm-smi (default off)
--python X.Y Install Python X.Y from deadsnakes (default: 3.11)
--no-snap Skip snap and btop installation
--no-ollama Skip Ollama installation
-h, --help Show help
EOF
}
while [[ $# -gt 0 ]]; do
case "$1" in
--with-nvidia) WITH_NVIDIA=1; shift ;;
--nvidia-version) NVIDIA_VER="${2:?}"; shift 2 ;;
--with-amd) WITH_AMD=1; shift ;;
--python) PY_VER="${2:?}"; shift 2 ;;
--no-snap) NO_SNAP=1; shift ;;
--no-ollama) NO_OLLAMA=1; shift ;;
-h|--help) usage; exit 0 ;;
*) echo "Unknown option: $1"; usage; exit 1 ;;
esac
done
install_base_tools
# btop + dust via snap (optional)
ensure_snap
if (( ! NO_SNAP )); then
log "Installing btop (snap)"
snap_install_if_missing btop
log "Installing dust (snap)"
snap_install_if_missing dust
fi
install_docker
install_python
install_gpu_utils
install_ollama
log "Done."
echo "If you were added to the docker group, run: newgrp docker (or logout/login) before using 'docker' without sudo."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment