Files
homelab/docs/services.md
Arpad Krejczinger f7b5d26eab Reorganize repository structure and add configuration management
- Create organized directory structure:
  - docs/ for all documentation files
  - config/ for deployment configurations and scripts
- Add CLAUDE.md with project architecture and development workflow
- Update README.md with new structure and current status
- Move all documentation to docs/ directory
- Organize Docker and Nginx configurations under config/

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-06 17:24:11 +02:00

12 KiB

Services & Applications

Planning and configuration for self-hosted services and applications.

Git Repository Hosting

Service Options

  • Gitea: Lightweight, Go-based, minimal resource usage Recommended
  • Forgejo: Gitea fork, community-driven development
  • GitLab CE: Feature-rich but more resource intensive
  • Gogs: Simple, lightweight alternative

Status: Container Running ⚠️ Configuration Issues - UI accessible, config needs debugging

Prerequisites:

# Install Docker and Docker Compose
sudo pacman -S docker docker-compose
sudo systemctl enable docker
sudo systemctl start docker

# Add user to docker group (logout/login required)
sudo usermod -aG docker hoborg

Gitea Docker Setup:

# Create directories for persistent data
mkdir -p ~/docker/gitea/{data,config}

# Run Gitea container
docker run -d \
  --name gitea \
  -p 3000:3000 \
  -p 2222:22 \
  -v ~/docker/gitea/data:/data \
  -v ~/docker/gitea/config:/etc/gitea \
  -e USER_UID=1000 \
  -e USER_GID=1000 \
  gitea/gitea:latest

# Alternative: Docker Compose (preferred)
# See docker-compose.yml below

Docker Compose Configuration: Create ~/docker/gitea/docker-compose.yml:

version: "3"

networks:
  gitea:
    external: false

services:
  server:
    image: gitea/gitea:latest
    container_name: gitea
    environment:
      - USER_UID=1000
      - USER_GID=1000
    restart: always
    networks:
      - gitea
    volumes:
      - ./data:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "3000:3000"
      - "2223:22"  # Gitea SSH (avoid conflict with system SSH on 2222)

Start with Docker Compose:

cd ~/docker/gitea
docker-compose up -d

Current Configuration

Container Status: Running at /opt/docker/gitea Access URLs:

Port Assignments:

  • System SSH: 2222 (for server administration)
  • Gitea SSH: 2223 (for Git operations)
  • Gitea Web: 3000 (web interface)

Database: SQLite (default, stored in container volume) Data Location: /opt/docker/gitea/data (persistent volume)

Router Port Forwarding Required:

  • 3000 → 192.168.0.100:3000 (web interface)
  • 2223 → 192.168.0.100:2223 (Git SSH operations)

Container Management:

cd /opt/docker/gitea
docker-compose logs gitea        # View logs
docker-compose down             # Stop container
docker-compose up -d            # Start container
docker-compose pull && docker-compose up -d  # Update

Gitea Configuration Recommendations

Database Selection:

  • SQLite (Recommended for homelab)
    • Zero configuration, single file
    • Perfect for personal/small team use
    • Easy backups and migration
  • PostgreSQL (Production alternative)
    • Better performance for heavy usage
    • Requires additional container setup

Domain & URL Configuration:

  • Server Domain: ak-homelab.duckdns.org
  • Gitea Base URL: http://ak-homelab.duckdns.org/gitea/
  • SSH Domain: ak-homelab.duckdns.org
  • SSH Port: 2223

Password Hash Algorithm:

  • Argon2 (Recommended)
    • Most secure modern algorithm
    • Resistant to GPU/ASIC attacks
    • Higher CPU usage but excellent security
  • bcrypt (Alternative)
    • Well-tested, lower resource usage
    • Good balance of security and performance

Setup Progress:

  1. Gitea container running
  2. Nginx reverse proxy setup complete
  3. 📋 Router port forwarding (80, 443) - Next
  4. ⚠️ Gitea web configuration - Partially complete, needs debugging
    • Initial setup wizard completed
    • Base URL configuration issue (extra space in config)
    • UI accessible but routing may be broken
  5. 📋 SSL certificate setup - After router config

Current Access:

  • Local UI working: http://192.168.0.100/gitea/
  • External access: Pending router port forwarding
  • ⚠️ Configuration debugging needed

Debug Tasks:

  • Fix base URL in /opt/docker/gitea/data/gitea/conf/app.ini
  • Check ROOT_URL setting for extra spaces
  • Verify redirect behavior after fix

Cloud Storage Solutions

Service Options

  • Copyparty: Quite new self-hosted file storage solution, must investigate!
  • Nextcloud: Full-featured, extensive app ecosystem Recommended
  • ownCloud: Original project, stable and mature
  • Seafile: Performance-focused file sync
  • Syncthing: Decentralized sync (no server needed)

Nextcloud Installation

# Via snap (recommended)
sudo snap install nextcloud

# Or via Docker
docker run -d \
  --name nextcloud \
  -p 8080:80 \
  -v nextcloud_data:/var/www/html \
  nextcloud

Personal notes: Not a fan of snap, isn't there an AUR package? Go with docker otherwise

Features

  • File synchronization across devices
  • Video files, game installers -> high prio
  • Self-hosted git mirrors of favorite FOSS projects -> medium prio
  • Calendar and contacts (CalDAV/CardDAV) -> low prio
  • Document editing (OnlyOffice/Collabora) -> low prio
  • Photo management and sharing -> low prio
  • Mobile apps available?

Media Management

Jellyfin Media Server

# Install via AUR
yay -S jellyfin-server jellyfin-web

# Enable service
sudo systemctl enable jellyfin
sudo systemctl start jellyfin

Configuration:

  • Port: 8096 (web interface)
  • Media paths: /data/movies, /data/tv, /data/music
  • Transcoding: Hardware acceleration if available

Photo Management

  • PhotoPrism: AI-powered photo management
  • Immich: Modern photo backup solution
  • LibrePhotos: Privacy-focused alternative

Monitoring & Logging

System Monitoring

# Prometheus + Grafana stack
docker-compose up -d prometheus grafana node-exporter

Log Management

  • Centralized logging: rsyslog or journald
  • Log rotation: logrotate configuration
  • Analysis: grep, awk, or ELK stack for advanced needs

Health Checks

  • Uptime monitoring: Simple HTTP checks
  • Service status: systemd service monitoring
  • Disk space: Automated alerts for low space

Containerization Strategy

Docker Setup

# Install Docker
pacman -S docker docker-compose
sudo systemctl enable docker

# Add user to docker group
sudo usermod -aG docker hoborg

Container Management

  • Orchestration: Docker Compose for multi-service apps
  • Storage: Named volumes for persistent data
  • Networking: Custom networks for service isolation
  • Updates: Watchtower for automated updates

Reverse Proxy Configuration

Decision Matrix: Nginx vs Traefik

Problem: Multiple services need to be accessible under single domain with path-based routing. Solution: Reverse proxy to route requests based on URL paths.

Nginx

Pros:

  • Mature & battle-tested (decades of production use)
  • High performance for static files and caching
  • Flexible configuration - handles any routing scenario
  • Extensive ecosystem and documentation
  • Can handle non-Docker services easily

Cons:

  • Manual configuration required
  • No auto-discovery of services
  • Requires config reload for changes

Traefik

Pros:

  • Docker-native auto-discovery via labels
  • Automatic HTTPS with Let's Encrypt
  • Dynamic configuration (no restarts)
  • Modern design for containerized environments

Cons:

  • Less mature, smaller ecosystem
  • Docker-dependent (less flexible)
  • Steeper learning curve for complex scenarios

Decision: Nginx - Better for homelab due to reliability, documentation, and flexibility for mixed Docker/non-Docker services.

URL Architecture Decision

Options Considered:

  1. Separate subdomains: gitea.ak-homelab.duckdns.org DuckDNS doesn't support nested subdomains
  2. Multiple DuckDNS domains: ak-homelab-git.duckdns.org Management overhead
  3. Path-based routing: ak-homelab.duckdns.org/gitea/ Selected

Chosen Architecture:

ak-homelab.duckdns.org/          → Landing page/dashboard
ak-homelab.duckdns.org/gitea/    → Gitea Git server
ak-homelab.duckdns.org/cloud/    → Nextcloud file sync
ak-homelab.duckdns.org/media/    → Jellyfin media server
ak-homelab.duckdns.org/monitor/  → System monitoring

Advanced Nginx Options

Nginx Plus (Commercial): $2500+/year

  • Advanced load balancing, health checks
  • API management, JWT validation
  • Real-time monitoring dashboard
  • Verdict: Overkill for homelab

Nginx + Lua (OpenResty):

  • Embed Lua scripts for dynamic processing
  • Complex routing logic, authentication
  • API gateway functionality
  • Verdict: Powerful but complex, not needed initially

Nginx Setup

Status: Complete - Reverse proxy configured and running

# Install nginx and SSL tools
sudo pacman -S nginx certbot certbot-nginx

# Create configuration
sudo nano /etc/nginx/sites-available/homelab

# Enable site
sudo ln -s /etc/nginx/sites-available/homelab /etc/nginx/sites-enabled/

# Test and reload
sudo nginx -t
sudo systemctl reload nginx

Configuration Template:

server {
    listen 80;
    server_name ak-homelab.duckdns.org;

    # Main landing page
    location / {
        root /var/www/homelab;
        index index.html;
    }

    # Gitea reverse proxy
    location /gitea/ {
        proxy_pass http://127.0.0.1:3000/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # Future services
    # location /cloud/ {
    #     proxy_pass http://127.0.0.1:8080/;
    #     proxy_set_header Host $host;
    # }
}

Router Port Forwarding Requirements

  • HTTP: Port 80 → 192.168.0.100:80
  • HTTPS: Port 443 → 192.168.0.100:443
  • Remove: Direct port 3000 forwarding (will go through nginx)

SSL Certificates

# Let's Encrypt via certbot (after nginx setup)
sudo certbot --nginx -d ak-homelab.duckdns.org

# Auto-renewal
sudo systemctl enable certbot.timer

Backup Strategy

Configuration Backups

  • Service configs: Docker volumes, /etc configs
  • Database dumps: Regular automated backups
  • Storage: External drive or cloud backup

Automated Backups

#!/bin/bash
# backup-services.sh
DATE=$(date +%Y%m%d)

# Backup Gitea
tar -czf /backup/gitea-$DATE.tar.gz /var/lib/gitea/

# Backup Nextcloud data
rsync -av /var/snap/nextcloud/common/nextcloud/data/ /backup/nextcloud-$DATE/

# Database backup
sudo -u postgres pg_dump gitea > /backup/gitea-db-$DATE.sql

Resource Planning

Hardware Requirements

  • RAM: 4GB minimum, 8GB recommended
  • Storage:
    • System: 50GB SSD
    • Data: 1TB+ HDD for media/files
  • Network: Gigabit Ethernet preferred

Service Resource Usage

Service RAM CPU Storage Port
Gitea 200MB Low 5GB+ 3000
Nextcloud 512MB Medium 10GB+ 8080
Jellyfin 1GB High* Media 8096
Monitoring 500MB Low 2GB 3000/9090

*High during transcoding

Security Considerations

Service Hardening

  • Regular updates: Automated security patches
  • Access control: VPN-only access when possible
  • Authentication: Strong passwords, 2FA where available
  • Network isolation: Separate VLANs or containers

Data Protection

  • Encryption: Full disk encryption (LUKS)
  • Backups: Encrypted offsite backups
  • Access logs: Monitor service access patterns
  • Fail2ban: Automatic IP blocking for repeated failures

Future Expansion

Additional Services to Consider

  • Home Assistant: ABSOLUTELY NOT
  • Bitwarden/Vaultwarden: Password management
    • How is this better than keepassxc + filesync?
  • Pi-hole: Network-wide ad blocking
  • Wireguard UI: Web interface for VPN management
  • Bookstack: Documentation wiki
    • What is this for? How does it compare to Logseq?
  • FreshRSS: RSS feed aggregator