- Add .claude/skills/: homelab-context (auto-loads key facts each session), homelab-status (/homelab-status command), deploy-config (symlink setup guide) - Remove AGENTS.md and ai/sessions/: superseded by plan mode + skill system - Remove 4 obsolete session commands (session-start/list/switch, reload-instructions) - Rewrite CLAUDE.md: remove duplicate content, enforce symlink policy, clarify sudo pattern - Trim docs/services.md from 946 to ~230 lines: remove planning-era content, keep install steps and current status for migration reference - Strip stale "sudo cp" deploy header from ssh-honeypot.service (now symlinked to repo) - Update TODO.md: mark NAS migration and symlink tasks done, add jellyfin upgrade warning
4.2 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
Personal homelab on a ThinkPad running Arch Linux. Docker services behind an Nginx reverse proxy. Full context is in .claude/skills/homelab-context/SKILL.md.
Architecture
- Domain: ak-homelab.duckdns.org (DuckDNS)
- Static IP: 192.168.0.100 (interface: enp4s0)
- NAS: 192.168.0.101, mounted at
/mnt/nas/ - Reverse Proxy: Nginx → path-based routing to services
Configuration Management
All configs are version-controlled in config/. Docker compose files are always symlinked — never copied:
/opt/docker/<service>/docker-compose.yml → ~/homelab/config/docker/<service>/docker-compose.yml
Editing the repo file is editing the live config. Restart the container to apply changes.
All configs — Docker, nginx, systemd units, www — are symlinked to this repo. Editing a file in config/ is editing the live config. Use /deploy-config only on a new machine to create symlinks from scratch, or if drift is detected (a real file exists instead of a symlink).
Sudo Access
A sudoers rule at /etc/sudoers.d/homelab-scripts grants NOPASSWD for scripts in scripts/tmp/:
hoborg ALL=(ALL) NOPASSWD: /bin/bash /home/hoborg/homelab/scripts/tmp/*
Scripts generated there can be run with sudo bash ~/homelab/scripts/tmp/<script>.sh — no password needed.
Never run sudo commands directly. Always create a script in scripts/tmp/.
Docker Guidelines
- NAS-mounted volumes (
/mnt/nas/): useUSER_UID=1024 USER_GID=100to match NAS file ownership - Local volumes: use
USER_UID=1000 USER_GID=1000 - s6-overlay containers (Gitea): do NOT set
user:directive — useUSER_UID/USER_GIDenv vars only - Never copy docker-compose files — they are symlinked; copying breaks the link and causes config drift
Key Commands
Docker
cd /opt/docker/<service>
docker compose logs -f # View logs
docker compose restart # Restart
docker compose down && docker compose up -d # Full restart
Nginx
sudo nginx -t # Test config
sudo systemctl reload nginx # Reload (use restart for major changes)
Systemd Services
sudo systemctl status nginx copyparty
sudo systemctl restart <service>
Development Workflow
- Edit files in
config/(these are the live configs for Docker via symlink) - For non-Docker configs: use
/deploy-configskill or write ascripts/tmp/script - Update
docs/if the change affects setup or architecture - Update
.claude/skills/homelab-context/SKILL.mdif ports, paths, or rules changed - Commit with a clear message
Documentation Structure
docs/— Human-readable reference. Keep for migration and troubleshooting.README.md— Overview and current statusTODO.md— Active task tracking.claude/skills/homelab-context/SKILL.md— AI-optimized operational facts (keep in sync with reality)
For detailed install steps per service, see docs/services.md.
Security Hardening Guidelines
- Understand service needs before applying restrictions (some need rw filesystem access)
- Test each security change individually, not in batches
- Network access patterns matter: SSH Git needs direct access, HTTP can go through localhost proxy
Claude Development Guidelines
CRITICAL: Anti-Pattern Reminders
- RESEARCH FIRST — Check existing solutions in order: pacman → AUR → GitHub
- VERIFY SYNTAX BEFORE WRITING — Use
--help, test in parts, never assume argument formats - STICK TO THE CHOSEN SOLUTION — Don't drift mid-implementation
- PREFER SIMPLE OVER COMPLEX — Existing tools > custom scripts; bash > python for simple tasks
- CHECK PACKAGE REPOS FIRST —
pacman -Ssbefore any manual installation
Failure Patterns to Avoid
- ❌ Broken syntax without testing commands first
- ❌ Switching solutions mid-implementation
- ❌ Overcomplicating when simple solutions exist
- ❌ Installing random scripts before checking packages
Success Pattern
- ✅ Research → Choose → Verify syntax → Implement → Test
- ✅ pacman → AUR → GitHub (preference order)
- ✅ Use proven, maintained tools over custom scripts