hetzner-server
hetzner-server — a Claude Code skill from connorads/dotfiles
Features
- ✓Manage dotfiles with Git, no symlinks
- ✓macOS & Linux support with nix-darwin or home-manager
- ✓Integrate with brew for macOS package management
- ✓Use mise for runtime management
- ✓Repository curated by connorads/dotfiles
Installation Guide
Quick start (recommended)
If you are setting up this exact repo on Linux/Codespaces, use the bootstrap script:
curl -fsSL https://raw.githubusercontent.com/connorads/dotfiles/master/install.sh | bashIt installs dotfiles and sets upstream tracking so git status/LazyGit show ahead-behind correctly.
Manual setup (from this repo)
If you want to follow the manual path (or fork this repo), use this.
DOTFILES_REPO=https://github.com/connorads/dotfiles.git
DOTFILES_DIR=$HOME/git/dotfiles
BOOTSTRAP_WORKTREE=$(mktemp -d "$HOME/.dotfiles-bootstrap.XXXXXX")
git clone --separate-git-dir="$DOTFILES_DIR" "$DOTFILES_REPO" "$BOOTSTRAP_WORKTREE"
rm -rf "$BOOTSTRAP_WORKTREE" Why the temporary BOOTSTRAP_WORKTREE dir? git clone needs a checkout target path, and $HOME is non-empty. The temp dir keeps bootstrap safe and disposable.
$HOME and ensure tracking refs
git --git-dir="$DOTFILES_DIR" config core.bare false
git --git-dir="$DOTFILES_DIR" config core.worktree "$HOME"
git --git-dir="$DOTFILES_DIR" config --replace-all remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
git --git-dir="$DOTFILES_DIR" fetch origin --prune$HOME (⚠️ this overwrites conflicting files)
git --git-dir="$DOTFILES_DIR" checkout 2>&1 | sed -n 's/^[[:space:]]\+//p' | while IFS= read -r file; do
if [ -f "$file" ]; then
mv "$file" "$file.bak"
fi
done
git --git-dir="$DOTFILES_DIR" --work-tree="$HOME" checkout -f
CURRENT_BRANCH=$(git --git-dir="$DOTFILES_DIR" symbolic-ref --quiet --short HEAD)
git --git-dir="$DOTFILES_DIR" --work-tree="$HOME" branch --set-upstream-to="origin/$CURRENT_BRANCH" "$CURRENT_BRANCH"macOS (nix-darwin):
# Install Homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
eval "$(/opt/homebrew/bin/brew shellenv)"
# Install Nix (vanilla, not Determinate Nix)
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install --determinate false
. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh
# Build and activate nix-darwin configuration
nix run nix-darwin/master#darwin-rebuild -- switch --flake ~/.config/nixLinux (home-manager):
# Install Nix (vanilla, not Determinate Nix)
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install --determinate false
. ~/.nix-profile/etc/profile.d/nix.sh
# Build and activate home-manager configuration
nix run home-manager/master -- switch --flake ~/.config/nix
exec zshMigration helper (if needed)
If an existing machine has an older setup, run:
DOTFILES_DIR=$HOME/git/dotfiles
if [ "$(git --git-dir=$DOTFILES_DIR rev-parse --is-bare-repository 2>/dev/null || true)" = "true" ]; then
git --git-dir=$DOTFILES_DIR config --unset core.bare || true
fi
git --git-dir=$DOTFILES_DIR config core.worktree $HOME
CURRENT_BRANCH=$(git --git-dir=$DOTFILES_DIR/ symbolic-ref --quiet --short HEAD)
git --git-dir=$DOTFILES_DIR/ config --replace-all remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
git --git-dir=$DOTFILES_DIR/ fetch origin --prune
git --git-dir=$DOTFILES_DIR/ --work-tree=$HOME branch --set-upstream-to=origin/$CURRENT_BRANCH $CURRENT_BRANCHCreate from scratch (optional)
This section is for anyone who wants to build their own dotfiles repo using the same git-dir + work-tree technique (not specifically this repo).
<details>
<summary>Show from-scratch setup</summary>
$HOME
DOTFILES_DIR=$HOME/git/dotfiles
mkdir -p "$DOTFILES_DIR"
git init "$DOTFILES_DIR"
git --git-dir="$DOTFILES_DIR" config core.worktree "$HOME"
git --git-dir="$DOTFILES_DIR" config --replace-all remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
touch "$HOME/.gitignore"
grep -qxF '/*' "$HOME/.gitignore" || printf '%s\n' '/*' >> "$HOME/.gitignore"
grep -qxF '!.gitignore' "$HOME/.gitignore" || printf '%s\n' '!.gitignore' >> "$HOME/.gitignore"~/.gitignore, then adding them
git --git-dir="$DOTFILES_DIR" --work-tree="$HOME" add .gitignore
git --git-dir="$DOTFILES_DIR" --work-tree="$HOME" commit -m "chore(dotfiles): initialise from scratch"
DOTFILES_REPO=git@github.com:your-user/dotfiles.git
dotfiles remote add origin "$DOTFILES_REPO"
dotfiles push -u origin HEAD</details>
Setup YubiKey for sudo
macOS sudo auth is configured in [darwin.nix](.config/nix/modules/darwin.nix):
pam_reattach is enabled so Touch ID works inside tmuxpam_u2f remains in the sudo PAM stack for YubiKey authIn practice:
The YubiKey mapping file is local per machine and is not tracked in dotfiles:
mkdir ~/.config/Yubico
pamu2fcfg > ~/.config/Yubico/u2f_keysAdd a second key if you like
pamu2fcfg -n >> ~/.config/Yubico/u2f_keys