# Homelab TODO List

## HIGH PRIO

- [ ] Move all bigger storages to NAS if it isn't there already
  - Gitea
  - Nextcloud
- [ ] Unify YADM configs across different systems
  - use YADM alternatives method if needed for conflicts

## Network & Security
- [x] DuckDNS dynamic DNS setup *(completed - ak-homelab.duckdns.org)*
- [x] SSH security hardening *(documented in network-security.md)*
  - [x] Figure out why laptop IP changes: Different eth ports have different MAC?
- [x] Router port forwarding configuration
- [x] !!! Set up geoblocking for SSH. Rest of SSH hardening already done.
- [ ] !!! Modify syncthing to sync the NAS folders where appropriate (e.g. Logseq)
- [x] Dockerize everything and use symlinks for dockerfiles — all docker-compose files symlinked from `/opt/docker/` to repo `config/docker/`
- [ ] !!! IMPORTANT: Run setup scripts made by security reviewer agent
  - [ ] Ran out of AI quota mid-security review so continue where we left off. Some scripts created but it's not
  complete yet
  - [ ] Some logs saved to ~/audit
- [ ] ENCRYPTED FOLDER idea:
  - Use tomb to create an encrypted vault e.g. /mnt/nas/nas_encrypted
  - Have a local folder that's empty e.g. <something>/nas_plain
  - Use tomb to unlock and mount /mnt/nas/nas_encrypted to <something>/nas_plain
  - Jellyfin is set up to look at nas_plain
  - When locked: Jellyfin sees empty folder
  - When unlocked: Jellyfin has access
  - TO TEST: What about preview pictures etc. within Jellyfin? Adult content may still be visible
- [ ] WireGuard VPN server configuration
- [ ] UFW firewall setup and rules
- [ ] fail2ban for intrusion prevention
- [x] VNC setup for remote desktop access *(TigerVNC installed, enabled temporarily via SSH when needed)*

## Git & Development
- [x] Gitea Docker container setup *(completed - running on port 3000)*
- [x] Nginx reverse proxy setup *(completed)*
- [ ] Create homelab landing page at /var/www/homelab/index.html
- [x] Configure router port forwarding for Nginx *(completed - external access working)*
  - [x] Port 80 → 192.168.0.100:80 (HTTP)
  - [x] Port 443 → 192.168.0.100:443 (HTTPS)
  - [x] Remove port 3000 direct forwarding (will go through nginx)
  - [x] Keep port 2223 → 192.168.0.100:2223 (Git SSH operations)
- [x] Test external access: https://ak-homelab.duckdns.org/ *(working - HTTPS with SSL)*
- [x] Set up SSL certificates: sudo certbot --nginx -d ak-homelab.duckdns.org *(completed - auto-renewal enabled)*
- [x] Initial Gitea configuration via web interface (http://ak-homelab.duckdns.org/gitea/) *(completed)*
  - [x] Complete installation wizard with correct base URL
  - [x] Create admin user account
  - [x] Configure SSH access and repository settings
  - [x] Migrate homelab repository to Gitea

## System Configuration
- [x] Arch Linux installation and basic setup *(completed)*
- [x] TTY configuration with ter-124b font *(completed)*
- [x] Caps lock → backspace mapping in TTY *(completed)*
- [x] Dotfiles management with yadm *(completed)*
- [x] Temperature monitoring in tmux *(completed)*
- [x] Zsh history sharing between sessions *(completed)*
- [x] Fix TTY colors for better code readability
- [ ] Configure automatic system backups

## Desktop & Applications
Lower priority - mostly using SSH or TTY anyways
- [ ] Add windows-like bottom panel icons
- [ ] Install additional browsers as backup
- [ ] Add dmenu run shortcut
- [ ] Later: Test awesomewm once again, consider migration
- [x] Install Deskflow for multi-device setup

## Data organization
- [ ] Mount and configure /data drive
- [ ] Copy backups from USB drives
      * Not sure if necessary, some files may already be on the PC
      * [ ] First: Do a bit of "duplication check" across various devices and USBs, make a plan of what to store where
- [ ] Copy any media files from other devices

## Music Collection Management
- [ ] Extract playlists from YouTube Music and SoundCloud
  - Store metadata (author, song title) in plaintext format
  - Tools to consider: ytmusicapi (YouTube Music), scdl (SoundCloud), Google Takeout
  - Output formats: CSV, JSON, M3U with metadata, plain text lists
- [ ] Obtain music files for self-hosted collection
  - Legal sources: Bandcamp (FLAC), Beatport, 7digital, HDtracks, artist websites
  - Physical media: CD ripping, vinyl digitization, cassette conversion
  - Streaming downloads: Tidal, Qobuz, Amazon Music, iTunes Store
  - Organization tools: MusicBrainz Picard (tagging), beets (library management)

## Services & Self-Hosting
- [x] Install and configure Gitea for Git hosting *(completed - external access working)*
- [x] Set up file server with Copyparty *(completed - uploads/downloads working)*
  - [x] User authentication and access control
  - [x] Multiple volume shares (shared, documents, music, videos, private)
  - [x] Systemd service for auto-start
  - [x] Nginx reverse proxy integration
- [x] Configure Jellyfin media server *(completed - running on port 8096)*
  - [x] Docker container setup with hardware acceleration
  - [x] Nginx reverse proxy integration at /media/ path
  - [x] Shared media folders with Copyparty (Music, Videos, shared)
- [ ] Set up self-hosted chat server (Matrix or Mattermost)
- [ ] Install monitoring and management tools *(in progress)*
  - [x] Portainer (Docker management with built-in auth)
  - [x] Glances (system monitoring with nginx basic auth)
  - [ ] lazydocker (terminal Docker management)
- [ ] Configure nginx basic auth for Glances endpoint
- [ ] Update nginx reverse proxy config for new admin services
- [ ] Update homelab landing page with new admin service links
- [ ] Set up Nextcloud for advanced file synchronization features
  - Copyparty covers basic file sharing needs
- [x] Set up reverse proxy with SSL certificates *(completed - HTTPS working with auto-renewal)*
- [x] Make sure all services are dockerized unless we have a good reason not to
  - Gitea: ✅ Docker
  - Jellyfin: ✅ Docker
  - qBittorrent: ✅ Docker
  - Portainer: ✅ Docker
  - Copyparty: ✅ Docker
  - Glances: ❌ systemd (needs full system access for accurate monitoring)
  - Netdata: ❌ systemd (needs full system access for accurate monitoring)
  - Syncthing: ❌ systemd (Docker permission issues with config directory)
  - Nginx: ❌ system package (reverse proxy, system integration required)

## Hardware & Troubleshooting
- [ ] Fix bluetooth audio connectivity issues
- [x] Investigate tmux battery indicator missing until config reload
- [x] Figure out drag and drop window tiling solution -> workaround with keyboard shortcuts
- [ ] Install multimedia codecs and applications

## Docker Storage Migration
- [x] Move Gitea storage to NAS — migrated to `/mnt/nas/docker-data/gitea/data` (USER_UID=1024:100 to match NAS ownership)
- [x] Move Nextcloud storage to NAS — migrated to `/mnt/nas/docker-data/nextcloud/`
- [ ] Persist copyparty index database to NAS — currently rebuilt from scratch on every restart (slow, scans entire NAS); mount `/mnt/nas/.copyparty-db` into the container so the index survives restarts
- [ ] Clean up old leftover data: `/opt/docker/gitea/data/`, `/opt/docker/gitea/data.old/`, Docker volumes `gitea_gitea`, `nextcloud_nextcloud_data`, `nextcloud_nextcloud_db`

## Docker Image Upgrades
See `docs/docker-upgrade-plan.md` for full plan. Key warnings:
- **Jellyfin**: v10.11+ does a major EF Core DB migration (`library.db` → `jellyfin.db`). Known to hang at "Saving BaseItem entries". **Back up jellyfin data volume before upgrading.**
- **Redis**: Stay on `7-alpine` — Redis 8 has ACL breaking changes, not worth upgrading for a cache role
- All containers are behind on updates as of 2026-02-27 (see plan doc for details)

## Security & Maintenance
- [ ] Configure automatic security updates
- [ ] Set up system monitoring and alerting
- [ ] Implement backup strategy for services
- [ ] Regular security audit and updates
- [ ] Document recovery procedures
