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>
This commit is contained in:
440
docs/services.md
Normal file
440
docs/services.md
Normal file
@@ -0,0 +1,440 @@
|
||||
# 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
|
||||
|
||||
### Gitea Installation (Docker - Recommended)
|
||||
|
||||
**Status:** ✅ **Container Running** ⚠️ **Configuration Issues** - UI accessible, config needs debugging
|
||||
|
||||
**Prerequisites:**
|
||||
```bash
|
||||
# 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:**
|
||||
```bash
|
||||
# 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`:
|
||||
```yaml
|
||||
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:**
|
||||
```bash
|
||||
cd ~/docker/gitea
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
### Current Configuration
|
||||
|
||||
**Container Status:** ✅ Running at /opt/docker/gitea
|
||||
**Access URLs:**
|
||||
- **Local Web**: http://192.168.0.100:3000
|
||||
- **External Web**: http://ak-homelab.duckdns.org:3000 (requires port forwarding)
|
||||
- **Git SSH**: ssh://git@ak-homelab.duckdns.org:2223 (requires port forwarding)
|
||||
|
||||
**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:**
|
||||
```bash
|
||||
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
|
||||
```bash
|
||||
# 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
|
||||
```bash
|
||||
# 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
|
||||
```bash
|
||||
# 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
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
# 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:**
|
||||
```nginx
|
||||
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
|
||||
```bash
|
||||
# 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
|
||||
```bash
|
||||
#!/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
|
||||
Reference in New Issue
Block a user