# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview This is a personal homelab setup repository documenting the migration from cloud services to self-hosted solutions on a ThinkPad running Arch Linux. The project uses Docker for containerized services behind an Nginx reverse proxy. ## Architecture ### Network Infrastructure - **Domain**: ak-homelab.duckdns.org (DuckDNS dynamic DNS) - **Static IP**: 192.168.0.100 (dual interface: ethernet enp4s0, WiFi wlp1s0) - **SSH**: Custom port 2222 for system access - **Reverse Proxy**: Nginx for path-based routing to services ### Service Architecture ``` Internet → Router → Nginx (80/443) → Services → SSH (2222) → System → Gitea SSH (2223) → Git operations ``` **Current Services:** - Gitea Git server: Docker container on port 3000, accessible via `/gitea/` path - Copyparty file server: Systemd service on port 8082, accessible via `/files/` path with WebDAV support - Jellyfin media server: Docker container on port 8096, accessible via `/media/` path - Nginx: Reverse proxy routing to `ak-homelab.duckdns.org/servicename/` ### Configuration Management All configurations are version controlled in the `config/` directory: - `config/docker/gitea/`: Gitea container setup and deployment scripts - `config/docker/jellyfin/`: Jellyfin media server configuration - `config/nginx/`: Reverse proxy configurations with SSL and WebDAV support - `config/scripts/`: Utility scripts for system maintenance - `~/.config/copyparty/`: Copyparty file server configuration Configuration files include deployment instructions in comments showing target locations (e.g., `/opt/docker/gitea/`, `/etc/nginx/sites-available/`). ## Key Commands ### Docker Service Management ```bash # Gitea operations (from /opt/docker/gitea/) docker-compose logs gitea # View logs docker-compose down # Stop docker-compose up -d # Start docker-compose pull && docker-compose up -d # Update # Jellyfin operations (from /opt/docker/jellyfin/) docker-compose logs jellyfin # View logs docker-compose down # Stop docker-compose up -d # Start docker-compose pull && docker-compose up -d # Update # Deploy from repo sudo cp config/docker/gitea/docker-compose.yml /opt/docker/gitea/ sudo cp config/docker/jellyfin/docker-compose.yml /opt/docker/jellyfin/ ``` ### Copyparty File Server Management ```bash # Service operations sudo systemctl status copyparty # Check status sudo systemctl start copyparty # Start service sudo systemctl stop copyparty # Stop service sudo systemctl restart copyparty # Restart (reload config) # Configuration sudo cp ~/.config/copyparty/copyparty.conf ~/.config/copyparty/copyparty.conf.backup # Edit config and restart service to reload ``` ### Nginx Operations ```bash # Deploy configuration sudo cp config/nginx/homelab.conf /etc/nginx/sites-available/homelab sudo ln -s /etc/nginx/sites-available/homelab /etc/nginx/sites-enabled/homelab # Management sudo nginx -t # Test config sudo systemctl reload nginx # Reload sudo systemctl status nginx # Status ``` ### SSL Certificate Management ```bash sudo certbot --nginx -d ak-homelab.duckdns.org sudo systemctl enable certbot.timer # Auto-renewal ``` ## Development Workflow ### Task Tracking Use `TODO.md` for centralized task management organized by category (Network & Security, Git & Development, System Configuration, etc.). Mark completed items and update status in documentation. ### Configuration Changes 1. Edit files in `config/` directory 2. Test locally when possible 3. Deploy to target locations with sudo commands included in file headers 4. Update documentation status in `docs/services.md` 5. Commit changes with logical separation ### Documentation Structure - `docs/`: Technical documentation for setup procedures - `README.md`: Overview and current status - `TODO.md`: Active task tracking - Configuration files self-document deployment locations in headers ### Network Configuration Notes - System uses dual ethernet ports (enp3s0f0, enp4s0) - stick to enp4s0 consistently - Port conflicts: SSH (2222), Gitea SSH (2223), Gitea Web (3000) - Router forwarding: HTTP (80), HTTPS (443), SSH (2222), Git SSH (2223) ### Service URLs - **Local access**: http://192.168.0.100/servicename/ - **External access**: https://ak-homelab.duckdns.org/servicename/ - **Gitea SSH**: ssh://git@ak-homelab.duckdns.org:2223 - **Voice Assistant**: http://127.0.0.1:8880 (local TTS server) - **Copyparty WebDAV**: https://ak-homelab.duckdns.org/files/ (for X-plore, rclone, etc.) ### Voice Assistant Commands ```bash # Enable voice mode (starts server and configures voice-mode) ./scripts/enable-voice.sh # Disable voice mode (stops server) ./scripts/disable-voice.sh # Manual voice server management cd voice-server poetry run voice-server # Start server poetry install # Install dependencies poetry run pytest # Run tests # Test TTS directly curl -X POST "http://127.0.0.1:8880/v1/audio/speech" \ -H "Content-Type: application/json" \ -d '{"input": "Hello world!", "voice": "ryan"}' \ --output test.wav ``` ### WebDAV Client Setup ```bash # X-plore File Manager (Android) # Server: ak-homelab.duckdns.org # Path: /files/ # Port: 443 (HTTPS) # Username: hoborg # Password: AdminPass2024! # rclone configuration rclone config create homelab-webdav webdav \ url=https://ak-homelab.duckdns.org/files/ \ vendor=other \ user=hoborg \ pass=$(rclone obscure "AdminPass2024!") # Mount with rclone rclone mount homelab-webdav: ~/homelab-files --daemon # Test WebDAV curl -X PROPFIND https://hoborg:AdminPass2024!@ak-homelab.duckdns.org/files/ \ -H "Depth: 1" -H "Content-Type: text/xml" ```