Zum Inhalt

Raspberry Pi 4 B – Dev-Workstation Setup

Hardware: Raspberry Pi 4 Model B, 4 GB RAM Gehäuse: Argon Case (konfiguriert via argon-config) Storage: USB-SSD (keine SD-Karte) Betrieb: Headless (SSH only) Netzwerk: UniFi (UDM Pro) Erstellt: Februar 2026


1. Betriebssystem

Raspberry Pi OS Lite (64-bit / Trixie)

Entscheidung für Pi OS Lite statt DietPi, weil bei SSD-Boot der RamLog-Vorteil von DietPi irrelevant ist und die maximale ARM64-Kompatibilität wichtiger ist als minimaler Footprint.

Installation

  1. Raspberry Pi Imager starten
  2. Choose Device → Raspberry Pi 4
  3. Choose OS → Raspberry Pi OS Lite (64-bit)
  4. Choose Storage → USB-SSD
  5. Settings (vor Write):
  6. SSH aktivieren
  7. Hostname setzen
  8. User + Passwort konfigurieren
  9. WLAN (optional)
  10. Locale: de_DE.UTF-8, Timezone: Europe/Berlin
  11. Write → SSD an blauen USB-3.0-Port → Boot

Erste Schritte nach Boot

sudo apt update && sudo apt upgrade -y
sudo raspi-config
# → Advanced Options → Expand Filesystem
sudo reboot

2. Headless-Optimierungen

Die Custom-Einträge für /boot/firmware/config.txt sind im Repo unter boot/config-additions.txt als Referenz dokumentiert.

GPU-Speicher reduzieren (60 MB mehr RAM)

sudo nano /boot/firmware/config.txt
# Einfügen:
gpu_mem=16

Bluetooth deaktivieren

# In /boot/firmware/config.txt einfügen:
dtoverlay=disable-bt
sudo systemctl disable hciuart bluetooth

Swap (zram)

zram ist auf Raspberry Pi OS standardmäßig aktiv und stellt 2 GB komprimierten Swap im RAM bereit. Bei 4 GB physischem RAM reicht das aus — kein zusätzlicher Swap-Partition oder Swap-File nötig.

# Status prüfen
swapon --show
zramctl

HDMI deaktivieren (optional, spart ~30 mA)

sudo nano /etc/rc.local
# Vor exit 0 einfügen:
/usr/bin/tvservice -o

3. Basis-Tools

sudo apt install -y \
  git curl wget htop jq tree \
  ripgrep fd-find shellcheck shfmt \
  tmux unzip build-essential \
  libssl-dev libffi-dev python3-dev \
  pkg-config cmake

# fd-find heißt auf Debian fdfind – Alias setzen
echo 'alias fd=fdfind' >> ~/.bashrc

Git-Konfiguration

Die Git-Config wird über das Repo verwaltet (git/gitconfig~/.gitconfig via bootstrap.sh).

# Nach bootstrap.sh: Prüfen
git config --global user.email
# → kontakt@robinwerner.de

4. Entwicklungsumgebungen

4.1 Node.js via nvm

# nvm installieren
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
source ~/.bashrc

# Node.js LTS installieren
nvm install --lts
nvm alias default lts/*

# Verifizieren
node -v && npm -v

Versionswechsel: nvm install 22 / nvm use 22

4.2 Python via uv

uv von Astral ersetzt pyenv, pip, virtualenv und pip-tools in einem Tool. Native ARM64-Unterstützung, extrem schnell (Rust-basiert).

# uv installieren
curl -LsSf https://astral.sh/uv/install.sh | sh
source ~/.bashrc

# Python installieren
uv python install 3.12 3.13

# Default Python im PATH
uv python install 3.13 --default

# Verifizieren
uv python list --only-installed

Versionswechsel: uv python pin 3.12 (pro Projekt via .python-version) Virtual Environments: uv venv / uv add <paket>

4.3 Go (manuell)

GO_VERSION=$(curl -s https://go.dev/VERSION?m=text | head -1)
wget "https://go.dev/dl/${GO_VERSION}.linux-arm64.tar.gz"
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf "${GO_VERSION}.linux-arm64.tar.gz"
rm "${GO_VERSION}.linux-arm64.tar.gz"

echo 'export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin' >> ~/.bashrc
source ~/.bashrc

go version

Update: Gleiche Schritte erneut ausführen.

4.4 Rust via rustup

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env

rustc --version

Versionswechsel: rustup default stable / rustup install nightly


5. Container Runtime: Podman

Podman statt Docker – kein Daemon, rootless-fähig, weniger RAM-Verbrauch, Docker-CLI-kompatibel.

# Podman + Tools installieren
sudo apt install -y podman podman-compose buildah skopeo

# Docker-CLI-Kompatibilität (alias docker=podman)
sudo apt install -y podman-docker

# Rootless-Support aktivieren
sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $USER
podman system migrate

# Verifizieren
podman --version
podman run --rm docker.io/library/hello-world

Docker → Podman Äquivalente

Docker-Befehl Podman-Äquivalent
docker run podman run (oder docker run via podman-docker)
docker build podman build / buildah
docker-compose podman-compose
docker push/pull podman push/pull / skopeo
dockerd (Daemon) nicht nötig

6. Infrastructure as Code

6.1 Terraform (direkt als Binary)

TF_VERSION=$(curl -fsSL https://api.github.com/repos/hashicorp/terraform/releases/latest \
  | jq -r .tag_name | sed 's/^v//')
wget "https://releases.hashicorp.com/terraform/${TF_VERSION}/terraform_${TF_VERSION}_linux_arm64.zip"
unzip "terraform_${TF_VERSION}_linux_arm64.zip"
sudo mv terraform /usr/local/bin/
rm "terraform_${TF_VERSION}_linux_arm64.zip"

terraform --version

6.2 OpenTofu (direkt als Binary)

TOFU_VERSION=$(curl -fsSL https://api.github.com/repos/opentofu/opentofu/releases/latest \
  | jq -r .tag_name | sed 's/^v//')
wget "https://github.com/opentofu/opentofu/releases/download/v${TOFU_VERSION}/tofu_${TOFU_VERSION}_linux_arm64.zip"
unzip "tofu_${TOFU_VERSION}_linux_arm64.zip" tofu
sudo mv tofu /usr/local/bin/
rm "tofu_${TOFU_VERSION}_linux_arm64.zip"

tofu --version

7. Kubernetes-Tools

kubectl

KUBECTL_VERSION=$(curl -fsSL https://dl.k8s.io/release/stable.txt)
curl -LO "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/arm64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/

kubectl version --client

Helm

curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

helm version

kubectx + kubens

sudo apt install -y kubectx

8. Claude Code

Installation (nativer Installer)

curl -fsSL https://claude.ai/install.sh | bash
claude --version

OAuth-Setup

claude
# URL im Browser öffnen, Code eingeben

CLAUDE.md (globale Konfiguration)

Datei: ~/.claude/CLAUDE.md — verwaltet im Repo unter claude/CLAUDE.md.

Konfiguriert für: - Sprache: Deutsch für Antworten, Englisch für Code/Commits - Stack: Azure Cloud, Kubernetes, Docker, Terraform, DevSecOps - Sprachen: Python, Bash, PowerShell, YAML/HCL - Platform: Raspberry Pi 4 B (ARM64, Pi OS Lite Trixie)

settings.json (Secret-Schutz)

Datei: ~/.claude/settings.json — verwaltet im Repo unter claude/settings.json.

tmux für persistente Sessions

tmux              # Neue Session starten
claude            # Claude Code darin starten
# Ctrl+B, D      # Session detachen (SSH kann getrennt werden)
tmux attach       # Wieder verbinden

Wichtig: Ohne tmux stirbt die Claude-Code-Session bei SSH-Verbindungsabbruch.


9. Update-Skript

Datei: ~/bin/update-devtools — verwaltet im Repo unter bin/update-devtools.

Aktualisiert kubectl, Helm, Terraform und OpenTofu automatisch. Prüft installierte vs. neueste Version und lädt nur bei Bedarf herunter.

Einrichtung

Das Skript wird automatisch von bootstrap.sh symlinkt:

./bootstrap.sh

Verwendung

update-devtools              # Alle vier Tools aktualisieren
update-devtools kubectl      # Nur kubectl
update-devtools terraform    # Nur Terraform
update-devtools tofu         # Nur OpenTofu
update-devtools helm kubectl # Mehrere auswählen

10. Kompletter Tool-Stack (Übersicht)

Kategorie Tool Versionsmanager Wechsel-Befehl
Runtime Node.js nvm nvm use 22
Runtime Python uv uv python pin 3.12
Runtime Go manuell Binary-Tausch
Runtime Rust rustup rustup default stable
Container Podman apt Docker-kompatibel, kein Daemon
IaC Terraform Binary update-devtools terraform
IaC OpenTofu Binary update-devtools tofu
K8s kubectl Binary update-devtools kubectl
K8s Helm Binary update-devtools helm
K8s kubectx/kubens apt Context/Namespace-Switcher
AI Claude Code nativer Installer claude update

11. Wichtige Pfade

Pfad Inhalt
~/.claude/CLAUDE.md Globale Claude-Code-Konfiguration
~/.claude/settings.json Secret-Schutz / Permissions
~/.nvm/ Node.js Versionen (nvm)
~/.local/share/uv/ Python Versionen (uv)
~/.cargo/ Rust Toolchain (rustup)
/usr/local/go/ Go Installation
/usr/local/bin/ kubectl, helm, terraform, tofu
~/bin/ Eigene Skripte (update-devtools)
/boot/firmware/config.txt Pi Hardware-Konfiguration
~/log/ Log-Dateien (update-devtools)

12. SSH-Härtung

Referenz-Config im Repo unter ssh/sshd_hardening.conf.

# Config anwenden
sudo cp ssh/sshd_hardening.conf /etc/ssh/sshd_config.d/hardening.conf
sudo sshd -t            # Syntax prüfen
sudo systemctl restart ssh

Wichtig: Erst sicherstellen, dass SSH-Key-Login funktioniert, bevor PasswordAuthentication no aktiv wird.

Aktive Einstellungen:

  • Root-Login deaktiviert (PermitRootLogin no)
  • Nur Key-basierte Authentifizierung (PasswordAuthentication no)
  • Nur User robin erlaubt (AllowUsers robin)
  • Max. 3 Login-Versuche (MaxAuthTries 3)
  • X11-Forwarding deaktiviert

13. Unattended Upgrades

Automatische Security-Updates für Debian Trixie.

sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades

Konfiguration in /etc/apt/apt.conf.d/50unattended-upgrades:

Unattended-Upgrade::Origins-Pattern {
    "origin=Debian,codename=${distro_codename}-security,label=Debian-Security";
};

Unattended-Upgrade::Automatic-Reboot "false";
Unattended-Upgrade::Mail "root";
# Prüfen
sudo unattended-upgrades --dry-run --debug

14. Cronjob für update-devtools

Wöchentliche Aktualisierung der Dev-Tools (Sonntag 03:00). Referenz-Datei im Repo unter cron/update-devtools.cron.

# Cronjob installieren
crontab -l 2>/dev/null | cat - cron/update-devtools.cron | crontab -

# Prüfen
crontab -l

# Log ansehen
tail -f ~/log/update-devtools.log

15. Dotfiles: Bootstrap

Das Repo enthält ein idempotentes Bootstrap-Skript, das alle Konfigurationsdateien per Symlink an die richtigen Stellen legt.

git clone git@github.com:SWATPeaceKeeper/claude-pi.git ~/repos/claude-pi
cd ~/repos/claude-pi

# Dry run — zeigt was passieren würde, ändert nichts
./bootstrap.sh -n

# Symlinks erstellen (sichert bestehende Dateien als .bak)
./bootstrap.sh

Was das Skript tut:

  • Erstellt ~/bin/ und symlinkt update-devtools
  • Symlinkt Claude Code Configs nach ~/.claude/
  • Symlinkt ~/.gitconfig und ~/.tmux.conf
  • Fügt eine Source-Zeile in .bashrc für bash/bashrc_custom.sh ein
  • Sichert bestehende Dateien vorher als .bak

Nach dem Bootstrap:

source ~/.bashrc
ls -la ~/.claude/settings.json ~/bin/update-devtools