Files
vps/vps1-state-25012026.md
service 1e1a528a5e Initial commit: VPS setup documentation
Add comprehensive documentation for VPS setup and configuration including:
- Project instructions
- VPS1 starting point configuration
- VPS1 current state documentation
- VPS1 todo list

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-26 07:43:24 +01:00

14 KiB
Raw Blame History

VPS1 State - 2026-01-25

Host: vps1.phiiiil.de (152.53.119.222) Date: 2026-01-25 Status: Production Ready

Executive Summary

VPS1 is a secure Docker-based hosting platform running on Debian 12 (ARM64) with 1TB storage and 15GB RAM. The system hosts three main services: Netbird VPN management, Immich photo management (37GB of photos), and Gitea Git hosting.

Key Achievements:

  • All services running and healthy (12 containers)
  • Security hardened (UFW firewall + Fail2ban)
  • Complete automated daily backups (databases + 39GB photo library)
  • SSL certificates for all domains via Caddy
  • Single sign-on ready via Netbird Zitadel
  • rsync installed for efficient backups

Services

Netbird VPN Management

URL: https://nb.phiiiil.de Purpose: VPN management, user authentication, reverse proxy

Components (8 containers):

  • netbird-caddy-1 - Reverse proxy (ports 80, 443)
  • netbird-dashboard-1 - Web UI
  • netbird-management-1 - Management API
  • netbird-zitadel-1 - Identity provider (OIDC/SSO)
  • netbird-zdb-1 - Zitadel PostgreSQL database
  • netbird-signal-1 - Signal service
  • netbird-relay-1 - Relay service
  • netbird-coturn-1 - TURN/STUN relay (host networking)

Features:

  • Centralized user management
  • OAuth2/OIDC authentication
  • Automatic SSL certificate management via Caddy
  • Routes for all services

Immich Photo Management

URL: https://immich.phiiiil.de Purpose: Photo backup, management, and AI-powered features

Components (3 containers):

  • immich_server - Main application (port 2283)
  • immich_postgres - PostgreSQL database with vector extension
  • immich_redis - Caching layer
  • immich_machine_learning - ML/AI features

Data:

  • 34,694 files (photos, videos, thumbnails) stored in /home/phil/docker/immich-app/library/
  • 39.34GB total library size
  • PostgreSQL database with indexed metadata

Backup: Fully automated daily backup at 04:00

  • Photo library: rsync to /mnt/backup/immich-photos/ (39GB, 30-day retention)
  • Database: PostgreSQL dump to /mnt/backup/latest/ (52MB, 30-day retention)
  • Both backups include detailed logging and restore procedures

Gitea Git Hosting

URL: https://git.phiiiil.de Purpose: Private Git hosting with integrated SSO

Components (2 containers):

  • gitea - Git application (port 3000, SSH on 2222)
  • gitea-db - PostgreSQL 16 database

Configuration:

  • Admin: User phil with secure password
  • Registration: Disabled (private instance)
  • SSH: Port 2222
  • Database: PostgreSQL 16 with strong password
  • OIDC: Enabled (ready for Netbird integration)

Security Configuration

Firewall (UFW)

Status: Active

Allowed Inbound Ports:

  • 22/tcp (SSH)
  • 80/tcp (HTTP → Caddy)
  • 443/tcp (HTTPS → Caddy)
  • 443/udp (HTTP3/QUIC → Caddy)
  • 2283/tcp (Immich direct access)
  • 2222/tcp (Gitea SSH)

Policy: Deny all other incoming traffic

Fail2ban

Status: Active protecting SSH

Configuration:

  • Ban time: 1 hour
  • Max retries: 3
  • Find time: 10 minutes
  • Currently banned: 5 IPs (SSH brute force attempts)

Security Headers (Caddy)

All domains have:

  • HSTS (3600s, includeSubDomains, preload)
  • X-Content-Type-Options: nosniff
  • X-Frame-Options: SAMEORIGIN
  • X-XSS-Protection: 1; mode=block
  • Referrer-Policy: strict-origin-when-cross-origin

Network & DNS

DNS Configuration

All domains correctly pointing to 152.53.119.222:

  • nb.phiiiil.de → 152.53.119.222
  • git.phiiiil.de → 152.53.119.222
  • immich.phiiiil.de → 152.53.119.222

SSL Certificates

All domains have valid Let's Encrypt certificates:

  • nb.phiiiil.de
  • git.phiiiil.de
  • immich.phiiiil.de

Certificates obtained and renewed automatically by Caddy.

Docker Networks

  • netbird_netbird - Shared network for all services (Netbird, Gitea, Immich, Caddy)
  • immich_default - Immich internal network
  • bridge - Default Docker network
  • host - For Coturn TURN server

Backup Strategy

Automated Backups

Schedule 1: Database Backup (02:00)

  • Script: /home/phil/docker/backup/backup.sh
  • Location: /mnt/backup/
  • Retention: 30 days
  • Log: /var/log/vps-backup.log

What Gets Backed Up:

  1. Immich PostgreSQL database (52MB)
  2. Immich library manifest (file count, size)
  3. Netbird management data (31MB)
  4. Netbird Zitadel database (77KB)
  5. Gitea PostgreSQL database (24KB)
  6. Gitea data volume (9.4KB)

Latest backup symlink: /mnt/backup/latest


Schedule 2: Immich Photo Backup (04:00) NEW

  • Script: /home/phil/docker/backup/backup-immich-photos.sh
  • Location: /mnt/backup/immich-photos/
  • Retention: 30 days
  • Log: /var/log/immich-photo-backup.log

What Gets Backed Up:

  • 34,694 files (photos, videos, thumbnails, encoded videos)
  • 39.34GB total library size
  • Incremental backup using rsync with hardlinking
  • Space-efficient (unchanged files use hardlinks)
  • Automatic cleanup of backups older than 30 days

Latest backup symlink: /mnt/backup/immich-photos/latest

Backup Performance

Immich Photo Backup:

  • First backup: ~4 minutes (164 MB/s)
  • Subsequent backups: ~1-2 minutes (incremental)
  • Storage overhead: Minimal (hardlinks for unchanged files)

Storage Requirements

Current Usage:

  • Photo backups: ~39GB (with hardlinks, additional days minimal)
  • Database backups: ~2.5GB (30 days × 83MB)
  • Total: ~42GB for 30-day retention

Available Space: 863GB free (91% of 1TB)

File Structure

/home/phil/docker/
├── netbird/              # Netbird VPN + Caddy reverse proxy
│   ├── docker-compose.yml
│   ├── Caddyfile
│   ├── dashboard.env
│   ├── management.json
│   ├── relay.env
│   ├── turnserver.conf
│   ├── zitadel.env
│   ├── zdb.env
│   └── machinekey/
├── immich-app/           # Immich Photo Management
│   ├── docker-compose.yml
│   ├── .env
│   ├── library/          # 39GB of photos (34,694 files)
│   └── postgres/         # Database files
├── gitea/                # Git Hosting
│   ├── docker-compose.yml
│   └── .env              # Contains DB password
└── backup/               # Backup scripts
    ├── backup.sh                 # Database backup (02:00)
    └── backup-immich-photos.sh   # Photo backup (04:00)

/mnt/backup/              # Backup storage mount point
├── latest/               # Symlink to latest database backup
└── immich-photos/        # Photo backups
    └── latest/           # Symlink to latest photo backup

Container Status

Container Status Health Purpose
gitea Running Healthy Git hosting
gitea-db Running Healthy Gitea database
immich_server Running Healthy Photo management
immich_postgres Running Healthy Immich database
immich_redis Running Healthy Immich cache
immich_machine_learning Running Healthy Immich ML/AI
netbird-caddy-1 Running - Reverse proxy
netbird-dashboard-1 Running - Netbird UI
netbird-management-1 Running - Netbird API
netbird-zitadel-1 Running - Identity provider
netbird-zdb-1 Running Healthy Zitadel DB
netbird-signal-1 Running - Signal service
netbird-relay-1 Running - Relay service
netbird-coturn-1 Running - TURN/STUN relay

Total: 12 containers Healthy: 6 All running: Yes

System Resources

Disk Usage:

  • Total: 1TB (1006GB)
  • Used: 92GB (10%)
  • Available: 863GB
  • Change: +37GB (photo backup)

RAM:

  • Total: 15GB
  • Used: ~2GB
  • Available: ~13GB

OS:

  • Distribution: Debian GNU/Linux 12 (bookworm)
  • Kernel: Linux 6.1.0-40-arm64
  • Architecture: ARM64
  • rsync: Installed

Access Credentials

SSH

Host: vps1.phiiiil.de (152.53.119.222) User: phil Key: ~/.ssh/id_rsa (RSA) Config: ~/.ssh/config (Host vps1)

Gitea

URL: https://git.phiiiil.de Admin User: phil Password: j8bKvIl3AtIp5aTG SSH: git@152.53.119.222:2222

Netbird

URL: https://nb.phiiiil.de Admin: Configured via Netbird dashboard

Immich

URL: https://immich.phiiiil.de Admin: Created during initial setup

Maintenance Commands

Daily Tasks

# Check all containers
docker ps

# Check system resources
df -h
free -h

# Check database backup log
tail -f /var/log/vps-backup.log

# Check photo backup log
tail -f /var/log/immich-photo-backup.log

# Verify photo backup completed
ls -lah /mnt/backup/immich-photos/latest/
cat /mnt/backup/immich-photos/latest/backup-info.txt

Weekly Tasks

# Check latest database backup
ls -lah /mnt/backup/latest/

# Check latest photo backup
ls -lah /mnt/backup/immich-photos/latest/

# Review fail2ban bans
sudo fail2ban-client status sshd

# Check container resource usage
docker stats

Monthly Tasks

# Update container images
cd /home/phil/docker/gitea && docker compose pull && docker compose up -d
cd /home/phil/docker/netbird && docker compose pull && docker compose up -d
cd /home/phil/docker/immich-app && docker compose pull && docker compose up -d

# Security updates
sudo apt update && sudo apt upgrade

# Review banned IPs
sudo fail2ban-client status sshd

Manual Backup

# Run database backup manually
/home/phil/docker/backup/backup.sh

# Run photo backup manually
/home/phil/docker/backup/backup-immich-photos.sh

# Check photo backup info
cat /mnt/backup/immich-photos/latest/backup-info.txt

Service Management

Start/Stop Services

# Netbird (includes Caddy)
cd /home/phil/docker/netbird
docker compose up -d    # Start
docker compose down    # Stop

# Gitea
cd /home/phil/docker/gitea
docker compose up -d
docker compose down

# Immich
cd /home/phil/docker/immich-app
docker compose up -d
docker compose down

View Logs

# Caddy (reverse proxy)
docker logs -f netbird-caddy-1

# Netbird
docker logs -f netbird-management-1

# Gitea
docker logs -f gitea

# Immich
docker logs -f immich_server

# Database backups
tail -f /var/log/vps-backup.log

# Photo backups
tail -f /var/log/immich-photo-backup.log

Disaster Recovery

Restore Immich Photos

# Stop Immich first
cd /home/phil/docker/immich-app
docker compose stop

# Restore all photos from latest backup
rsync -av /mnt/backup/immich-photos/latest/ /home/phil/docker/immich-app/library/

# Or restore specific date
rsync -av /mnt/backup/immich-photos/20260125_160319/ /home/phil/docker/immich-app/library/

# Restart Immich
docker compose start

Restore Immich Database

# From latest backup
gunzip < /mnt/backup/latest/immich-db.sql.gz | docker exec -i immich_postgres psql -U postgres immich

Restore Gitea

# Database
gunzip < /mnt/backup/latest/gitea-db.sql.gz | docker exec -i gitea-db psql -U gitea gitea

# Data volume
docker run --rm -v gitea_gitea_data:/data -v /mnt/backup/latest:/backup alpine tar xzf /backup/gitea-data.tar.gz -C /data

Restore Netbird

# Management data
docker run --rm -v netbird_netbird_management:/data -v /mnt/backup/latest:/backup alpine tar xzf /backup/netbird-management.tar.gz -C /data

Pending Tasks

1. Remote Backup Storage ⚠️

Action: Mount remote storage to /mnt/backup

Options:

  • S3 bucket via s3fs
  • NFS mount
  • SSHFS
  • WebDAV

Benefit: Off-site backup for disaster recovery

2. OIDC SSO Integration

Optional: Integrate Gitea and Immich with Netbird Zitadel for SSO

See:

  • docs/sso-integration-plan.md - Complete implementation guide
  • docs/oidc-integration-guide.md - Original setup guide

Benefits:

  • Unified authentication across all services
  • Centralized user management
  • Single sign-on

Important Notes

BACKUP STATUS

  • Immich Photos: Automated daily backup (04:00, 39GB, 30-day retention)
  • Immich Database: Automated daily backup (02:00, 52MB)
  • Gitea: Automated daily backup (02:00, database + data)
  • Netbird: Automated daily backup (02:00, management + database)

DO NOT DELETE

  • /home/phil/docker/immich-app/library/ - Contains 39GB of irreplaceable photos (now backed up)
  • /home/phil/docker/immich-app/postgres/ - Immich database with metadata
  • Docker volumes: gitea_gitea_*, immich_*, netbird_netbird_*

Security Reminders

  • All SSH access via key authentication only
  • UFW firewall blocks all non-essential ports
  • Fail2ban actively blocks brute force attempts
  • Daily backups of all databases (30-day retention)
  • SSL/TLS enforced for all services

System Upgrades

When upgrading containers:

  1. Always pull images first: docker compose pull
  2. Then restart: docker compose up -d
  3. Check logs: docker logs <container>
  4. Have backup ready before major upgrades

Contact & Support

System Admin: phil@phiiiil.de Documentation Location: /home/phil/Schreibtisch/Privat/vps/docs/

Documentation Files:

  • vps1-state-25012026.md (this file) - Current system state
  • vps1-startpoint.md - Initial analysis and architecture
  • vps1-todo.md - Action items and maintenance tasks
  • docs/deployment-summary.md - Deployment details
  • docs/oidc-integration-guide.md - SSO setup guide
  • docs/sso-integration-plan.md - Complete SSO implementation plan
  • docs/sso-integration-diagram.txt - SSO architecture diagrams
  • docs/immich-backup-implementation.md - Photo backup implementation

Changelog

2026-01-25 (Later)

  • Immich photo backup implemented (34,694 files, 39GB)
  • Automated daily backup at 04:00 using rsync
  • 30-day retention with hardlinking for space efficiency
  • rsync installed for backup operations
  • Complete backup coverage (databases + photos)
  • SSO integration plan created (ready to implement)

2026-01-25 (Earlier)

  • Security hardening (UFW + Fail2ban)
  • Gitea deployment with PostgreSQL
  • Automated database backup system implemented
  • DNS configured for all domains
  • SSL certificates obtained via Caddy
  • Nextcloud removed (FastCGI configuration issues)
  • System production ready

Last Updated: 2026-01-25 System Status: All services operational