This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Personal machine setup scripts for macOS, Linux servers, and Proxmox VMs. Scripts are numbered by phase so you know what to run and in what order.
All scripts source .env from $HOME/.env (canonical, single source of
truth). The repo-root .env is a symlink to $HOME/.env so docker-compose
env_file: directives keep working transparently. Scripts also fall back to
$REPO_ROOT/.env if $HOME/.env is missing.
cp .env.example ~/.env
chmod 600 ~/.env
ln -sf ~/.env "$(dirname $(realpath .))/.env" # back-compat symlink for docker-compose
# Required: SETUP_USER, SETUP_HOST, DOTFILES_REPO, GH_TOKEN, SSH_PUBLIC_KEY,
# RAGFLOW_API_KEY, LLAMACPP_*, etc. — see .env.exampleOnboarding is split from software setup:
bootstrap/— one-time onboarding for a fresh host, run from your local machine over SSH.local/generates and uploads your SSH key;server/createsSETUP_USER, grants passwordless sudo, and hardens sshd. Seebootstrap/README.mdfor run order. UseSSH_USER=rootfor a brand-new server.- Platform dirs — software setup for an already-accessible host, run on the
machine itself:
ubuntu/(Debian/Ubuntu/Mint desktop or server),fedora/, andmac/. Each has the same01_basics.sh→02_shell.sh→03_dotfiles.shphases.ubuntu/01_basics.shis a superset (packages + Docker + most optional tools in one pass) and has a test pipeline.
The old linux/ collection was consolidated into bootstrap/ + ubuntu/ (commit
cadde35); it no longer exists.
# From your local machine — generate/upload key, create user, harden sshd.
# Use SSH_USER=root for a fresh server where SETUP_USER doesn't exist yet.
bash bootstrap/local/01_keygen.sh && bash bootstrap/local/02_key_upload.sh && bash bootstrap/local/03_key_test.sh
SSH_USER=root bash bootstrap/server/04_adduser.sh && SSH_USER=root bash bootstrap/server/05_sudoers.sh
bash bootstrap/server/06_sshd_harden.sh
# Then SSH into the host as your user and run the platform scripts:
bash ubuntu/01_basics.sh && bash ubuntu/02_shell.sh && bash ubuntu/03_dotfiles.sh
exec zsh && p10k configurebash ubuntu/01_basics.sh # packages + Docker + most optional tools
bash ubuntu/02_shell.sh # oh-my-zsh + powerlevel10k + plugins
bash ubuntu/03_dotfiles.sh # chezmoi dotfiles + tpm
exec zshbash mac/01_basics.sh && bash mac/02_shell.sh && bash mac/03_dotfiles.sh
exec zsh && p10k configurebash ubuntu/10_containers.sh # ctop, dive, lazydocker, k9s, kubectl, helm, k3d, kind, minikube
bash ubuntu/20_gui.sh # flatpak, ghostty, Obsidian, Discord, WezTerm, Chrome, Firefox
bash tools/10_claude_agents.sh --start # persistent Claude tmux sessions (backup copy — see below)Test the ubuntu pipeline in an isolated environment:
# Auto-detect backend (Docker preferred; quickemu if /dev/kvm available)
bash ubuntu/test_pipeline.sh
# Force Docker
bash ubuntu/test_pipeline.sh --backend docker
# Include dotfiles phase (requires GH_TOKEN in .env)
bash ubuntu/test_pipeline.sh --with-dotfiles
# Leave container running to inspect
bash ubuntu/test_pipeline.sh --keep
# Destroy previous environment first
bash ubuntu/test_pipeline.sh --cleanLogs are written to ~/.pipeline-test/logs/.
Version resolution: All tool versions are resolved at runtime via the GitHub API — no hardcoded versions. The gh_api() helper in ubuntu/01_basics.sh uses gh auth token when available to avoid rate limits.
Idempotency: Every tool install is guarded with command -v <tool> &>/dev/null || install. Scripts are safe to re-run; 02_shell.sh explicitly skips already-installed components.
Error handling: set -euo pipefail at the top, but optional/external downloads use soft-fail (log_error function + continue) so one failed download doesn't abort the whole script.
Install locations: User-level tools go to ~/.local/bin; system tools requiring sudo go to /usr/local/bin.
Ubuntu quirks handled by scripts:
batis installed asbatcat→ symlinked to~/.local/bin/batlibfuse2renamed tolibfuse2t64in Ubuntu 22.10+ (auto-detected)- Ghostty terminfo installed in
02_shell.shto prevent SSH character repeat bugs
tools/10_claude_agents.sh is a backup copy. The canonical version lives at ~/work/agentic-toolkit-private/scripts/agents.sh. Edits here are not picked up by the nightly cron. It manages a claude tmux session with windows: ozzie (WhatsApp bot), top (crowd dashboard), kora (remote-control agent).
Self-contained stack lives at llamacpp/ (top-level, mirrors ragflow/):
single llama-swap container that fronts per-model llama-server processes
on the AMD Radeon 890M iGPU via Vulkan/RADV. Replaces Ollama as RagFlow's
chat/embed backend (~4× faster prompt-eval on Qwen3-30B-A3B; verified bench
in memory project_f3a_llm_stack.md).
- Run:
bash ubuntu/52_llamacpp_vulkan.sh(thin launcher; also builds the native~/llama.cppfor ad-hoc benching). - Endpoint:
http://192.168.1.13:8080(OpenAI-compatible /v1). - Models in container:
qwen3-30b-a3b-q4_K_M(chat),bge-m3(embedding). - VLM (
qwen3-vl:8b) stays on Ollama for now — itsmmprojpackaging in llama-server needs a separate migration step. - Ollama remains as a backup chat/embed provider; do not decommission until the llama.cpp stack has run RagFlow's full RTCU dataset end-to-end.
Self-contained stack lives at ragflow/ (top-level, mirrors proxmox/):
pinned infiniflow/ragflow:v0.25.1 Docker image, custom entrypoint, and
a Python init script that auto-creates one admin user, persists a stable
RAGFLOW_API_KEY, and registers Ollama as the LLM provider on first boot.
- Run from F3A:
bash ubuntu/53_ragflow.sh(thin launcher). - Variables read from
$HOME/.env(see.env.examplefor the full list). - Reset state:
cd ragflow && docker compose down -v. - Inspired by
~/work/ragflow-docker(multi-instance Bosch deployment) but trimmed for single-user, Ollama-only, private-LAN deployment. No UFW outbound block — F3A is on a private LAN.
Proxmox uses the same canonical ~/.env (with PROXMOX_* keys).
./proxmox/provision.sh --dry-run proxmox/vms/<name>.yaml
./proxmox/provision.sh proxmox/vms/<name>.yamlSee proxmox/README.md for full documentation.