Merge pull request #3 from efigueroa/claude/gitops-home-services-011CUqEzDETA2BqAzYUcXtjt
Claude/gitops home services
This commit is contained in:
commit
165c72818c
45 changed files with 4316 additions and 795 deletions
|
|
@ -5,9 +5,13 @@ LLDAP_LDAP_BASE_DN=dc=fig,dc=systems
|
|||
# Admin user configuration
|
||||
LLDAP_LDAP_USER_DN=admin
|
||||
LLDAP_LDAP_USER_EMAIL=admin@edfig.dev
|
||||
# Use a strong password (at least 16 characters, mix of letters, numbers, symbols)
|
||||
# Example format: MyS3cur3P@ssw0rd!2024#HomeL@b
|
||||
LLDAP_LDAP_USER_PASS=changeme_please_set_secure_password
|
||||
|
||||
# JWT secret for session management (change this!)
|
||||
# JWT secret for session management (64+ character random string)
|
||||
# Generate with: openssl rand -hex 32
|
||||
# Example format: a1b2c3d4e5f67890abcdef1234567890a1b2c3d4e5f67890abcdef1234567890
|
||||
LLDAP_JWT_SECRET=changeme_please_set_random_secret
|
||||
|
||||
# Database URL (SQLite by default)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ TZ=America/Los_Angeles
|
|||
LDAP_ADDRESS=ldap://lldap:3890
|
||||
LDAP_BASE_DN=dc=fig,dc=systems
|
||||
LDAP_BIND_DN=uid=admin,ou=people,dc=fig,dc=systems
|
||||
# Must match LLDAP_LDAP_USER_PASS in lldap/.env
|
||||
# Example format: MyS3cur3P@ssw0rd!2024#HomeL@b
|
||||
LDAP_BIND_PASSWORD=changeme_please_set_secure_password
|
||||
LDAP_SEARCH_FILTER=(uid=%s)
|
||||
LDAP_INSECURE=true
|
||||
|
|
@ -20,6 +22,8 @@ LDAP_INSECURE=true
|
|||
# USERS=
|
||||
|
||||
# Session configuration
|
||||
# Generate with: openssl rand -hex 32
|
||||
# Example format: b2c3d4e5f67890abcdef1234567890a1b2c3d4e5f67890abcdef1234567890ab
|
||||
SESSION_SECRET=changeme_please_set_random_session_secret
|
||||
SESSION_MAX_AGE=86400
|
||||
|
||||
|
|
|
|||
11
compose/media/automation/qbittorrent/.env
Normal file
11
compose/media/automation/qbittorrent/.env
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# qBittorrent Configuration
|
||||
|
||||
# User and Group IDs (run 'id' command to find yours)
|
||||
PUID=1000
|
||||
PGID=1000
|
||||
|
||||
# Timezone
|
||||
TZ=America/Los_Angeles
|
||||
|
||||
# WebUI Port
|
||||
WEBUI_PORT=8080
|
||||
|
|
@ -5,11 +5,8 @@ services:
|
|||
qbittorrent:
|
||||
container_name: qbittorrent
|
||||
image: lscr.io/linuxserver/qbittorrent:latest
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=America/Los_Angeles
|
||||
- WEBUI_PORT=8080
|
||||
env_file:
|
||||
- .env
|
||||
volumes:
|
||||
- ./config:/config
|
||||
- /media/downloads:/downloads
|
||||
|
|
|
|||
8
compose/media/automation/radarr/.env
Normal file
8
compose/media/automation/radarr/.env
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# Radarr Configuration
|
||||
|
||||
# User and Group IDs (run 'id' command to find yours)
|
||||
PUID=1000
|
||||
PGID=1000
|
||||
|
||||
# Timezone
|
||||
TZ=America/Los_Angeles
|
||||
|
|
@ -5,10 +5,8 @@ services:
|
|||
radarr:
|
||||
container_name: radarr
|
||||
image: lscr.io/linuxserver/radarr:latest
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=America/Los_Angeles
|
||||
env_file:
|
||||
- .env
|
||||
volumes:
|
||||
- ./config:/config
|
||||
# Media library
|
||||
|
|
|
|||
8
compose/media/automation/sabnzbd/.env
Normal file
8
compose/media/automation/sabnzbd/.env
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# SABnzbd Configuration
|
||||
|
||||
# User and Group IDs (run 'id' command to find yours)
|
||||
PUID=1000
|
||||
PGID=1000
|
||||
|
||||
# Timezone
|
||||
TZ=America/Los_Angeles
|
||||
|
|
@ -5,10 +5,8 @@ services:
|
|||
sabnzbd:
|
||||
container_name: sabnzbd
|
||||
image: lscr.io/linuxserver/sabnzbd:latest
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=America/Los_Angeles
|
||||
env_file:
|
||||
- .env
|
||||
volumes:
|
||||
- ./config:/config
|
||||
- /media/downloads:/downloads
|
||||
|
|
|
|||
8
compose/media/automation/sonarr/.env
Normal file
8
compose/media/automation/sonarr/.env
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# Sonarr Configuration
|
||||
|
||||
# User and Group IDs (run 'id' command to find yours)
|
||||
PUID=1000
|
||||
PGID=1000
|
||||
|
||||
# Timezone
|
||||
TZ=America/Los_Angeles
|
||||
|
|
@ -5,10 +5,8 @@ services:
|
|||
sonarr:
|
||||
container_name: sonarr
|
||||
image: lscr.io/linuxserver/sonarr:latest
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=America/Los_Angeles
|
||||
env_file:
|
||||
- .env
|
||||
volumes:
|
||||
- ./config:/config
|
||||
# Media library
|
||||
|
|
|
|||
|
|
@ -14,7 +14,9 @@ IMMICH_VERSION=V2.1.0
|
|||
|
||||
# Connection secret for postgres. You should change it to a random password
|
||||
# Please use only the characters `A-Za-z0-9`, without special characters or spaces
|
||||
#DB_PASSWORD=postgres
|
||||
# Generate with: openssl rand -base64 32 | tr -d /=+ | cut -c1-32
|
||||
# Example format: aB3dEf7HiJ9kLmN2oPqR5sTuV8wXyZ1
|
||||
DB_PASSWORD=changeme_please_set_secure_password
|
||||
|
||||
# The values below this line do not need to be changed
|
||||
###################################################################################
|
||||
|
|
|
|||
|
|
@ -77,13 +77,8 @@ services:
|
|||
database:
|
||||
container_name: immich_postgres
|
||||
image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:bcf63357191b76a916ae5eb93464d65c07511da41e3bf7a8416db519b40b1c23
|
||||
environment:
|
||||
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
||||
POSTGRES_USER: ${DB_USERNAME}
|
||||
POSTGRES_DB: ${DB_DATABASE_NAME}
|
||||
POSTGRES_INITDB_ARGS: '--data-checksums'
|
||||
# Uncomment the DB_STORAGE_TYPE: 'HDD' var if your database isn't stored on SSDs
|
||||
# DB_STORAGE_TYPE: 'HDD'
|
||||
env_file:
|
||||
- .env
|
||||
volumes:
|
||||
# Do not edit the next line. If you want to change the database storage location on your system, edit the value of DB_DATA_LOCATION in the .env file
|
||||
- ${DB_DATA_LOCATION}:/var/lib/postgresql/data
|
||||
|
|
|
|||
27
compose/media/frontend/jellyfin/.env
Normal file
27
compose/media/frontend/jellyfin/.env
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# Jellyfin Configuration
|
||||
|
||||
# User and Group IDs (run 'id' command to find yours)
|
||||
PUID=1000
|
||||
PGID=1000
|
||||
|
||||
# Timezone
|
||||
TZ=America/Los_Angeles
|
||||
|
||||
# Published server URL (for DLNA and discovery)
|
||||
JELLYFIN_PublishedServerUrl=https://flix.fig.systems
|
||||
|
||||
# NVIDIA GPU Transcoding (for GTX 1070)
|
||||
# Uncomment the lines below in compose.yaml to enable GPU transcoding:
|
||||
# 1. Uncomment 'runtime: nvidia' line
|
||||
# 2. Uncomment the 'deploy.resources.reservations.devices' section
|
||||
#
|
||||
# Prerequisites:
|
||||
# - Install NVIDIA Container Toolkit on host:
|
||||
# sudo apt install nvidia-container-toolkit
|
||||
# sudo nvidia-ctk runtime configure --runtime=docker
|
||||
# sudo systemctl restart docker
|
||||
#
|
||||
# - Verify GPU is available: docker run --rm --gpus all nvidia/cuda:11.8.0-base-ubuntu22.04 nvidia-smi
|
||||
#
|
||||
# In Jellyfin UI after enabling:
|
||||
# Dashboard → Playback → Transcoding → Hardware acceleration: NVIDIA NVENC
|
||||
|
|
@ -6,11 +6,8 @@ services:
|
|||
jellyfin:
|
||||
container_name: jellyfin
|
||||
image: lscr.io/linuxserver/jellyfin:latest
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=America/Los_Angeles
|
||||
- JELLYFIN_PublishedServerUrl=https://flix.fig.systems
|
||||
env_file:
|
||||
- .env
|
||||
volumes:
|
||||
- ./config:/config
|
||||
- ./cache:/cache
|
||||
|
|
@ -35,7 +32,9 @@ services:
|
|||
# Note: Jellyfin has its own auth system, SSO middleware disabled by default
|
||||
# Uncomment the line below to enable SSO (requires users to auth via tinyauth first)
|
||||
# traefik.http.routers.jellyfin.middlewares: tinyauth
|
||||
# Uncomment for NVIDIA GPU transcoding
|
||||
|
||||
# Uncomment for NVIDIA GPU transcoding (GTX 1070)
|
||||
# Requires NVIDIA Container Toolkit installed on host
|
||||
# runtime: nvidia
|
||||
# deploy:
|
||||
# resources:
|
||||
|
|
|
|||
11
compose/media/frontend/jellyseer/.env
Normal file
11
compose/media/frontend/jellyseer/.env
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# Jellyseerr Configuration
|
||||
|
||||
# Log Level (debug, info, warn, error)
|
||||
LOG_LEVEL=info
|
||||
|
||||
# Timezone
|
||||
TZ=America/Los_Angeles
|
||||
|
||||
# User and Group IDs
|
||||
PUID=1000
|
||||
PGID=1000
|
||||
|
|
@ -5,11 +5,8 @@ services:
|
|||
jellyseerr:
|
||||
container_name: jellyseerr
|
||||
image: fallenbagel/jellyseerr:latest
|
||||
environment:
|
||||
- LOG_LEVEL=info
|
||||
- TZ=America/Los_Angeles
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
env_file:
|
||||
- .env
|
||||
volumes:
|
||||
- ./config:/app/config
|
||||
restart: unless-stopped
|
||||
|
|
|
|||
8
compose/services/FreshRSS/.env
Normal file
8
compose/services/FreshRSS/.env
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# FreshRSS Configuration
|
||||
|
||||
# Timezone
|
||||
TZ=America/Los_Angeles
|
||||
|
||||
# User and Group IDs
|
||||
PUID=1000
|
||||
PGID=1000
|
||||
|
|
@ -5,23 +5,7 @@ services:
|
|||
freshrss:
|
||||
container_name: freshrss
|
||||
image: lscr.io/linuxserver/freshrss:latest
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=America/Los_Angeles
|
||||
volumes:
|
||||
- ./config:/config
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- homelab
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.http.routers.freshrss.rule: Host(`rss.fig.systems`) || Host(`rss.edfig.dev`)
|
||||
traefik.http.routers.freshrss.entrypoints: websecure
|
||||
traefik.http.routers.freshrss.tls.certresolver: letsencrypt
|
||||
traefik.http.services.freshrss.loadbalancer.server.port: 80
|
||||
traefik.http.routers.freshrss.middlewares: tinyauth
|
||||
|
||||
networks:
|
||||
homelab:
|
||||
external: true
|
||||
env_file:
|
||||
|
||||
- .env
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
# Backrest Configuration
|
||||
# Backrest provides a web UI for managing Restic backups
|
||||
|
||||
# Application Settings
|
||||
BACKREST_DATA=/data
|
||||
BACKREST_CONFIG=/config/config.json
|
||||
XDG_CACHE_HOME=/cache
|
||||
|
||||
# Timezone
|
||||
TZ=America/Los_Angeles
|
||||
|
||||
|
|
|
|||
|
|
@ -15,11 +15,8 @@ services:
|
|||
- /home/user/homelab/compose/media/frontend/immich/upload:/backups/immich:ro
|
||||
- /home/user/homelab/compose:/backups/homelab-config:ro
|
||||
|
||||
environment:
|
||||
- BACKREST_DATA=/data
|
||||
- BACKREST_CONFIG=/config/config.json
|
||||
- XDG_CACHE_HOME=/cache
|
||||
- TZ=${TZ:-America/Los_Angeles}
|
||||
env_file:
|
||||
- .env
|
||||
|
||||
labels:
|
||||
# Traefik
|
||||
|
|
|
|||
8
compose/services/booklore/.env
Normal file
8
compose/services/booklore/.env
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# Booklore Configuration
|
||||
|
||||
# Timezone
|
||||
TZ=America/Los_Angeles
|
||||
|
||||
# User and Group IDs
|
||||
PUID=1000
|
||||
PGID=1000
|
||||
|
|
@ -5,24 +5,7 @@ services:
|
|||
booklore:
|
||||
container_name: booklore
|
||||
image: ghcr.io/lorebooks/booklore:latest
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=America/Los_Angeles
|
||||
volumes:
|
||||
- ./config:/config
|
||||
- /media/books:/books:ro
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- homelab
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.http.routers.booklore.rule: Host(`booklore.fig.systems`) || Host(`booklore.edfig.dev`)
|
||||
traefik.http.routers.booklore.entrypoints: websecure
|
||||
traefik.http.routers.booklore.tls.certresolver: letsencrypt
|
||||
traefik.http.services.booklore.loadbalancer.server.port: 3000
|
||||
traefik.http.routers.booklore.middlewares: tinyauth
|
||||
|
||||
networks:
|
||||
homelab:
|
||||
external: true
|
||||
env_file:
|
||||
|
||||
- .env
|
||||
|
|
|
|||
11
compose/services/calibre-web/.env
Normal file
11
compose/services/calibre-web/.env
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# Calibre-web Configuration
|
||||
|
||||
# Timezone
|
||||
TZ=America/Los_Angeles
|
||||
|
||||
# User and Group IDs
|
||||
PUID=1000
|
||||
PGID=1000
|
||||
|
||||
# Docker mods (optional - for ebook conversion)
|
||||
# DOCKER_MODS=linuxserver/mods:universal-calibre
|
||||
|
|
@ -5,26 +5,7 @@ services:
|
|||
calibre-web:
|
||||
container_name: calibre-web
|
||||
image: lscr.io/linuxserver/calibre-web:latest
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=America/Los_Angeles
|
||||
- DOCKER_MODS=linuxserver/mods:universal-calibre
|
||||
- OAUTHLIB_RELAX_TOKEN_SCOPE=1
|
||||
volumes:
|
||||
- ./config:/config
|
||||
- /media/books:/books
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- homelab
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.http.routers.calibre-web.rule: Host(`books.fig.systems`) || Host(`books.edfig.dev`)
|
||||
traefik.http.routers.calibre-web.entrypoints: websecure
|
||||
traefik.http.routers.calibre-web.tls.certresolver: letsencrypt
|
||||
traefik.http.services.calibre-web.loadbalancer.server.port: 8083
|
||||
traefik.http.routers.calibre-web.middlewares: tinyauth
|
||||
|
||||
networks:
|
||||
homelab:
|
||||
external: true
|
||||
env_file:
|
||||
|
||||
- .env
|
||||
|
|
|
|||
8
compose/services/filebrowser/.env
Normal file
8
compose/services/filebrowser/.env
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# File Browser Configuration
|
||||
|
||||
# Timezone
|
||||
TZ=America/Los_Angeles
|
||||
|
||||
# User and Group IDs
|
||||
PUID=1000
|
||||
PGID=1000
|
||||
|
|
@ -5,25 +5,7 @@ services:
|
|||
filebrowser:
|
||||
container_name: filebrowser
|
||||
image: filebrowser/filebrowser:latest
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=America/Los_Angeles
|
||||
volumes:
|
||||
- ./config:/config
|
||||
- ./database:/database
|
||||
- /media:/srv
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- homelab
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.http.routers.filebrowser.rule: Host(`files.fig.systems`) || Host(`files.edfig.dev`)
|
||||
traefik.http.routers.filebrowser.entrypoints: websecure
|
||||
traefik.http.routers.filebrowser.tls.certresolver: letsencrypt
|
||||
traefik.http.services.filebrowser.loadbalancer.server.port: 80
|
||||
traefik.http.routers.filebrowser.middlewares: tinyauth
|
||||
|
||||
networks:
|
||||
homelab:
|
||||
external: true
|
||||
env_file:
|
||||
|
||||
- .env
|
||||
|
|
|
|||
14
compose/services/homarr/.env
Normal file
14
compose/services/homarr/.env
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# Homarr Configuration
|
||||
|
||||
# Timezone
|
||||
TZ=America/Los_Angeles
|
||||
|
||||
# Base path (if behind reverse proxy with path)
|
||||
# BASE_URL=/dashboard
|
||||
|
||||
# Port (default: 7575)
|
||||
PORT=7575
|
||||
|
||||
# Authentication
|
||||
# AUTH_PROVIDER=oidc # For SSO integration
|
||||
# DEFAULT_COLOR_SCHEME=dark
|
||||
|
|
@ -7,51 +7,6 @@ services:
|
|||
container_name: homarr
|
||||
image: ghcr.io/ajnart/homarr:latest
|
||||
|
||||
environment:
|
||||
# Timezone
|
||||
- TZ=America/Los_Angeles
|
||||
env_file:
|
||||
|
||||
# Base path (if behind reverse proxy with path)
|
||||
# - BASE_URL=/dashboard
|
||||
|
||||
# Port (default: 7575)
|
||||
- PORT=7575
|
||||
|
||||
# Authentication
|
||||
# - AUTH_PROVIDER=oidc # For SSO integration
|
||||
# - DEFAULT_COLOR_SCHEME=dark
|
||||
|
||||
volumes:
|
||||
# Configuration and data
|
||||
- ./config:/app/data/configs
|
||||
- ./data:/data
|
||||
- ./icons:/app/public/icons
|
||||
|
||||
# Docker socket for auto-discovery
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
|
||||
restart: unless-stopped
|
||||
|
||||
networks:
|
||||
- homelab
|
||||
|
||||
labels:
|
||||
traefik.enable: true
|
||||
|
||||
# Web UI routing
|
||||
traefik.http.routers.homarr.rule: Host(`home.fig.systems`) || Host(`home.edfig.dev`)
|
||||
traefik.http.routers.homarr.entrypoints: websecure
|
||||
traefik.http.routers.homarr.tls.certresolver: letsencrypt
|
||||
traefik.http.services.homarr.loadbalancer.server.port: 7575
|
||||
|
||||
# SSO Protection (optional - dashboard may be public)
|
||||
# traefik.http.routers.homarr.middlewares: tinyauth
|
||||
|
||||
# Homarr Labels for custom configuration
|
||||
homarr.name: Homarr Dashboard
|
||||
homarr.group: Infrastructure
|
||||
homarr.icon: /icons/homarr.png
|
||||
|
||||
networks:
|
||||
homelab:
|
||||
external: true
|
||||
- .env
|
||||
|
|
|
|||
|
|
@ -1,473 +1,65 @@
|
|||
NEXTAUTH_URL=http://localhost:3000/api/v1/auth
|
||||
NEXTAUTH_SECRET=
|
||||
|
||||
# Manual installation database settings
|
||||
# Example: DATABASE_URL=postgresql://user:password@localhost:5432/linkwarden
|
||||
DATABASE_URL=
|
||||
|
||||
# Docker installation database settings
|
||||
POSTGRES_PASSWORD=
|
||||
|
||||
# Additional Optional Settings
|
||||
PAGINATION_TAKE_COUNT=
|
||||
STORAGE_FOLDER=
|
||||
AUTOSCROLL_TIMEOUT=
|
||||
NEXT_PUBLIC_DISABLE_REGISTRATION=
|
||||
NEXT_PUBLIC_CREDENTIALS_ENABLED=
|
||||
DISABLE_NEW_SSO_USERS=
|
||||
MAX_LINKS_PER_USER=
|
||||
ARCHIVE_TAKE_COUNT=
|
||||
BROWSER_TIMEOUT=
|
||||
IGNORE_UNAUTHORIZED_CA=
|
||||
IGNORE_HTTPS_ERRORS=
|
||||
IGNORE_URL_SIZE_LIMIT=
|
||||
NEXT_PUBLIC_DEMO=
|
||||
NEXT_PUBLIC_DEMO_USERNAME=
|
||||
NEXT_PUBLIC_DEMO_PASSWORD=
|
||||
NEXT_PUBLIC_ADMIN=
|
||||
NEXT_PUBLIC_MAX_FILE_BUFFER=
|
||||
PDF_MAX_BUFFER=
|
||||
SCREENSHOT_MAX_BUFFER=
|
||||
READABILITY_MAX_BUFFER=
|
||||
PREVIEW_MAX_BUFFER=
|
||||
MONOLITH_MAX_BUFFER=
|
||||
MONOLITH_CUSTOM_OPTIONS=
|
||||
IMPORT_LIMIT=
|
||||
PLAYWRIGHT_LAUNCH_OPTIONS_EXECUTABLE_PATH=
|
||||
PLAYWRIGHT_WS_URL=
|
||||
MAX_WORKERS=
|
||||
DISABLE_PRESERVATION=
|
||||
NEXT_PUBLIC_RSS_POLLING_INTERVAL_MINUTES=
|
||||
RSS_SUBSCRIPTION_LIMIT_PER_USER=
|
||||
TEXT_CONTENT_LIMIT=
|
||||
SEARCH_FILTER_LIMIT=
|
||||
INDEX_TAKE_COUNT=
|
||||
MEILI_TIMEOUT=
|
||||
|
||||
# AI Settings
|
||||
NEXT_PUBLIC_OLLAMA_ENDPOINT_URL=
|
||||
OLLAMA_MODEL=
|
||||
|
||||
# https://ai-sdk.dev/providers/openai-compatible-providers
|
||||
OPENAI_API_KEY=
|
||||
OPENAI_MODEL=
|
||||
# Optional: Set a custom OpenAI base URL and name (for third-party providers)
|
||||
CUSTOM_OPENAI_BASE_URL=
|
||||
CUSTOM_OPENAI_NAME=
|
||||
|
||||
# https://sdk.vercel.ai/providers/ai-sdk-providers/azure
|
||||
AZURE_API_KEY=
|
||||
AZURE_RESOURCE_NAME=
|
||||
AZURE_MODEL=
|
||||
|
||||
# https://sdk.vercel.ai/providers/ai-sdk-providers/anthropic
|
||||
ANTHROPIC_API_KEY=
|
||||
ANTHROPIC_MODEL=
|
||||
|
||||
# https://github.com/OpenRouterTeam/ai-sdk-provider
|
||||
OPENROUTER_API_KEY=
|
||||
OPENROUTER_MODEL=
|
||||
|
||||
# https://ai-sdk.dev/providers/ai-sdk-providers/perplexity
|
||||
PERPLEXITY_API_KEY=
|
||||
PERPLEXITY_MODEL=
|
||||
|
||||
# MeiliSearch Settings
|
||||
MEILI_HOST=
|
||||
MEILI_MASTER_KEY=
|
||||
|
||||
# AWS S3 Settings
|
||||
SPACES_KEY=
|
||||
SPACES_SECRET=
|
||||
SPACES_ENDPOINT=
|
||||
SPACES_BUCKET_NAME=
|
||||
SPACES_REGION=
|
||||
SPACES_FORCE_PATH_STYLE=
|
||||
|
||||
# SMTP Settings
|
||||
NEXT_PUBLIC_EMAIL_PROVIDER=
|
||||
EMAIL_FROM=
|
||||
EMAIL_SERVER=
|
||||
BASE_URL=
|
||||
|
||||
# Proxy settings
|
||||
PROXY=
|
||||
PROXY_USERNAME=
|
||||
PROXY_PASSWORD=
|
||||
PROXY_BYPASS=
|
||||
|
||||
# PDF archive settings
|
||||
PDF_MARGIN_TOP=
|
||||
PDF_MARGIN_BOTTOM=
|
||||
|
||||
#################
|
||||
# SSO Providers #
|
||||
#################
|
||||
|
||||
# 42 School
|
||||
NEXT_PUBLIC_FORTYTWO_ENABLED=
|
||||
FORTYTWO_CUSTOM_NAME=
|
||||
FORTYTWO_CLIENT_ID=
|
||||
FORTYTWO_CLIENT_SECRET=
|
||||
|
||||
# Apple
|
||||
NEXT_PUBLIC_APPLE_ENABLED=
|
||||
APPLE_CUSTOM_NAME=
|
||||
APPLE_ID=
|
||||
APPLE_SECRET=
|
||||
|
||||
# Atlassian
|
||||
NEXT_PUBLIC_ATLASSIAN_ENABLED=
|
||||
ATLASSIAN_CUSTOM_NAME=
|
||||
ATLASSIAN_CLIENT_ID=
|
||||
ATLASSIAN_CLIENT_SECRET=
|
||||
ATLASSIAN_SCOPE=
|
||||
|
||||
# Auth0
|
||||
NEXT_PUBLIC_AUTH0_ENABLED=
|
||||
AUTH0_CUSTOM_NAME=
|
||||
AUTH0_ISSUER=
|
||||
AUTH0_CLIENT_SECRET=
|
||||
AUTH0_CLIENT_ID=
|
||||
|
||||
# Authelia
|
||||
NEXT_PUBLIC_AUTHELIA_ENABLED=""
|
||||
AUTHELIA_CLIENT_ID=""
|
||||
AUTHELIA_CLIENT_SECRET=""
|
||||
AUTHELIA_WELLKNOWN_URL=""
|
||||
|
||||
# Authentik
|
||||
NEXT_PUBLIC_AUTHENTIK_ENABLED=
|
||||
AUTHENTIK_CUSTOM_NAME=
|
||||
AUTHENTIK_ISSUER=
|
||||
AUTHENTIK_CLIENT_ID=
|
||||
AUTHENTIK_CLIENT_SECRET=
|
||||
|
||||
# Azure AD B2C
|
||||
NEXT_PUBLIC_AZURE_AD_B2C_ENABLED=
|
||||
AZURE_AD_B2C_TENANT_NAME=
|
||||
AZURE_AD_B2C_CLIENT_ID=
|
||||
AZURE_AD_B2C_CLIENT_SECRET=
|
||||
AZURE_AD_B2C_PRIMARY_USER_FLOW=
|
||||
|
||||
# Azure AD
|
||||
NEXT_PUBLIC_AZURE_AD_ENABLED=
|
||||
AZURE_AD_CLIENT_ID=
|
||||
AZURE_AD_CLIENT_SECRET=
|
||||
AZURE_AD_TENANT_ID=
|
||||
|
||||
# Battle.net
|
||||
NEXT_PUBLIC_BATTLENET_ENABLED=
|
||||
BATTLENET_CUSTOM_NAME=
|
||||
BATTLENET_CLIENT_ID=
|
||||
BATTLENET_CLIENT_SECRET=
|
||||
BATTLENET_ISSUER=
|
||||
|
||||
# Box
|
||||
NEXT_PUBLIC_BOX_ENABLED=
|
||||
BOX_CUSTOM_NAME=
|
||||
BOX_CLIENT_ID=
|
||||
BOX_CLIENT_SECRET=
|
||||
|
||||
# Bungie
|
||||
NEXT_PUBLIC_BUNGIE_ENABLED=
|
||||
BUNGIE_CUSTOM_NAME=
|
||||
BUNGIE_CLIENT_ID=
|
||||
BUNGIE_CLIENT_SECRET=
|
||||
BUNGIE_API_KEY=
|
||||
|
||||
# Cognito
|
||||
NEXT_PUBLIC_COGNITO_ENABLED=
|
||||
COGNITO_CUSTOM_NAME=
|
||||
COGNITO_CLIENT_ID=
|
||||
COGNITO_CLIENT_SECRET=
|
||||
COGNITO_ISSUER=
|
||||
|
||||
# Coinbase
|
||||
NEXT_PUBLIC_COINBASE_ENABLED=
|
||||
COINBASE_CUSTOM_NAME=
|
||||
COINBASE_CLIENT_ID=
|
||||
COINBASE_CLIENT_SECRET=
|
||||
|
||||
# Discord
|
||||
NEXT_PUBLIC_DISCORD_ENABLED=
|
||||
DISCORD_CUSTOM_NAME=
|
||||
DISCORD_CLIENT_ID=
|
||||
DISCORD_CLIENT_SECRET=
|
||||
|
||||
# Dropbox
|
||||
NEXT_PUBLIC_DROPBOX_ENABLED=
|
||||
DROPBOX_CUSTOM_NAME=
|
||||
DROPBOX_CLIENT_ID=
|
||||
DROPBOX_CLIENT_SECRET=
|
||||
|
||||
# DuendeIndentityServer6
|
||||
NEXT_PUBLIC_DUENDE_IDS6_ENABLED=
|
||||
DUENDE_IDS6_CUSTOM_NAME=
|
||||
DUENDE_IDS6_CLIENT_ID=
|
||||
DUENDE_IDS6_CLIENT_SECRET=
|
||||
DUENDE_IDS6_ISSUER=
|
||||
|
||||
# EVE Online
|
||||
NEXT_PUBLIC_EVEONLINE_ENABLED=
|
||||
EVEONLINE_CUSTOM_NAME=
|
||||
EVEONLINE_CLIENT_ID=
|
||||
EVEONLINE_CLIENT_SECRET=
|
||||
|
||||
# Facebook
|
||||
NEXT_PUBLIC_FACEBOOK_ENABLED=
|
||||
FACEBOOK_CUSTOM_NAME=
|
||||
FACEBOOK_CLIENT_ID=
|
||||
FACEBOOK_CLIENT_SECRET=
|
||||
|
||||
# FACEIT
|
||||
NEXT_PUBLIC_FACEIT_ENABLED=
|
||||
FACEIT_CUSTOM_NAME=
|
||||
FACEIT_CLIENT_ID=
|
||||
FACEIT_CLIENT_SECRET=
|
||||
|
||||
# Foursquare
|
||||
NEXT_PUBLIC_FOURSQUARE_ENABLED=
|
||||
FOURSQUARE_CUSTOM_NAME=
|
||||
FOURSQUARE_CLIENT_ID=
|
||||
FOURSQUARE_CLIENT_SECRET=
|
||||
FOURSQUARE_APIVERSION=
|
||||
|
||||
# Freshbooks
|
||||
NEXT_PUBLIC_FRESHBOOKS_ENABLED=
|
||||
FRESHBOOKS_CUSTOM_NAME=
|
||||
FRESHBOOKS_CLIENT_ID=
|
||||
FRESHBOOKS_CLIENT_SECRET=
|
||||
|
||||
# FusionAuth
|
||||
NEXT_PUBLIC_FUSIONAUTH_ENABLED=
|
||||
FUSIONAUTH_CUSTOM_NAME=
|
||||
FUSIONAUTH_CLIENT_ID=
|
||||
FUSIONAUTH_CLIENT_SECRET=
|
||||
FUSIONAUTH_ISSUER=
|
||||
FUSIONAUTH_TENANT_ID=
|
||||
|
||||
# GitHub
|
||||
NEXT_PUBLIC_GITHUB_ENABLED=
|
||||
GITHUB_CUSTOM_NAME=
|
||||
GITHUB_ID=
|
||||
GITHUB_SECRET=
|
||||
|
||||
# GitLab
|
||||
NEXT_PUBLIC_GITLAB_ENABLED=
|
||||
GITLAB_CUSTOM_NAME=
|
||||
GITLAB_CLIENT_ID=
|
||||
GITLAB_CLIENT_SECRET=
|
||||
GITLAB_AUTH_URL=
|
||||
|
||||
# Google
|
||||
NEXT_PUBLIC_GOOGLE_ENABLED=
|
||||
GOOGLE_CUSTOM_NAME=
|
||||
GOOGLE_CLIENT_ID=
|
||||
GOOGLE_CLIENT_SECRET=
|
||||
|
||||
# HubSpot
|
||||
NEXT_PUBLIC_HUBSPOT_ENABLED=
|
||||
HUBSPOT_CUSTOM_NAME=
|
||||
HUBSPOT_CLIENT_ID=
|
||||
HUBSPOT_CLIENT_SECRET=
|
||||
|
||||
# IdentityServer4
|
||||
NEXT_PUBLIC_IDS4_ENABLED=
|
||||
IDS4_CUSTOM_NAME=
|
||||
IDS4_CLIENT_ID=
|
||||
IDS4_CLIENT_SECRET=
|
||||
IDS4_ISSUER=
|
||||
|
||||
# Kakao
|
||||
NEXT_PUBLIC_KAKAO_ENABLED=
|
||||
KAKAO_CUSTOM_NAME=
|
||||
KAKAO_CLIENT_ID=
|
||||
KAKAO_CLIENT_SECRET=
|
||||
|
||||
# Keycloak
|
||||
NEXT_PUBLIC_KEYCLOAK_ENABLED=
|
||||
KEYCLOAK_CUSTOM_NAME=
|
||||
KEYCLOAK_ISSUER=
|
||||
KEYCLOAK_CLIENT_ID=
|
||||
KEYCLOAK_CLIENT_SECRET=
|
||||
|
||||
# LINE
|
||||
NEXT_PUBLIC_LINE_ENABLED=
|
||||
LINE_CUSTOM_NAME=
|
||||
LINE_CLIENT_ID=
|
||||
LINE_CLIENT_SECRET=
|
||||
|
||||
# LinkedIn
|
||||
NEXT_PUBLIC_LINKEDIN_ENABLED=
|
||||
LINKEDIN_CUSTOM_NAME=
|
||||
LINKEDIN_CLIENT_ID=
|
||||
LINKEDIN_CLIENT_SECRET=
|
||||
|
||||
# Mailchimp
|
||||
NEXT_PUBLIC_MAILCHIMP_ENABLED=
|
||||
MAILCHIMP_CUSTOM_NAME=
|
||||
MAILCHIMP_CLIENT_ID=
|
||||
MAILCHIMP_CLIENT_SECRET=
|
||||
|
||||
# Mail.ru
|
||||
NEXT_PUBLIC_MAILRU_ENABLED=
|
||||
MAILRU_CUSTOM_NAME=
|
||||
MAILRU_CLIENT_ID=
|
||||
MAILRU_CLIENT_SECRET=
|
||||
|
||||
# Naver
|
||||
NEXT_PUBLIC_NAVER_ENABLED=
|
||||
NAVER_CUSTOM_NAME=
|
||||
NAVER_CLIENT_ID=
|
||||
NAVER_CLIENT_SECRET=
|
||||
|
||||
# Netlify
|
||||
NEXT_PUBLIC_NETLIFY_ENABLED=
|
||||
NETLIFY_CUSTOM_NAME=
|
||||
NETLIFY_CLIENT_ID=
|
||||
NETLIFY_CLIENT_SECRET=
|
||||
|
||||
# Okta
|
||||
NEXT_PUBLIC_OKTA_ENABLED=
|
||||
OKTA_CUSTOM_NAME=
|
||||
OKTA_CLIENT_ID=
|
||||
OKTA_CLIENT_SECRET=
|
||||
OKTA_ISSUER=
|
||||
|
||||
# OneLogin
|
||||
NEXT_PUBLIC_ONELOGIN_ENABLED=
|
||||
ONELOGIN_CUSTOM_NAME=
|
||||
ONELOGIN_CLIENT_ID=
|
||||
ONELOGIN_CLIENT_SECRET=
|
||||
ONELOGIN_ISSUER=
|
||||
|
||||
# Osso
|
||||
NEXT_PUBLIC_OSSO_ENABLED=
|
||||
OSSO_CUSTOM_NAME=
|
||||
OSSO_CLIENT_ID=
|
||||
OSSO_CLIENT_SECRET=
|
||||
OSSO_ISSUER=
|
||||
|
||||
# osu!
|
||||
NEXT_PUBLIC_OSU_ENABLED=
|
||||
OSU_CUSTOM_NAME=
|
||||
OSU_CLIENT_ID=
|
||||
OSU_CLIENT_SECRET=
|
||||
|
||||
# Patreon
|
||||
NEXT_PUBLIC_PATREON_ENABLED=
|
||||
PATREON_CUSTOM_NAME=
|
||||
PATREON_CLIENT_ID=
|
||||
PATREON_CLIENT_SECRET=
|
||||
|
||||
# Pinterest
|
||||
NEXT_PUBLIC_PINTEREST_ENABLED=
|
||||
PINTEREST_CUSTOM_NAME=
|
||||
PINTEREST_CLIENT_ID=
|
||||
PINTEREST_CLIENT_SECRET=
|
||||
|
||||
# Pipedrive
|
||||
NEXT_PUBLIC_PIPEDRIVE_ENABLED=
|
||||
PIPEDRIVE_CUSTOM_NAME=
|
||||
PIPEDRIVE_CLIENT_ID=
|
||||
PIPEDRIVE_CLIENT_SECRET=
|
||||
|
||||
# Reddit
|
||||
NEXT_PUBLIC_REDDIT_ENABLED=
|
||||
REDDIT_CUSTOM_NAME=
|
||||
REDDIT_CLIENT_ID=
|
||||
REDDIT_CLIENT_SECRET=
|
||||
|
||||
# Salesforce
|
||||
NEXT_PUBLIC_SALESFORCE_ENABLED=
|
||||
SALESFORCE_CUSTOM_NAME=
|
||||
SALESFORCE_CLIENT_ID=
|
||||
SALESFORCE_CLIENT_SECRET=
|
||||
|
||||
# Slack
|
||||
NEXT_PUBLIC_SLACK_ENABLED=
|
||||
SLACK_CUSTOM_NAME=
|
||||
SLACK_CLIENT_ID=
|
||||
SLACK_CLIENT_SECRET=
|
||||
|
||||
# Spotify
|
||||
NEXT_PUBLIC_SPOTIFY_ENABLED=
|
||||
SPOTIFY_CUSTOM_NAME=
|
||||
SPOTIFY_CLIENT_ID=
|
||||
SPOTIFY_CLIENT_SECRET=
|
||||
|
||||
# Strava
|
||||
NEXT_PUBLIC_STRAVA_ENABLED=
|
||||
STRAVA_CUSTOM_NAME=
|
||||
STRAVA_CLIENT_ID=
|
||||
STRAVA_CLIENT_SECRET=
|
||||
|
||||
# Synology
|
||||
NEXT_PUBLIC_SYNOLOGY_ENABLED=
|
||||
SYNOLOGY_CUSTOM_NAME=
|
||||
SYNOLOGY_CLIENT_ID=
|
||||
SYNOLOGY_CLIENT_SECRET=
|
||||
SYNOLOGY_WELLKNOWN_URL=
|
||||
|
||||
# Todoist
|
||||
NEXT_PUBLIC_TODOIST_ENABLED=
|
||||
TODOIST_CUSTOM_NAME=
|
||||
TODOIST_CLIENT_ID=
|
||||
TODOIST_CLIENT_SECRET=
|
||||
|
||||
# Twitch
|
||||
NEXT_PUBLIC_TWITCH_ENABLED=
|
||||
TWITCH_CUSTOM_NAME=
|
||||
TWITCH_CLIENT_ID=
|
||||
TWITCH_CLIENT_SECRET=
|
||||
|
||||
# United Effects
|
||||
NEXT_PUBLIC_UNITED_EFFECTS_ENABLED=
|
||||
UNITED_EFFECTS_CUSTOM_NAME=
|
||||
UNITED_EFFECTS_CLIENT_ID=
|
||||
UNITED_EFFECTS_CLIENT_SECRET=
|
||||
UNITED_EFFECTS_ISSUER=
|
||||
|
||||
# VK
|
||||
NEXT_PUBLIC_VK_ENABLED=
|
||||
VK_CUSTOM_NAME=
|
||||
VK_CLIENT_ID=
|
||||
VK_CLIENT_SECRET=
|
||||
|
||||
# Wikimedia
|
||||
NEXT_PUBLIC_WIKIMEDIA_ENABLED=
|
||||
WIKIMEDIA_CUSTOM_NAME=
|
||||
WIKIMEDIA_CLIENT_ID=
|
||||
WIKIMEDIA_CLIENT_SECRET=
|
||||
|
||||
# Wordpress.com
|
||||
NEXT_PUBLIC_WORDPRESS_ENABLED=
|
||||
WORDPRESS_CUSTOM_NAME=
|
||||
WORDPRESS_CLIENT_ID=
|
||||
WORDPRESS_CLIENT_SECRET=
|
||||
|
||||
# Yandex
|
||||
NEXT_PUBLIC_YANDEX_ENABLED=
|
||||
YANDEX_CUSTOM_NAME=
|
||||
YANDEX_CLIENT_ID=
|
||||
YANDEX_CLIENT_SECRET=
|
||||
|
||||
# Zitadel
|
||||
NEXT_PUBLIC_ZITADEL_ENABLED=
|
||||
ZITADEL_CUSTOM_NAME=
|
||||
ZITADEL_CLIENT_ID=
|
||||
ZITADEL_CLIENT_SECRET=
|
||||
ZITADEL_ISSUER=
|
||||
|
||||
# Zoho
|
||||
NEXT_PUBLIC_ZOHO_ENABLED=
|
||||
ZOHO_CUSTOM_NAME=
|
||||
ZOHO_CLIENT_ID=
|
||||
ZOHO_CLIENT_SECRET=
|
||||
|
||||
# Zoom
|
||||
NEXT_PUBLIC_ZOOM_ENABLED=
|
||||
ZOOM_CUSTOM_NAME=
|
||||
ZOOM_CLIENT_ID=
|
||||
ZOOM_CLIENT_SECRET=
|
||||
# Linkwarden Configuration
|
||||
# Docs: https://docs.linkwarden.app/self-hosting/environment-variables
|
||||
|
||||
# NextAuth Configuration
|
||||
NEXTAUTH_URL=https://links.fig.systems
|
||||
# Generate with: openssl rand -hex 32
|
||||
# Example format: e4f5g6h789012abcdef345678901a2b3c4d5e6f78901abcdef2345678901abcde
|
||||
NEXTAUTH_SECRET=changeme_please_set_random_secret_key
|
||||
|
||||
# Database Configuration
|
||||
# Generate with: openssl rand -base64 32 | tr -d /=+ | cut -c1-32
|
||||
# Example format: eF7gH0iI3jK5lM8nO1pQ4rS7tU0vW3xY
|
||||
POSTGRES_PASSWORD=changeme_please_set_secure_postgres_password
|
||||
POSTGRES_USER=postgres
|
||||
POSTGRES_DB=postgres
|
||||
DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@linkwarden-postgres:5432/postgres
|
||||
|
||||
# Meilisearch (search engine)
|
||||
# Generate with: openssl rand -hex 16
|
||||
# Example format: f6g7h8i901234abcdef567890a1b2c3d
|
||||
MEILI_MASTER_KEY=changeme_please_set_meili_master_key
|
||||
|
||||
# Timezone
|
||||
TZ=America/Los_Angeles
|
||||
|
||||
# Optional: Registration Control
|
||||
# NEXT_PUBLIC_DISABLE_REGISTRATION=true
|
||||
|
||||
# Optional: Credentials Authentication
|
||||
# NEXT_PUBLIC_CREDENTIALS_ENABLED=true
|
||||
|
||||
# Optional: Pagination
|
||||
# PAGINATION_TAKE_COUNT=20
|
||||
|
||||
# Optional: Storage folder (for screenshots/PDFs)
|
||||
# STORAGE_FOLDER=data
|
||||
|
||||
# Optional: Limits
|
||||
# MAX_LINKS_PER_USER=unlimited
|
||||
# NEXT_PUBLIC_MAX_FILE_BUFFER=10485760 # 10MB in bytes
|
||||
# PDF_MAX_BUFFER=10485760
|
||||
# SCREENSHOT_MAX_BUFFER=10485760
|
||||
|
||||
# Optional: Browser timeout for archiving (in milliseconds)
|
||||
# BROWSER_TIMEOUT=30000
|
||||
# AUTOSCROLL_TIMEOUT=30
|
||||
|
||||
# Optional: Archive settings
|
||||
# ARCHIVE_TAKE_COUNT=5
|
||||
|
||||
# Optional: Security
|
||||
# IGNORE_UNAUTHORIZED_CA=false
|
||||
# IGNORE_HTTPS_ERRORS=false
|
||||
# IGNORE_URL_SIZE_LIMIT=false
|
||||
|
||||
# Optional: SSO Settings
|
||||
# DISABLE_NEW_SSO_USERS=false
|
||||
|
||||
# Optional: Demo Mode
|
||||
# NEXT_PUBLIC_DEMO=false
|
||||
# NEXT_PUBLIC_DEMO_USERNAME=
|
||||
# NEXT_PUBLIC_DEMO_PASSWORD=
|
||||
|
||||
# Optional: Admin Panel
|
||||
# NEXT_PUBLIC_ADMIN=false
|
||||
|
|
|
|||
|
|
@ -6,9 +6,6 @@ services:
|
|||
container_name: linkwarden
|
||||
image: ghcr.io/linkwarden/linkwarden:latest
|
||||
env_file: .env
|
||||
environment:
|
||||
- DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@linkwarden-postgres:5432/postgres
|
||||
- TZ=America/Los_Angeles
|
||||
volumes:
|
||||
- ./data:/data/data
|
||||
depends_on:
|
||||
|
|
@ -31,8 +28,6 @@ services:
|
|||
container_name: linkwarden-postgres
|
||||
image: postgres:16-alpine
|
||||
env_file: .env
|
||||
environment:
|
||||
- TZ=America/Los_Angeles
|
||||
volumes:
|
||||
- ./pgdata:/var/lib/postgresql/data
|
||||
restart: always
|
||||
|
|
@ -48,8 +43,6 @@ services:
|
|||
container_name: linkwarden-meilisearch
|
||||
image: getmeili/meilisearch:v1.12.8
|
||||
env_file: .env
|
||||
environment:
|
||||
- TZ=America/Los_Angeles
|
||||
volumes:
|
||||
- ./meili_data:/meili_data
|
||||
restart: always
|
||||
|
|
|
|||
15
compose/services/lubelogger/.env
Normal file
15
compose/services/lubelogger/.env
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# LubeLogger Configuration
|
||||
|
||||
# Timezone
|
||||
TZ=America/Los_Angeles
|
||||
|
||||
# LC_ALL locale setting
|
||||
LC_ALL=en_US.UTF-8
|
||||
|
||||
# LANG locale setting
|
||||
LANG=en_US.UTF-8
|
||||
|
||||
# Enable OpenID (for SSO integration)
|
||||
# ENABLE_OPENID=true
|
||||
# OPENID_CLIENT_ID=your-client-id
|
||||
# OPENID_CLIENT_SECRET=your-client-secret
|
||||
|
|
@ -5,26 +5,7 @@ services:
|
|||
lubelogger:
|
||||
container_name: lubelogger
|
||||
image: ghcr.io/hargata/lubelogger:latest
|
||||
environment:
|
||||
- TZ=America/Los_Angeles
|
||||
volumes:
|
||||
- data:/App/data
|
||||
- keys:/root/.aspnet/DataProtection-Keys
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- homelab
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.http.routers.lubelogger.rule: Host(`garage.fig.systems`) || Host(`garage.edfig.dev`)
|
||||
traefik.http.routers.lubelogger.entrypoints: websecure
|
||||
traefik.http.routers.lubelogger.tls.certresolver: letsencrypt
|
||||
traefik.http.services.lubelogger.loadbalancer.server.port: 8080
|
||||
traefik.http.routers.lubelogger.middlewares: tinyauth
|
||||
|
||||
networks:
|
||||
homelab:
|
||||
external: true
|
||||
env_file:
|
||||
|
||||
volumes:
|
||||
data:
|
||||
keys:
|
||||
- .env
|
||||
|
|
|
|||
|
|
@ -6,49 +6,6 @@ services:
|
|||
container_name: microbin
|
||||
image: danielszabo99/microbin:latest
|
||||
env_file: .env
|
||||
environment:
|
||||
MICROBIN_BASIC_AUTH_USERNAME: ${MICROBIN_BASIC_AUTH_USERNAME}
|
||||
MICROBIN_BASIC_AUTH_PASSWORD: ${MICROBIN_BASIC_AUTH_PASSWORD}
|
||||
MICROBIN_ADMIN_USERNAME: ${MICROBIN_ADMIN_USERNAME}
|
||||
MICROBIN_ADMIN_PASSWORD: ${MICROBIN_ADMIN_PASSWORD}
|
||||
MICROBIN_EDITABLE: ${MICROBIN_EDITABLE}
|
||||
MICROBIN_FOOTER_TEXT: ${MICROBIN_FOOTER_TEXT}
|
||||
MICROBIN_HIDE_FOOTER: ${MICROBIN_HIDE_FOOTER}
|
||||
MICROBIN_HIDE_HEADER: ${MICROBIN_HIDE_HEADER}
|
||||
MICROBIN_HIDE_LOGO: ${MICROBIN_HIDE_LOGO}
|
||||
MICROBIN_NO_LISTING: ${MICROBIN_NO_LISTING}
|
||||
MICROBIN_HIGHLIGHTSYNTAX: ${MICROBIN_HIGHLIGHTSYNTAX}
|
||||
MICROBIN_BIND: ${MICROBIN_BIND}
|
||||
MICROBIN_PRIVATE: ${MICROBIN_PRIVATE}
|
||||
MICROBIN_PURE_HTML: ${MICROBIN_PURE_HTML}
|
||||
MICROBIN_DATA_DIR: ${MICROBIN_DATA_DIR}
|
||||
MICROBIN_JSON_DB: ${MICROBIN_JSON_DB}
|
||||
MICROBIN_PUBLIC_PATH: ${MICROBIN_PUBLIC_PATH}
|
||||
MICROBIN_SHORT_PATH: ${MICROBIN_SHORT_PATH}
|
||||
MICROBIN_READONLY: ${MICROBIN_READONLY}
|
||||
MICROBIN_UPLOADER_PASSWORD: ${MICROBIN_UPLOADER_PASSWORD}
|
||||
MICROBIN_SHOW_READ_STATS: ${MICROBIN_SHOW_READ_STATS}
|
||||
MICROBIN_TITLE: ${MICROBIN_TITLE}
|
||||
MICROBIN_THREADS: ${MICROBIN_THREADS}
|
||||
MICROBIN_GC_DAYS: ${MICROBIN_GC_DAYS}
|
||||
MICROBIN_ENABLE_BURN_AFTER: ${MICROBIN_ENABLE_BURN_AFTER}
|
||||
MICROBIN_DEFAULT_BURN_AFTER: ${MICROBIN_DEFAULT_BURN_AFTER}
|
||||
MICROBIN_WIDE: ${MICROBIN_WIDE}
|
||||
MICROBIN_QR: ${MICROBIN_QR}
|
||||
MICROBIN_ETERNAL_PASTA: ${MICROBIN_ETERNAL_PASTA}
|
||||
MICROBIN_ENABLE_READONLY: ${MICROBIN_ENABLE_READONLY}
|
||||
MICROBIN_DEFAULT_EXPIRY: ${MICROBIN_DEFAULT_EXPIRY}
|
||||
MICROBIN_NO_FILE_UPLOAD: ${MICROBIN_NO_FILE_UPLOAD}
|
||||
MICROBIN_CUSTOM_CSS: ${MICROBIN_CUSTOM_CSS}
|
||||
MICROBIN_HASH_IDS: ${MICROBIN_HASH_IDS}
|
||||
MICROBIN_ENCRYPTION_CLIENT_SIDE: ${MICROBIN_ENCRYPTION_CLIENT_SIDE}
|
||||
MICROBIN_ENCRYPTION_SERVER_SIDE: ${MICROBIN_ENCRYPTION_SERVER_SIDE}
|
||||
MICROBIN_MAX_FILE_SIZE_ENCRYPTED_MB: ${MICROBIN_MAX_FILE_SIZE_ENCRYPTED_MB}
|
||||
MICROBIN_MAX_FILE_SIZE_UNENCRYPTED_MB: ${MICROBIN_MAX_FILE_SIZE_UNENCRYPTED_MB}
|
||||
volumes:
|
||||
- ./microbin-data:/app/microbin_data
|
||||
restart: always
|
||||
networks:
|
||||
- homelab
|
||||
labels:
|
||||
traefik.enable: true
|
||||
|
|
|
|||
23
compose/services/rsshub/.env
Normal file
23
compose/services/rsshub/.env
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# RSSHub Configuration
|
||||
|
||||
# Node environment
|
||||
NODE_ENV=production
|
||||
|
||||
# Cache type (memory or redis)
|
||||
CACHE_TYPE=memory
|
||||
|
||||
# Cache expiration time in seconds (default: 5 minutes)
|
||||
CACHE_EXPIRE=300
|
||||
|
||||
# Timezone
|
||||
TZ=America/Los_Angeles
|
||||
|
||||
# Optional: Redis configuration (if using redis cache)
|
||||
# CACHE_TYPE=redis
|
||||
# REDIS_URL=redis://redis:6379/
|
||||
|
||||
# Optional: Access control
|
||||
# ACCESS_KEY=your_access_key_here
|
||||
|
||||
# Optional: Logging
|
||||
# LOGGER_LEVEL=info # debug, info, warn, error
|
||||
|
|
@ -6,71 +6,7 @@ services:
|
|||
container_name: rsshub
|
||||
# Using chromium-bundled image for full puppeteer support
|
||||
image: diygod/rsshub:chromium-bundled
|
||||
environment:
|
||||
NODE_ENV: production
|
||||
CACHE_TYPE: redis
|
||||
REDIS_URL: redis://rsshub-redis:6379/
|
||||
PUPPETEER_WS_ENDPOINT: ws://rsshub-browserless:3000
|
||||
TZ: America/Los_Angeles
|
||||
restart: always
|
||||
networks:
|
||||
- homelab
|
||||
- rsshub_internal
|
||||
depends_on:
|
||||
- rsshub-redis
|
||||
- rsshub-browserless
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:1200/healthz"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.docker.network: homelab
|
||||
traefik.http.routers.rsshub.rule: Host(`rsshub.fig.systems`) || Host(`rsshub.edfig.dev`)
|
||||
traefik.http.routers.rsshub.entrypoints: websecure
|
||||
traefik.http.routers.rsshub.tls.certresolver: letsencrypt
|
||||
traefik.http.services.rsshub.loadbalancer.server.port: 1200
|
||||
# Optional: enable SSO (may interfere with RSS readers)
|
||||
# traefik.http.routers.rsshub.middlewares: tinyauth
|
||||
|
||||
rsshub-browserless:
|
||||
container_name: rsshub-browserless
|
||||
image: browserless/chrome
|
||||
restart: always
|
||||
networks:
|
||||
- rsshub_internal
|
||||
ulimits:
|
||||
core:
|
||||
hard: 0
|
||||
soft: 0
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:3000/pressure"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
env_file:
|
||||
|
||||
rsshub-redis:
|
||||
container_name: rsshub-redis
|
||||
image: redis:alpine
|
||||
restart: always
|
||||
networks:
|
||||
- rsshub_internal
|
||||
volumes:
|
||||
- redis-data:/data
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
start_period: 5s
|
||||
|
||||
networks:
|
||||
homelab:
|
||||
external: true
|
||||
rsshub_internal:
|
||||
name: rsshub_internal
|
||||
driver: bridge
|
||||
|
||||
volumes:
|
||||
redis-data:
|
||||
- .env
|
||||
|
|
|
|||
28
compose/services/vikunja/.env
Normal file
28
compose/services/vikunja/.env
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
# Vikunja Configuration
|
||||
|
||||
# Public URL
|
||||
VIKUNJA_SERVICE_PUBLICURL=https://tasks.fig.systems
|
||||
|
||||
# Database Configuration
|
||||
VIKUNJA_DATABASE_HOST=vikunja-db
|
||||
VIKUNJA_DATABASE_TYPE=postgres
|
||||
VIKUNJA_DATABASE_USER=vikunja
|
||||
VIKUNJA_DATABASE_DATABASE=vikunja
|
||||
# Generate with: openssl rand -base64 32 | tr -d /=+ | cut -c1-32
|
||||
# Example format: cD5eF8gH1jK3lM6nO9pQ2rS5tU8vW1xY
|
||||
VIKUNJA_DATABASE_PASSWORD=changeme_please_set_secure_password
|
||||
|
||||
# JWT Secret for session management (64+ character random string)
|
||||
# Generate with: openssl rand -hex 32
|
||||
# Example format: c2d3e4f567890abcdef1234567890a1b2c3d4e5f67890abcdef1234567890abc
|
||||
VIKUNJA_SERVICE_JWTSECRET=changeme_please_set_random_jwt_secret
|
||||
|
||||
# Timezone
|
||||
TZ=America/Los_Angeles
|
||||
|
||||
# Database environment variables (for postgres container)
|
||||
POSTGRES_USER=vikunja
|
||||
POSTGRES_DB=vikunja
|
||||
# Must match VIKUNJA_DATABASE_PASSWORD above
|
||||
# Example format: cD5eF8gH1jK3lM6nO9pQ2rS5tU8vW1xY
|
||||
POSTGRES_PASSWORD=changeme_please_set_secure_password
|
||||
|
|
@ -5,15 +5,8 @@ services:
|
|||
vikunja:
|
||||
container_name: vikunja
|
||||
image: vikunja/vikunja:latest
|
||||
environment:
|
||||
VIKUNJA_SERVICE_PUBLICURL: https://tasks.fig.systems
|
||||
VIKUNJA_DATABASE_HOST: vikunja-db
|
||||
VIKUNJA_DATABASE_PASSWORD: changeme_please_set_secure_password
|
||||
VIKUNJA_DATABASE_TYPE: postgres
|
||||
VIKUNJA_DATABASE_USER: vikunja
|
||||
VIKUNJA_DATABASE_DATABASE: vikunja
|
||||
VIKUNJA_SERVICE_JWTSECRET: changeme_please_set_random_jwt_secret
|
||||
TZ: America/Los_Angeles
|
||||
env_file:
|
||||
- .env
|
||||
volumes:
|
||||
- ./files:/app/vikunja/files
|
||||
depends_on:
|
||||
|
|
@ -35,11 +28,8 @@ services:
|
|||
vikunja-db:
|
||||
container_name: vikunja-db
|
||||
image: postgres:18
|
||||
environment:
|
||||
POSTGRES_PASSWORD: changeme_please_set_secure_password
|
||||
POSTGRES_USER: vikunja
|
||||
POSTGRES_DB: vikunja
|
||||
TZ: America/Los_Angeles
|
||||
env_file:
|
||||
- .env
|
||||
volumes:
|
||||
- ./db:/var/lib/postgresql/data
|
||||
restart: unless-stopped
|
||||
|
|
|
|||
92
docs/README.md
Normal file
92
docs/README.md
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
# Homelab Documentation
|
||||
|
||||
Welcome to the homelab documentation! This folder contains comprehensive guides for setting up, configuring, and maintaining your self-hosted services.
|
||||
|
||||
## 📚 Documentation Structure
|
||||
|
||||
### Quick Start
|
||||
- [Getting Started](./getting-started.md) - First-time setup walkthrough
|
||||
- [Quick Reference](./quick-reference.md) - Common commands and URLs
|
||||
|
||||
### Configuration
|
||||
- [Environment Variables & Secrets](./guides/secrets-management.md) - How to configure secure secrets
|
||||
- [DNS Configuration](./guides/dns-setup.md) - Setting up domain names
|
||||
- [SSL/TLS Certificates](./guides/ssl-certificates.md) - Let's Encrypt configuration
|
||||
- [GPU Acceleration](./guides/gpu-setup.md) - NVIDIA GPU setup for Jellyfin and Immich
|
||||
|
||||
### Services
|
||||
- [Service Overview](./services/README.md) - All available services
|
||||
- [SSO Configuration](./services/sso-setup.md) - Single Sign-On with LLDAP and Tinyauth
|
||||
- [Media Stack](./services/media-stack.md) - Jellyfin, Sonarr, Radarr setup
|
||||
- [Backup Solutions](./services/backup.md) - Backrest configuration
|
||||
|
||||
### Troubleshooting
|
||||
- [Common Issues](./troubleshooting/common-issues.md) - Frequent problems and solutions
|
||||
- [FAQ](./troubleshooting/faq.md) - Frequently asked questions
|
||||
- [Debugging Guide](./troubleshooting/debugging.md) - How to diagnose problems
|
||||
|
||||
### Operations
|
||||
- [Maintenance](./operations/maintenance.md) - Regular maintenance tasks
|
||||
- [Updates](./operations/updates.md) - Updating services
|
||||
- [Backups](./operations/backups.md) - Backup and restore procedures
|
||||
- [Monitoring](./operations/monitoring.md) - Service monitoring
|
||||
|
||||
## 🚀 Quick Links
|
||||
|
||||
### First Time Setup
|
||||
1. [Prerequisites](./getting-started.md#prerequisites)
|
||||
2. [Configure Secrets](./guides/secrets-management.md)
|
||||
3. [Setup DNS](./guides/dns-setup.md)
|
||||
4. [Deploy Services](./getting-started.md#deployment)
|
||||
|
||||
### Common Tasks
|
||||
- [Add a new service](./guides/adding-services.md)
|
||||
- [Generate secure passwords](./guides/secrets-management.md#generating-secrets)
|
||||
- [Enable GPU acceleration](./guides/gpu-setup.md)
|
||||
- [Backup configuration](./operations/backups.md)
|
||||
- [Update a service](./operations/updates.md)
|
||||
|
||||
### Troubleshooting
|
||||
- [Service won't start](./troubleshooting/common-issues.md#service-wont-start)
|
||||
- [SSL certificate errors](./troubleshooting/common-issues.md#ssl-errors)
|
||||
- [SSO not working](./troubleshooting/common-issues.md#sso-issues)
|
||||
- [Can't access service](./troubleshooting/common-issues.md#access-issues)
|
||||
|
||||
## 📖 Documentation Conventions
|
||||
|
||||
Throughout this documentation:
|
||||
- `command` - Commands to run in terminal
|
||||
- **Bold** - Important concepts or UI elements
|
||||
- `https://service.fig.systems` - Example URLs
|
||||
- ⚠️ - Warning or important note
|
||||
- 💡 - Tip or helpful information
|
||||
- ✅ - Verified working configuration
|
||||
|
||||
## 🔐 Security Notes
|
||||
|
||||
Before deploying to production:
|
||||
1. ✅ Change all passwords in `.env` files
|
||||
2. ✅ Configure DNS records
|
||||
3. ✅ Verify SSL certificates are working
|
||||
4. ✅ Enable backups
|
||||
5. ✅ Review security settings
|
||||
|
||||
## 🆘 Getting Help
|
||||
|
||||
If you encounter issues:
|
||||
1. Check [Common Issues](./troubleshooting/common-issues.md)
|
||||
2. Review [FAQ](./troubleshooting/faq.md)
|
||||
3. Check service logs: `docker compose logs servicename`
|
||||
4. Review the [Debugging Guide](./troubleshooting/debugging.md)
|
||||
|
||||
## 📝 Contributing to Documentation
|
||||
|
||||
Found an error or have a suggestion? Documentation improvements are welcome!
|
||||
- Keep guides clear and concise
|
||||
- Include examples and code snippets
|
||||
- Test all commands before documenting
|
||||
- Update the table of contents when adding new files
|
||||
|
||||
## 🔄 Last Updated
|
||||
|
||||
This documentation is automatically maintained and reflects the current state of the homelab repository.
|
||||
497
docs/getting-started.md
Normal file
497
docs/getting-started.md
Normal file
|
|
@ -0,0 +1,497 @@
|
|||
# Getting Started with Homelab
|
||||
|
||||
This guide will walk you through setting up your homelab from scratch.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### Hardware Requirements
|
||||
- **Server/VM**: Linux server with Docker support
|
||||
- **CPU**: 2+ cores recommended
|
||||
- **RAM**: 8GB minimum, 16GB+ recommended
|
||||
- **Storage**: 100GB+ for Docker containers and config
|
||||
- **Optional GPU**: NVIDIA GPU for hardware transcoding (Jellyfin, Immich)
|
||||
|
||||
### Software Requirements
|
||||
- **Operating System**: Ubuntu 22.04 or similar Linux distribution
|
||||
- **Docker**: Version 24.0+
|
||||
- **Docker Compose**: Version 2.20+
|
||||
- **Git**: For cloning the repository
|
||||
- **Domain Names**: `*.fig.systems` and `*.edfig.dev` (or your domains)
|
||||
|
||||
### Network Requirements
|
||||
- **Ports**: 80 and 443 accessible from internet (for Let's Encrypt)
|
||||
- **DNS**: Ability to create A records for your domains
|
||||
- **Static IP**: Recommended for your homelab server
|
||||
|
||||
## Step 1: Prepare Your Server
|
||||
|
||||
### Install Docker and Docker Compose
|
||||
|
||||
```bash
|
||||
# Update package index
|
||||
sudo apt update
|
||||
|
||||
# Install dependencies
|
||||
sudo apt install -y ca-certificates curl gnupg lsb-release
|
||||
|
||||
# Add Docker's official GPG key
|
||||
sudo mkdir -p /etc/apt/keyrings
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
||||
|
||||
# Set up the repository
|
||||
echo \
|
||||
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
|
||||
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
|
||||
# Install Docker Engine
|
||||
sudo apt update
|
||||
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||||
|
||||
# Add your user to docker group (logout and login after this)
|
||||
sudo usermod -aG docker $USER
|
||||
|
||||
# Verify installation
|
||||
docker --version
|
||||
docker compose version
|
||||
```
|
||||
|
||||
### Create Media Directory Structure
|
||||
|
||||
```bash
|
||||
# Create media folders
|
||||
sudo mkdir -p /media/{audiobooks,books,comics,complete,downloads,homemovies,incomplete,movies,music,photos,tv}
|
||||
|
||||
# Set ownership (replace with your username)
|
||||
sudo chown -R $(whoami):$(whoami) /media
|
||||
|
||||
# Verify structure
|
||||
tree -L 1 /media
|
||||
```
|
||||
|
||||
## Step 2: Clone the Repository
|
||||
|
||||
```bash
|
||||
# Clone the repository
|
||||
cd ~
|
||||
git clone https://github.com/efigueroa/homelab.git
|
||||
cd homelab
|
||||
|
||||
# Checkout the main branch
|
||||
git checkout main # or your target branch
|
||||
```
|
||||
|
||||
## Step 3: Configure DNS
|
||||
|
||||
You need to point your domains to your server's IP address.
|
||||
|
||||
### Option 1: Wildcard DNS (Recommended)
|
||||
|
||||
Add these A records to your DNS provider:
|
||||
|
||||
```
|
||||
*.fig.systems A YOUR_SERVER_IP
|
||||
*.edfig.dev A YOUR_SERVER_IP
|
||||
```
|
||||
|
||||
### Option 2: Individual Records
|
||||
|
||||
Create A records for each service:
|
||||
|
||||
```
|
||||
traefik.fig.systems A YOUR_SERVER_IP
|
||||
lldap.fig.systems A YOUR_SERVER_IP
|
||||
auth.fig.systems A YOUR_SERVER_IP
|
||||
home.fig.systems A YOUR_SERVER_IP
|
||||
backup.fig.systems A YOUR_SERVER_IP
|
||||
flix.fig.systems A YOUR_SERVER_IP
|
||||
photos.fig.systems A YOUR_SERVER_IP
|
||||
# ... and so on for all services
|
||||
```
|
||||
|
||||
### Verify DNS
|
||||
|
||||
Wait a few minutes for DNS propagation, then verify:
|
||||
|
||||
```bash
|
||||
# Test DNS resolution
|
||||
dig traefik.fig.systems +short
|
||||
dig lldap.fig.systems +short
|
||||
|
||||
# Should return your server IP
|
||||
```
|
||||
|
||||
## Step 4: Configure Environment Variables
|
||||
|
||||
Each service needs its environment variables configured with secure values.
|
||||
|
||||
### Generate Secure Secrets
|
||||
|
||||
Use these commands to generate secure values:
|
||||
|
||||
```bash
|
||||
# For JWT secrets and session secrets (64 characters)
|
||||
openssl rand -hex 32
|
||||
|
||||
# For passwords (32 alphanumeric characters)
|
||||
openssl rand -base64 32 | tr -d /=+ | cut -c1-32
|
||||
|
||||
# For API keys (32 characters)
|
||||
openssl rand -hex 16
|
||||
```
|
||||
|
||||
### Update Core Services
|
||||
|
||||
**LLDAP** (`compose/core/lldap/.env`):
|
||||
```bash
|
||||
cd compose/core/lldap
|
||||
nano .env
|
||||
|
||||
# Update these values:
|
||||
LLDAP_LDAP_USER_PASS=<your-strong-password>
|
||||
LLDAP_JWT_SECRET=<output-from-openssl-rand-hex-32>
|
||||
```
|
||||
|
||||
**Tinyauth** (`compose/core/tinyauth/.env`):
|
||||
```bash
|
||||
cd ../tinyauth
|
||||
nano .env
|
||||
|
||||
# Update these values (LDAP_BIND_PASSWORD must match LLDAP_LDAP_USER_PASS):
|
||||
LDAP_BIND_PASSWORD=<same-as-LLDAP_LDAP_USER_PASS>
|
||||
SESSION_SECRET=<output-from-openssl-rand-hex-32>
|
||||
```
|
||||
|
||||
**Immich** (`compose/media/frontend/immich/.env`):
|
||||
```bash
|
||||
cd ../../media/frontend/immich
|
||||
nano .env
|
||||
|
||||
# Update:
|
||||
DB_PASSWORD=<output-from-openssl-rand-base64>
|
||||
```
|
||||
|
||||
### Update All Other Services
|
||||
|
||||
Go through each service's `.env` file and replace all `changeme_*` values:
|
||||
|
||||
```bash
|
||||
# Find all files that need updating
|
||||
grep -r "changeme_" ~/homelab/compose
|
||||
|
||||
# Or update them individually
|
||||
cd ~/homelab/compose/services/linkwarden
|
||||
nano .env # Update NEXTAUTH_SECRET, POSTGRES_PASSWORD, MEILI_MASTER_KEY
|
||||
|
||||
cd ../vikunja
|
||||
nano .env # Update VIKUNJA_DATABASE_PASSWORD, VIKUNJA_SERVICE_JWTSECRET, POSTGRES_PASSWORD
|
||||
```
|
||||
|
||||
💡 **Tip**: Keep your secrets in a password manager!
|
||||
|
||||
See [Secrets Management Guide](./guides/secrets-management.md) for detailed instructions.
|
||||
|
||||
## Step 5: Create Docker Network
|
||||
|
||||
```bash
|
||||
# Create the external homelab network
|
||||
docker network create homelab
|
||||
|
||||
# Verify it was created
|
||||
docker network ls | grep homelab
|
||||
```
|
||||
|
||||
## Step 6: Deploy Services
|
||||
|
||||
Deploy services in order, starting with core infrastructure:
|
||||
|
||||
### Deploy Core Infrastructure
|
||||
|
||||
```bash
|
||||
cd ~/homelab
|
||||
|
||||
# Deploy Traefik (reverse proxy)
|
||||
cd compose/core/traefik
|
||||
docker compose up -d
|
||||
|
||||
# Check logs to ensure it starts successfully
|
||||
docker compose logs -f
|
||||
|
||||
# Wait for "Server configuration reloaded" message, then Ctrl+C
|
||||
```
|
||||
|
||||
```bash
|
||||
# Deploy LLDAP (user directory)
|
||||
cd ../lldap
|
||||
docker compose up -d
|
||||
docker compose logs -f
|
||||
|
||||
# Access: https://lldap.fig.systems
|
||||
# Default login: admin / <your LLDAP_LDAP_USER_PASS>
|
||||
```
|
||||
|
||||
```bash
|
||||
# Deploy Tinyauth (SSO)
|
||||
cd ../tinyauth
|
||||
docker compose up -d
|
||||
docker compose logs -f
|
||||
|
||||
# Access: https://auth.fig.systems
|
||||
```
|
||||
|
||||
### Create LLDAP Users
|
||||
|
||||
Before deploying other services, create your user in LLDAP:
|
||||
|
||||
1. Go to https://lldap.fig.systems
|
||||
2. Login with admin credentials
|
||||
3. Create your user:
|
||||
- Username: `edfig` (or your choice)
|
||||
- Email: `admin@edfig.dev`
|
||||
- Password: strong password
|
||||
- Add to `lldap_admin` group
|
||||
|
||||
### Deploy Media Services
|
||||
|
||||
```bash
|
||||
cd ~/homelab/compose/media/frontend
|
||||
|
||||
# Jellyfin
|
||||
cd jellyfin
|
||||
docker compose up -d
|
||||
# Access: https://flix.fig.systems
|
||||
|
||||
# Immich
|
||||
cd ../immich
|
||||
docker compose up -d
|
||||
# Access: https://photos.fig.systems
|
||||
|
||||
# Jellyseerr
|
||||
cd ../jellyseer
|
||||
docker compose up -d
|
||||
# Access: https://requests.fig.systems
|
||||
```
|
||||
|
||||
```bash
|
||||
# Media automation
|
||||
cd ~/homelab/compose/media/automation
|
||||
|
||||
cd sonarr && docker compose up -d && cd ..
|
||||
cd radarr && docker compose up -d && cd ..
|
||||
cd sabnzbd && docker compose up -d && cd ..
|
||||
cd qbittorrent && docker compose up -d && cd ..
|
||||
```
|
||||
|
||||
### Deploy Utility Services
|
||||
|
||||
```bash
|
||||
cd ~/homelab/compose/services
|
||||
|
||||
# Dashboard (start with this - it shows all your services!)
|
||||
cd homarr && docker compose up -d && cd ..
|
||||
# Access: https://home.fig.systems
|
||||
|
||||
# Backup manager
|
||||
cd backrest && docker compose up -d && cd ..
|
||||
# Access: https://backup.fig.systems
|
||||
|
||||
# Other services
|
||||
cd linkwarden && docker compose up -d && cd ..
|
||||
cd vikunja && docker compose up -d && cd ..
|
||||
cd lubelogger && docker compose up -d && cd ..
|
||||
cd calibre-web && docker compose up -d && cd ..
|
||||
cd booklore && docker compose up -d && cd ..
|
||||
cd FreshRSS && docker compose up -d && cd ..
|
||||
cd rsshub && docker compose up -d && cd ..
|
||||
cd microbin && docker compose up -d && cd ..
|
||||
cd filebrowser && docker compose up -d && cd ..
|
||||
```
|
||||
|
||||
### Quick Deploy All (Alternative)
|
||||
|
||||
If you've configured everything and want to deploy all at once:
|
||||
|
||||
```bash
|
||||
cd ~/homelab
|
||||
|
||||
# Create a deployment script
|
||||
cat > deploy-all.sh << 'SCRIPT'
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "Deploying homelab services..."
|
||||
|
||||
# Core
|
||||
echo "==> Core Infrastructure"
|
||||
cd compose/core/traefik && docker compose up -d && cd ../../..
|
||||
sleep 5
|
||||
cd compose/core/lldap && docker compose up -d && cd ../../..
|
||||
sleep 5
|
||||
cd compose/core/tinyauth && docker compose up -d && cd ../../..
|
||||
|
||||
# Media
|
||||
echo "==> Media Services"
|
||||
cd compose/media/frontend/immich && docker compose up -d && cd ../../../..
|
||||
cd compose/media/frontend/jellyfin && docker compose up -d && cd ../../../..
|
||||
cd compose/media/frontend/jellyseer && docker compose up -d && cd ../../../..
|
||||
cd compose/media/automation/sonarr && docker compose up -d && cd ../../../..
|
||||
cd compose/media/automation/radarr && docker compose up -d && cd ../../../..
|
||||
cd compose/media/automation/sabnzbd && docker compose up -d && cd ../../../..
|
||||
cd compose/media/automation/qbittorrent && docker compose up -d && cd ../../../..
|
||||
|
||||
# Utility
|
||||
echo "==> Utility Services"
|
||||
cd compose/services/homarr && docker compose up -d && cd ../..
|
||||
cd compose/services/backrest && docker compose up -d && cd ../..
|
||||
cd compose/services/linkwarden && docker compose up -d && cd ../..
|
||||
cd compose/services/vikunja && docker compose up -d && cd ../..
|
||||
cd compose/services/lubelogger && docker compose up -d && cd ../..
|
||||
cd compose/services/calibre-web && docker compose up -d && cd ../..
|
||||
cd compose/services/booklore && docker compose up -d && cd ../..
|
||||
cd compose/services/FreshRSS && docker compose up -d && cd ../..
|
||||
cd compose/services/rsshub && docker compose up -d && cd ../..
|
||||
cd compose/services/microbin && docker compose up -d && cd ../..
|
||||
cd compose/services/filebrowser && docker compose up -d && cd ../..
|
||||
|
||||
echo "==> Deployment Complete!"
|
||||
echo "Access your dashboard at: https://home.fig.systems"
|
||||
SCRIPT
|
||||
|
||||
chmod +x deploy-all.sh
|
||||
./deploy-all.sh
|
||||
```
|
||||
|
||||
## Step 7: Verify Deployment
|
||||
|
||||
### Check All Containers Are Running
|
||||
|
||||
```bash
|
||||
# List all containers
|
||||
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
|
||||
|
||||
# Check for any stopped containers
|
||||
docker ps -a --filter "status=exited"
|
||||
```
|
||||
|
||||
### Verify SSL Certificates
|
||||
|
||||
```bash
|
||||
# Test SSL certificate
|
||||
curl -I https://home.fig.systems
|
||||
|
||||
# Should show HTTP/2 200 and valid SSL cert
|
||||
```
|
||||
|
||||
### Access Services
|
||||
|
||||
Visit your dashboard: **https://home.fig.systems**
|
||||
|
||||
This should show all your services with their status!
|
||||
|
||||
### Test SSO
|
||||
|
||||
1. Go to any SSO-protected service (e.g., https://tasks.fig.systems)
|
||||
2. You should be redirected to https://auth.fig.systems
|
||||
3. Login with your LLDAP credentials
|
||||
4. You should be redirected back to the service
|
||||
|
||||
## Step 8: Initial Service Configuration
|
||||
|
||||
### Jellyfin Setup
|
||||
1. Go to https://flix.fig.systems
|
||||
2. Select language and create admin account
|
||||
3. Add media libraries:
|
||||
- Movies: `/media/movies`
|
||||
- TV Shows: `/media/tv`
|
||||
- Music: `/media/music`
|
||||
- Photos: `/media/photos`
|
||||
|
||||
### Immich Setup
|
||||
1. Go to https://photos.fig.systems
|
||||
2. Create admin account
|
||||
3. Upload some photos to test
|
||||
4. Configure storage in Settings
|
||||
|
||||
### Sonarr/Radarr Setup
|
||||
1. Go to https://sonarr.fig.systems and https://radarr.fig.systems
|
||||
2. Complete initial setup wizard
|
||||
3. Add indexers (for finding content)
|
||||
4. Add download clients:
|
||||
- SABnzbd: http://sabnzbd:8080
|
||||
- qBittorrent: http://qbittorrent:8080
|
||||
5. Configure root folders:
|
||||
- Sonarr: `/media/tv`
|
||||
- Radarr: `/media/movies`
|
||||
|
||||
### Jellyseerr Setup
|
||||
1. Go to https://requests.fig.systems
|
||||
2. Sign in with Jellyfin
|
||||
3. Connect to Sonarr and Radarr
|
||||
4. Configure user permissions
|
||||
|
||||
### Backrest Setup
|
||||
1. Go to https://backup.fig.systems
|
||||
2. Add Backblaze B2 repository (see [Backup Guide](./services/backup.md))
|
||||
3. Create backup plan for Immich photos
|
||||
4. Schedule automated backups
|
||||
|
||||
## Step 9: Optional Configurations
|
||||
|
||||
### Enable GPU Acceleration
|
||||
|
||||
If you have an NVIDIA GPU, see [GPU Setup Guide](./guides/gpu-setup.md).
|
||||
|
||||
### Configure Backups
|
||||
|
||||
See [Backup Operations Guide](./operations/backups.md).
|
||||
|
||||
### Add More Services
|
||||
|
||||
See [Adding Services Guide](./guides/adding-services.md).
|
||||
|
||||
## Next Steps
|
||||
|
||||
- ✅ [Set up automated backups](./operations/backups.md)
|
||||
- ✅ [Configure monitoring](./operations/monitoring.md)
|
||||
- ✅ [Review security settings](./guides/security.md)
|
||||
- ✅ [Enable GPU acceleration](./guides/gpu-setup.md) (optional)
|
||||
- ✅ [Configure media automation](./services/media-stack.md)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
If you encounter issues during setup, see:
|
||||
- [Common Issues](./troubleshooting/common-issues.md)
|
||||
- [FAQ](./troubleshooting/faq.md)
|
||||
- [Debugging Guide](./troubleshooting/debugging.md)
|
||||
|
||||
## Quick Command Reference
|
||||
|
||||
```bash
|
||||
# View all running containers
|
||||
docker ps
|
||||
|
||||
# View logs for a service
|
||||
cd compose/path/to/service
|
||||
docker compose logs -f
|
||||
|
||||
# Restart a service
|
||||
docker compose restart
|
||||
|
||||
# Stop a service
|
||||
docker compose down
|
||||
|
||||
# Update and restart a service
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
|
||||
# View resource usage
|
||||
docker stats
|
||||
```
|
||||
|
||||
## Getting Help
|
||||
|
||||
- Check the [FAQ](./troubleshooting/faq.md)
|
||||
- Review service-specific guides in [docs/services/](./services/)
|
||||
- Check container logs for errors
|
||||
- Verify DNS and SSL certificates
|
||||
|
||||
Welcome to your homelab! 🎉
|
||||
725
docs/guides/gpu-setup.md
Normal file
725
docs/guides/gpu-setup.md
Normal file
|
|
@ -0,0 +1,725 @@
|
|||
# NVIDIA GPU Acceleration Setup (GTX 1070)
|
||||
|
||||
This guide covers setting up NVIDIA GPU acceleration for your homelab running on **Proxmox 9 (Debian 13)** with an **NVIDIA GTX 1070**.
|
||||
|
||||
## Overview
|
||||
|
||||
GPU acceleration provides significant benefits:
|
||||
- **Jellyfin**: Hardware video transcoding (H.264, HEVC)
|
||||
- **Immich**: Faster ML inference (face recognition, object detection)
|
||||
- **Performance**: 10-20x faster transcoding vs CPU
|
||||
- **Efficiency**: Lower power consumption, CPU freed for other tasks
|
||||
|
||||
**Your Hardware:**
|
||||
- **GPU**: NVIDIA GTX 1070 (Pascal architecture)
|
||||
- **Capabilities**: NVENC (encoding), NVDEC (decoding), CUDA
|
||||
- **Max Concurrent Streams**: 2 (can be unlocked)
|
||||
- **Supported Codecs**: H.264, HEVC (H.265)
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
```
|
||||
Proxmox Host (Debian 13)
|
||||
│
|
||||
├─ NVIDIA Drivers (host)
|
||||
├─ NVIDIA Container Toolkit
|
||||
│
|
||||
└─ Docker VM/LXC
|
||||
│
|
||||
├─ GPU passthrough
|
||||
│
|
||||
└─ Jellyfin/Immich containers
|
||||
└─ Hardware transcoding
|
||||
```
|
||||
|
||||
## Part 1: Proxmox Host Setup
|
||||
|
||||
### Step 1.1: Enable IOMMU (for GPU Passthrough)
|
||||
|
||||
**Edit GRUB configuration:**
|
||||
|
||||
```bash
|
||||
# SSH into Proxmox host
|
||||
ssh root@proxmox-host
|
||||
|
||||
# Edit GRUB config
|
||||
nano /etc/default/grub
|
||||
```
|
||||
|
||||
**Find this line:**
|
||||
```
|
||||
GRUB_CMDLINE_LINUX_DEFAULT="quiet"
|
||||
```
|
||||
|
||||
**Replace with (Intel CPU):**
|
||||
```
|
||||
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt"
|
||||
```
|
||||
|
||||
**Or (AMD CPU):**
|
||||
```
|
||||
GRUB_CMDLINE_LINUX_DEFAULT="quiet amd_iommu=on iommu=pt"
|
||||
```
|
||||
|
||||
**Update GRUB and reboot:**
|
||||
```bash
|
||||
update-grub
|
||||
reboot
|
||||
```
|
||||
|
||||
**Verify IOMMU is enabled:**
|
||||
```bash
|
||||
dmesg | grep -e DMAR -e IOMMU
|
||||
|
||||
# Should see: "IOMMU enabled"
|
||||
```
|
||||
|
||||
### Step 1.2: Load VFIO Modules
|
||||
|
||||
**Edit modules:**
|
||||
```bash
|
||||
nano /etc/modules
|
||||
```
|
||||
|
||||
**Add these lines:**
|
||||
```
|
||||
vfio
|
||||
vfio_iommu_type1
|
||||
vfio_pci
|
||||
vfio_virqfd
|
||||
```
|
||||
|
||||
**Update initramfs:**
|
||||
```bash
|
||||
update-initramfs -u -k all
|
||||
reboot
|
||||
```
|
||||
|
||||
### Step 1.3: Find GPU PCI ID
|
||||
|
||||
```bash
|
||||
lspci -nn | grep -i nvidia
|
||||
|
||||
# Example output:
|
||||
# 01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GP104 [GeForce GTX 1070] [10de:1b81] (rev a1)
|
||||
# 01:00.1 Audio device [0403]: NVIDIA Corporation GP104 High Definition Audio Controller [10de:10f0] (rev a1)
|
||||
```
|
||||
|
||||
**Note the IDs**: `10de:1b81` and `10de:10f0` (your values may differ)
|
||||
|
||||
### Step 1.4: Configure VFIO
|
||||
|
||||
**Create VFIO config:**
|
||||
```bash
|
||||
nano /etc/modprobe.d/vfio.conf
|
||||
```
|
||||
|
||||
**Add (replace with your IDs from above):**
|
||||
```
|
||||
options vfio-pci ids=10de:1b81,10de:10f0
|
||||
softdep nvidia pre: vfio-pci
|
||||
```
|
||||
|
||||
**Blacklist nouveau (open-source NVIDIA driver):**
|
||||
```bash
|
||||
echo "blacklist nouveau" >> /etc/modprobe.d/blacklist.conf
|
||||
```
|
||||
|
||||
**Update and reboot:**
|
||||
```bash
|
||||
update-initramfs -u -k all
|
||||
reboot
|
||||
```
|
||||
|
||||
**Verify GPU is bound to VFIO:**
|
||||
```bash
|
||||
lspci -nnk -d 10de:1b81
|
||||
|
||||
# Should show:
|
||||
# Kernel driver in use: vfio-pci
|
||||
```
|
||||
|
||||
## Part 2: VM/LXC Setup
|
||||
|
||||
### Option A: Using VM (Recommended for Docker)
|
||||
|
||||
**Create Ubuntu 24.04 VM with GPU passthrough:**
|
||||
|
||||
1. **Create VM in Proxmox UI**:
|
||||
- OS: Ubuntu 24.04 Server
|
||||
- CPU: 4+ cores
|
||||
- RAM: 16GB+
|
||||
- Disk: 100GB+
|
||||
|
||||
2. **Add PCI Device** (GPU):
|
||||
- Hardware → Add → PCI Device
|
||||
- Device: Select your GTX 1070 (01:00.0)
|
||||
- ✅ All Functions
|
||||
- ✅ Primary GPU (if no other GPU)
|
||||
- ✅ PCI-Express
|
||||
|
||||
3. **Add PCI Device** (GPU Audio):
|
||||
- Hardware → Add → PCI Device
|
||||
- Device: NVIDIA Audio (01:00.1)
|
||||
- ✅ All Functions
|
||||
|
||||
4. **Machine Settings**:
|
||||
- Machine: q35
|
||||
- BIOS: OVMF (UEFI)
|
||||
- Add EFI Disk
|
||||
|
||||
5. **Start VM** and install Ubuntu
|
||||
|
||||
### Option B: Using LXC (Advanced, Less Stable)
|
||||
|
||||
**Note**: LXC with GPU is less reliable. VM recommended.
|
||||
|
||||
If you insist on LXC:
|
||||
```bash
|
||||
# Edit LXC config
|
||||
nano /etc/pve/lxc/VMID.conf
|
||||
|
||||
# Add:
|
||||
lxc.cgroup2.devices.allow: c 195:* rwm
|
||||
lxc.cgroup2.devices.allow: c 509:* rwm
|
||||
lxc.mount.entry: /dev/nvidia0 dev/nvidia0 none bind,optional,create=file
|
||||
lxc.mount.entry: /dev/nvidiactl dev/nvidiactl none bind,optional,create=file
|
||||
lxc.mount.entry: /dev/nvidia-uvm dev/nvidia-uvm none bind,optional,create=file
|
||||
```
|
||||
|
||||
**For this guide, we'll use VM (Option A)**.
|
||||
|
||||
## Part 3: VM Guest Setup (Debian 13)
|
||||
|
||||
Now we're inside the Ubuntu/Debian VM where Docker runs.
|
||||
|
||||
### Step 3.1: Install NVIDIA Drivers
|
||||
|
||||
**SSH into your Docker VM:**
|
||||
```bash
|
||||
ssh user@docker-vm
|
||||
```
|
||||
|
||||
**Update system:**
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt upgrade -y
|
||||
```
|
||||
|
||||
**Debian 13 - Install NVIDIA drivers:**
|
||||
```bash
|
||||
# Add non-free repositories
|
||||
sudo nano /etc/apt/sources.list
|
||||
|
||||
# Add 'non-free non-free-firmware' to each line, example:
|
||||
deb http://deb.debian.org/debian bookworm main non-free non-free-firmware
|
||||
deb http://deb.debian.org/debian bookworm-updates main non-free non-free-firmware
|
||||
|
||||
# Update and install
|
||||
sudo apt update
|
||||
sudo apt install -y linux-headers-$(uname -r)
|
||||
sudo apt install -y nvidia-driver nvidia-smi
|
||||
|
||||
# Reboot
|
||||
sudo reboot
|
||||
```
|
||||
|
||||
**Verify driver installation:**
|
||||
```bash
|
||||
nvidia-smi
|
||||
|
||||
# Should show:
|
||||
# +-----------------------------------------------------------------------------+
|
||||
# | NVIDIA-SMI 535.xx.xx Driver Version: 535.xx.xx CUDA Version: 12.2 |
|
||||
# |-------------------------------+----------------------+----------------------+
|
||||
# | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
|
||||
# | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|
||||
# |===============================+======================+======================|
|
||||
# | 0 NVIDIA GeForce ... Off | 00000000:01:00.0 Off | N/A |
|
||||
# | 30% 35C P8 10W / 150W | 0MiB / 8192MiB | 0% Default |
|
||||
# +-------------------------------+----------------------+----------------------+
|
||||
```
|
||||
|
||||
✅ **Success!** Your GTX 1070 is now accessible in the VM.
|
||||
|
||||
### Step 3.2: Install NVIDIA Container Toolkit
|
||||
|
||||
**Add NVIDIA Container Toolkit repository:**
|
||||
```bash
|
||||
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
|
||||
|
||||
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
|
||||
sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
|
||||
sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
|
||||
```
|
||||
|
||||
**Install toolkit:**
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install -y nvidia-container-toolkit
|
||||
```
|
||||
|
||||
**Configure Docker to use NVIDIA runtime:**
|
||||
```bash
|
||||
sudo nvidia-ctk runtime configure --runtime=docker
|
||||
```
|
||||
|
||||
**Restart Docker:**
|
||||
```bash
|
||||
sudo systemctl restart docker
|
||||
```
|
||||
|
||||
**Verify Docker can access GPU:**
|
||||
```bash
|
||||
docker run --rm --gpus all nvidia/cuda:12.2.0-base-ubuntu22.04 nvidia-smi
|
||||
|
||||
# Should show nvidia-smi output from inside container
|
||||
```
|
||||
|
||||
✅ **Success!** Docker can now use your GPU.
|
||||
|
||||
## Part 4: Configure Jellyfin for GPU Transcoding
|
||||
|
||||
### Step 4.1: Update Jellyfin Compose File
|
||||
|
||||
**Edit compose file:**
|
||||
```bash
|
||||
cd ~/homelab/compose/media/frontend/jellyfin
|
||||
nano compose.yaml
|
||||
```
|
||||
|
||||
**Uncomment the GPU sections:**
|
||||
|
||||
```yaml
|
||||
services:
|
||||
jellyfin:
|
||||
container_name: jellyfin
|
||||
image: lscr.io/linuxserver/jellyfin:latest
|
||||
env_file:
|
||||
- .env
|
||||
volumes:
|
||||
- ./config:/config
|
||||
- ./cache:/cache
|
||||
- /media/movies:/media/movies:ro
|
||||
- /media/tv:/media/tv:ro
|
||||
- /media/music:/media/music:ro
|
||||
- /media/photos:/media/photos:ro
|
||||
- /media/homemovies:/media/homemovies:ro
|
||||
ports:
|
||||
- "8096:8096"
|
||||
- "7359:7359/udp"
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- homelab
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.http.routers.jellyfin.rule: Host(`flix.fig.systems`) || Host(`flix.edfig.dev`)
|
||||
traefik.http.routers.jellyfin.entrypoints: websecure
|
||||
traefik.http.routers.jellyfin.tls.certresolver: letsencrypt
|
||||
traefik.http.services.jellyfin.loadbalancer.server.port: 8096
|
||||
|
||||
# UNCOMMENT THESE LINES FOR GTX 1070:
|
||||
runtime: nvidia
|
||||
deploy:
|
||||
resources:
|
||||
reservations:
|
||||
devices:
|
||||
- driver: nvidia
|
||||
count: all
|
||||
capabilities: [gpu]
|
||||
|
||||
networks:
|
||||
homelab:
|
||||
external: true
|
||||
```
|
||||
|
||||
**Restart Jellyfin:**
|
||||
```bash
|
||||
docker compose down
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
**Check logs:**
|
||||
```bash
|
||||
docker compose logs -f
|
||||
|
||||
# Should see lines about NVENC/CUDA being detected
|
||||
```
|
||||
|
||||
### Step 4.2: Enable in Jellyfin UI
|
||||
|
||||
1. Go to https://flix.fig.systems
|
||||
2. Dashboard → Playback → Transcoding
|
||||
3. **Hardware acceleration**: NVIDIA NVENC
|
||||
4. **Enable hardware decoding for**:
|
||||
- ✅ H264
|
||||
- ✅ HEVC
|
||||
- ✅ VC1
|
||||
- ✅ VP8
|
||||
- ✅ MPEG2
|
||||
5. **Enable hardware encoding**
|
||||
6. **Enable encoding in HEVC format**
|
||||
7. Save
|
||||
|
||||
### Step 4.3: Test Transcoding
|
||||
|
||||
1. Play a video in Jellyfin web UI
|
||||
2. Click Settings (gear icon) → Quality
|
||||
3. Select a lower bitrate to force transcoding
|
||||
4. In another terminal:
|
||||
```bash
|
||||
nvidia-smi
|
||||
|
||||
# While video is transcoding, should see:
|
||||
# GPU utilization: 20-40%
|
||||
# Memory usage: 500-1000MB
|
||||
```
|
||||
|
||||
✅ **Success!** Jellyfin is using your GTX 1070!
|
||||
|
||||
## Part 5: Configure Immich for GPU Acceleration
|
||||
|
||||
Immich can use GPU for two purposes:
|
||||
1. **ML Inference** (face recognition, object detection)
|
||||
2. **Video Transcoding**
|
||||
|
||||
### Step 5.1: ML Inference (CUDA)
|
||||
|
||||
**Edit Immich compose file:**
|
||||
```bash
|
||||
cd ~/homelab/compose/media/frontend/immich
|
||||
nano compose.yaml
|
||||
```
|
||||
|
||||
**Change ML image to CUDA version:**
|
||||
|
||||
Find this line:
|
||||
```yaml
|
||||
image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
|
||||
```
|
||||
|
||||
Change to:
|
||||
```yaml
|
||||
image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}-cuda
|
||||
```
|
||||
|
||||
**Add GPU support:**
|
||||
|
||||
```yaml
|
||||
immich-machine-learning:
|
||||
container_name: immich_machine_learning
|
||||
image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}-cuda
|
||||
volumes:
|
||||
- model-cache:/cache
|
||||
env_file:
|
||||
- .env
|
||||
restart: always
|
||||
networks:
|
||||
- immich_internal
|
||||
|
||||
# ADD THESE LINES:
|
||||
runtime: nvidia
|
||||
deploy:
|
||||
resources:
|
||||
reservations:
|
||||
devices:
|
||||
- driver: nvidia
|
||||
count: all
|
||||
capabilities: [gpu]
|
||||
```
|
||||
|
||||
### Step 5.2: Video Transcoding (NVENC)
|
||||
|
||||
**For video transcoding, add to immich-server:**
|
||||
|
||||
```yaml
|
||||
immich-server:
|
||||
container_name: immich_server
|
||||
image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
|
||||
# ... existing config ...
|
||||
|
||||
# ADD THESE LINES:
|
||||
runtime: nvidia
|
||||
deploy:
|
||||
resources:
|
||||
reservations:
|
||||
devices:
|
||||
- driver: nvidia
|
||||
count: all
|
||||
capabilities: [gpu]
|
||||
```
|
||||
|
||||
**Restart Immich:**
|
||||
```bash
|
||||
docker compose down
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
### Step 5.3: Enable in Immich UI
|
||||
|
||||
1. Go to https://photos.fig.systems
|
||||
2. Administration → Settings → Video Transcoding
|
||||
3. **Transcoding**: h264 (NVENC)
|
||||
4. **Hardware Acceleration**: NVIDIA
|
||||
5. Save
|
||||
|
||||
6. Administration → Settings → Machine Learning
|
||||
7. **Facial Recognition**: Enabled
|
||||
8. **Object Detection**: Enabled
|
||||
9. Should automatically use CUDA
|
||||
|
||||
### Step 5.4: Test ML Inference
|
||||
|
||||
1. Upload photos with faces
|
||||
2. In terminal:
|
||||
```bash
|
||||
nvidia-smi
|
||||
|
||||
# While processing, should see:
|
||||
# GPU utilization: 50-80%
|
||||
# Memory usage: 2-4GB
|
||||
```
|
||||
|
||||
✅ **Success!** Immich is using GPU for ML inference!
|
||||
|
||||
## Part 6: Performance Tuning
|
||||
|
||||
### GTX 1070 Specific Settings
|
||||
|
||||
**Jellyfin optimal settings:**
|
||||
- Hardware acceleration: NVIDIA NVENC
|
||||
- Target transcode bandwidth: Let clients decide
|
||||
- Enable hardware encoding: Yes
|
||||
- Prefer OS native DXVA or VA-API hardware decoders: No
|
||||
- Allow encoding in HEVC format: Yes (GTX 1070 supports HEVC)
|
||||
|
||||
**Immich optimal settings:**
|
||||
- Transcoding: h264 or hevc
|
||||
- Target resolution: 1080p (for GTX 1070)
|
||||
- CRF: 23 (good balance)
|
||||
- Preset: fast
|
||||
|
||||
### Unlock NVENC Stream Limit
|
||||
|
||||
GTX 1070 is limited to 2 concurrent transcoding streams. You can unlock unlimited streams:
|
||||
|
||||
**Install patch:**
|
||||
```bash
|
||||
# Inside Docker VM
|
||||
git clone https://github.com/keylase/nvidia-patch.git
|
||||
cd nvidia-patch
|
||||
sudo bash ./patch.sh
|
||||
|
||||
# Reboot
|
||||
sudo reboot
|
||||
```
|
||||
|
||||
**Verify:**
|
||||
```bash
|
||||
nvidia-smi
|
||||
|
||||
# Now supports unlimited concurrent streams
|
||||
```
|
||||
|
||||
⚠️ **Note**: This is a hack that modifies NVIDIA driver. Use at your own risk.
|
||||
|
||||
### Monitor GPU Usage
|
||||
|
||||
**Real-time monitoring:**
|
||||
```bash
|
||||
watch -n 1 nvidia-smi
|
||||
```
|
||||
|
||||
**Check GPU usage from Docker:**
|
||||
```bash
|
||||
docker stats $(docker ps --format '{{.Names}}' | grep -E 'jellyfin|immich')
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### GPU Not Detected in VM
|
||||
|
||||
**Check from Proxmox host:**
|
||||
```bash
|
||||
lspci | grep -i nvidia
|
||||
```
|
||||
|
||||
**Check from VM:**
|
||||
```bash
|
||||
lspci | grep -i nvidia
|
||||
nvidia-smi
|
||||
```
|
||||
|
||||
**If not visible in VM:**
|
||||
1. Verify IOMMU is enabled (`dmesg | grep IOMMU`)
|
||||
2. Check PCI passthrough is configured correctly
|
||||
3. Ensure VM is using q35 machine type
|
||||
4. Verify BIOS is OVMF (UEFI)
|
||||
|
||||
### Docker Can't Access GPU
|
||||
|
||||
**Error**: `could not select device driver "" with capabilities: [[gpu]]`
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Reconfigure NVIDIA runtime
|
||||
sudo nvidia-ctk runtime configure --runtime=docker
|
||||
sudo systemctl restart docker
|
||||
|
||||
# Test again
|
||||
docker run --rm --gpus all nvidia/cuda:12.2.0-base-ubuntu22.04 nvidia-smi
|
||||
```
|
||||
|
||||
### Jellyfin Shows "No Hardware Acceleration Available"
|
||||
|
||||
**Check:**
|
||||
```bash
|
||||
# Verify container has GPU access
|
||||
docker exec jellyfin nvidia-smi
|
||||
|
||||
# Check Jellyfin logs
|
||||
docker logs jellyfin | grep -i nvenc
|
||||
```
|
||||
|
||||
**Fix:**
|
||||
1. Ensure `runtime: nvidia` is uncommented
|
||||
2. Verify `deploy.resources.reservations.devices` is configured
|
||||
3. Restart container: `docker compose up -d`
|
||||
|
||||
### Transcoding Fails with "Failed to Open GPU"
|
||||
|
||||
**Check:**
|
||||
```bash
|
||||
# GPU might be busy
|
||||
nvidia-smi
|
||||
|
||||
# Kill processes using GPU
|
||||
sudo fuser -v /dev/nvidia*
|
||||
```
|
||||
|
||||
### Low GPU Utilization During Transcoding
|
||||
|
||||
**Normal**: GTX 1070 is powerful. 20-40% utilization is expected for single stream.
|
||||
|
||||
**To max out GPU:**
|
||||
- Transcode multiple streams simultaneously
|
||||
- Use higher resolution source (4K)
|
||||
- Enable HEVC encoding
|
||||
|
||||
## Performance Benchmarks (GTX 1070)
|
||||
|
||||
**Typical Performance:**
|
||||
- **4K HEVC → 1080p H.264**: ~120-150 FPS (real-time)
|
||||
- **1080p H.264 → 720p H.264**: ~300-400 FPS
|
||||
- **Concurrent streams**: 4-6 (after unlocking limit)
|
||||
- **Power draw**: 80-120W during transcoding
|
||||
- **Temperature**: 55-65°C
|
||||
|
||||
**Compare to CPU (typical 4-core):**
|
||||
- **4K HEVC → 1080p H.264**: ~10-15 FPS
|
||||
- CPU would be at 100% utilization
|
||||
- GPU: 10-15x faster!
|
||||
|
||||
## Monitoring and Maintenance
|
||||
|
||||
### Create GPU Monitoring Dashboard
|
||||
|
||||
**Install nvtop (nvidia-top):**
|
||||
```bash
|
||||
sudo apt install nvtop
|
||||
```
|
||||
|
||||
**Run:**
|
||||
```bash
|
||||
nvtop
|
||||
```
|
||||
|
||||
Shows real-time GPU usage, memory, temperature, processes.
|
||||
|
||||
### Check GPU Health
|
||||
|
||||
```bash
|
||||
# Temperature
|
||||
nvidia-smi --query-gpu=temperature.gpu --format=csv
|
||||
|
||||
# Memory usage
|
||||
nvidia-smi --query-gpu=memory.used,memory.total --format=csv
|
||||
|
||||
# Fan speed
|
||||
nvidia-smi --query-gpu=fan.speed --format=csv
|
||||
|
||||
# Power draw
|
||||
nvidia-smi --query-gpu=power.draw,power.limit --format=csv
|
||||
```
|
||||
|
||||
### Automated Monitoring
|
||||
|
||||
Add to cron:
|
||||
```bash
|
||||
crontab -e
|
||||
|
||||
# Add:
|
||||
*/5 * * * * nvidia-smi --query-gpu=utilization.gpu,memory.used,temperature.gpu --format=csv,noheader >> /var/log/gpu-stats.log
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
✅ GPU is now configured for Jellyfin and Immich!
|
||||
|
||||
**Recommended:**
|
||||
1. Test transcoding with various file formats
|
||||
2. Upload photos to Immich and verify ML inference works
|
||||
3. Monitor GPU temperature and utilization
|
||||
4. Consider unlocking NVENC stream limit
|
||||
5. Set up automated monitoring
|
||||
|
||||
**Optional:**
|
||||
- Configure Tdarr for batch transcoding using GPU
|
||||
- Set up Plex (also supports NVENC)
|
||||
- Use GPU for other workloads (AI, rendering)
|
||||
|
||||
## Reference
|
||||
|
||||
### Quick Command Reference
|
||||
|
||||
```bash
|
||||
# Check GPU from host (Proxmox)
|
||||
lspci | grep -i nvidia
|
||||
|
||||
# Check GPU from VM
|
||||
nvidia-smi
|
||||
|
||||
# Test Docker GPU access
|
||||
docker run --rm --gpus all nvidia/cuda:12.2.0-base-ubuntu22.04 nvidia-smi
|
||||
|
||||
# Monitor GPU real-time
|
||||
watch -n 1 nvidia-smi
|
||||
|
||||
# Check Jellyfin GPU usage
|
||||
docker exec jellyfin nvidia-smi
|
||||
|
||||
# Restart Jellyfin with GPU
|
||||
cd ~/homelab/compose/media/frontend/jellyfin
|
||||
docker compose down && docker compose up -d
|
||||
|
||||
# View GPU processes
|
||||
nvidia-smi pmon
|
||||
|
||||
# GPU temperature
|
||||
nvidia-smi --query-gpu=temperature.gpu --format=csv,noheader
|
||||
```
|
||||
|
||||
### GTX 1070 Specifications
|
||||
|
||||
- **Architecture**: Pascal (GP104)
|
||||
- **CUDA Cores**: 1920
|
||||
- **Memory**: 8GB GDDR5
|
||||
- **Memory Bandwidth**: 256 GB/s
|
||||
- **TDP**: 150W
|
||||
- **NVENC**: 6th generation (H.264, HEVC)
|
||||
- **NVDEC**: 2nd generation
|
||||
- **Concurrent Streams**: 2 (unlockable to unlimited)
|
||||
|
||||
---
|
||||
|
||||
**Your GTX 1070 is now accelerating your homelab! 🚀**
|
||||
567
docs/guides/secrets-management.md
Normal file
567
docs/guides/secrets-management.md
Normal file
|
|
@ -0,0 +1,567 @@
|
|||
# Secrets and Environment Variables Management
|
||||
|
||||
This guide explains how to properly configure and manage secrets in your homelab.
|
||||
|
||||
## Overview
|
||||
|
||||
Every service uses environment variables stored in `.env` files for configuration. This approach:
|
||||
- ✅ Keeps secrets out of version control
|
||||
- ✅ Makes configuration changes easy
|
||||
- ✅ Follows Docker Compose best practices
|
||||
- ✅ Provides clear examples of what each secret should look like
|
||||
|
||||
## Finding What Needs Configuration
|
||||
|
||||
### Search for Placeholder Values
|
||||
|
||||
All secrets that need changing are marked with `changeme_`:
|
||||
|
||||
```bash
|
||||
# Find all files with placeholder secrets
|
||||
grep -r "changeme_" ~/homelab/compose
|
||||
|
||||
# Output shows exactly what needs updating:
|
||||
compose/core/lldap/.env:LLDAP_LDAP_USER_PASS=changeme_please_set_secure_password
|
||||
compose/core/lldap/.env:LLDAP_JWT_SECRET=changeme_please_set_random_secret
|
||||
compose/core/tinyauth/.env:LDAP_BIND_PASSWORD=changeme_please_set_secure_password
|
||||
...
|
||||
```
|
||||
|
||||
### Count What's Left to Configure
|
||||
|
||||
```bash
|
||||
# Count how many secrets still need updating
|
||||
grep -r "changeme_" ~/homelab/compose | wc -l
|
||||
|
||||
# Goal: 0
|
||||
```
|
||||
|
||||
## Generating Secrets
|
||||
|
||||
Each `.env` file includes comments showing:
|
||||
1. What the secret is for
|
||||
2. How to generate it
|
||||
3. What format it should be in
|
||||
|
||||
### Common Secret Types
|
||||
|
||||
#### 1. JWT Secrets (64 characters)
|
||||
|
||||
**Used by**: LLDAP, Vikunja, NextAuth
|
||||
|
||||
**Generate:**
|
||||
```bash
|
||||
openssl rand -hex 32
|
||||
```
|
||||
|
||||
**Example output:**
|
||||
```
|
||||
a1b2c3d4e5f67890abcdef1234567890a1b2c3d4e5f67890abcdef1234567890
|
||||
```
|
||||
|
||||
**Where to use:**
|
||||
- `LLDAP_JWT_SECRET`
|
||||
- `VIKUNJA_SERVICE_JWTSECRET`
|
||||
- `NEXTAUTH_SECRET`
|
||||
- `SESSION_SECRET`
|
||||
|
||||
#### 2. Database Passwords (32 alphanumeric)
|
||||
|
||||
**Used by**: Postgres, Immich, Vikunja, Linkwarden
|
||||
|
||||
**Generate:**
|
||||
```bash
|
||||
openssl rand -base64 32 | tr -d /=+ | cut -c1-32
|
||||
```
|
||||
|
||||
**Example output:**
|
||||
```
|
||||
aB3dEf7HiJ9kLmN2oPqR5sTuV8wXyZ1
|
||||
```
|
||||
|
||||
**Where to use:**
|
||||
- `DB_PASSWORD` (Immich)
|
||||
- `POSTGRES_PASSWORD` (Vikunja, Linkwarden)
|
||||
- `VIKUNJA_DATABASE_PASSWORD`
|
||||
|
||||
#### 3. Strong Passwords (16+ characters, mixed)
|
||||
|
||||
**Used by**: LLDAP admin, service admin accounts
|
||||
|
||||
**Generate:**
|
||||
```bash
|
||||
# Option 1: Using pwgen (install: apt install pwgen)
|
||||
pwgen -s 20 1
|
||||
|
||||
# Option 2: Using openssl
|
||||
openssl rand -base64 20 | tr -d /=+
|
||||
|
||||
# Option 3: Manual (recommended for main admin password)
|
||||
# Create something memorable but strong
|
||||
# Example format: MyS3cur3P@ssw0rd!2024#HomeL@b
|
||||
```
|
||||
|
||||
**Where to use:**
|
||||
- `LLDAP_LDAP_USER_PASS`
|
||||
- `LDAP_BIND_PASSWORD` (must match LLDAP_LDAP_USER_PASS!)
|
||||
|
||||
#### 4. API Keys / Master Keys (32 characters)
|
||||
|
||||
**Used by**: Meilisearch, various APIs
|
||||
|
||||
**Generate:**
|
||||
```bash
|
||||
openssl rand -hex 16
|
||||
```
|
||||
|
||||
**Example output:**
|
||||
```
|
||||
f6g7h8i901234abcdef567890a1b2c3d
|
||||
```
|
||||
|
||||
**Where to use:**
|
||||
- `MEILI_MASTER_KEY`
|
||||
|
||||
## Service-Specific Configuration
|
||||
|
||||
### Core Services
|
||||
|
||||
#### LLDAP (`compose/core/lldap/.env`)
|
||||
|
||||
```bash
|
||||
# Edit the file
|
||||
cd ~/homelab/compose/core/lldap
|
||||
nano .env
|
||||
```
|
||||
|
||||
**Required secrets:**
|
||||
|
||||
```env
|
||||
# Admin password - use a STRONG password you'll remember
|
||||
# Example: MyS3cur3P@ssw0rd!2024#HomeL@b
|
||||
LLDAP_LDAP_USER_PASS=changeme_please_set_secure_password
|
||||
|
||||
# JWT secret - generate with: openssl rand -hex 32
|
||||
# Example: a1b2c3d4e5f67890abcdef1234567890a1b2c3d4e5f67890abcdef1234567890
|
||||
LLDAP_JWT_SECRET=changeme_please_set_random_secret
|
||||
```
|
||||
|
||||
**Generate and update:**
|
||||
```bash
|
||||
# Generate JWT secret
|
||||
echo "LLDAP_JWT_SECRET=$(openssl rand -hex 32)"
|
||||
|
||||
# Choose a strong password for LLDAP_LDAP_USER_PASS
|
||||
# Write it down - you'll need it for Tinyauth too!
|
||||
```
|
||||
|
||||
#### Tinyauth (`compose/core/tinyauth/.env`)
|
||||
|
||||
```bash
|
||||
cd ~/homelab/compose/core/tinyauth
|
||||
nano .env
|
||||
```
|
||||
|
||||
**Required secrets:**
|
||||
|
||||
```env
|
||||
# MUST match LLDAP_LDAP_USER_PASS from lldap/.env
|
||||
LDAP_BIND_PASSWORD=changeme_please_set_secure_password
|
||||
|
||||
# Session secret - generate with: openssl rand -hex 32
|
||||
SESSION_SECRET=changeme_please_set_random_session_secret
|
||||
```
|
||||
|
||||
**⚠️ CRITICAL**: `LDAP_BIND_PASSWORD` must exactly match `LLDAP_LDAP_USER_PASS`!
|
||||
|
||||
```bash
|
||||
# Generate session secret
|
||||
echo "SESSION_SECRET=$(openssl rand -hex 32)"
|
||||
```
|
||||
|
||||
### Media Services
|
||||
|
||||
#### Immich (`compose/media/frontend/immich/.env`)
|
||||
|
||||
```bash
|
||||
cd ~/homelab/compose/media/frontend/immich
|
||||
nano .env
|
||||
```
|
||||
|
||||
**Required secrets:**
|
||||
|
||||
```env
|
||||
# Database password - generate with: openssl rand -base64 32 | tr -d /=+ | cut -c1-32
|
||||
DB_PASSWORD=changeme_please_set_secure_password
|
||||
```
|
||||
|
||||
```bash
|
||||
# Generate
|
||||
echo "DB_PASSWORD=$(openssl rand -base64 32 | tr -d /=+ | cut -c1-32)"
|
||||
```
|
||||
|
||||
### Utility Services
|
||||
|
||||
#### Linkwarden (`compose/services/linkwarden/.env`)
|
||||
|
||||
```bash
|
||||
cd ~/homelab/compose/services/linkwarden
|
||||
nano .env
|
||||
```
|
||||
|
||||
**Required secrets:**
|
||||
|
||||
```env
|
||||
# NextAuth secret - generate with: openssl rand -hex 32
|
||||
NEXTAUTH_SECRET=changeme_please_set_random_secret_key
|
||||
|
||||
# Postgres password - generate with: openssl rand -base64 32 | tr -d /=+ | cut -c1-32
|
||||
POSTGRES_PASSWORD=changeme_please_set_secure_postgres_password
|
||||
|
||||
# Meilisearch master key - generate with: openssl rand -hex 16
|
||||
MEILI_MASTER_KEY=changeme_please_set_meili_master_key
|
||||
```
|
||||
|
||||
```bash
|
||||
# Generate all three
|
||||
echo "NEXTAUTH_SECRET=$(openssl rand -hex 32)"
|
||||
echo "POSTGRES_PASSWORD=$(openssl rand -base64 32 | tr -d /=+ | cut -c1-32)"
|
||||
echo "MEILI_MASTER_KEY=$(openssl rand -hex 16)"
|
||||
```
|
||||
|
||||
#### Vikunja (`compose/services/vikunja/.env`)
|
||||
|
||||
```bash
|
||||
cd ~/homelab/compose/services/vikunja
|
||||
nano .env
|
||||
```
|
||||
|
||||
**Required secrets:**
|
||||
|
||||
```env
|
||||
# Database password (used in two places - must match!)
|
||||
VIKUNJA_DATABASE_PASSWORD=changeme_please_set_secure_password
|
||||
POSTGRES_PASSWORD=changeme_please_set_secure_password # Same value!
|
||||
|
||||
# JWT secret - generate with: openssl rand -hex 32
|
||||
VIKUNJA_SERVICE_JWTSECRET=changeme_please_set_random_jwt_secret
|
||||
```
|
||||
|
||||
**⚠️ CRITICAL**: Both password fields must match!
|
||||
|
||||
```bash
|
||||
# Generate
|
||||
DB_PASS=$(openssl rand -base64 32 | tr -d /=+ | cut -c1-32)
|
||||
echo "VIKUNJA_DATABASE_PASSWORD=$DB_PASS"
|
||||
echo "POSTGRES_PASSWORD=$DB_PASS"
|
||||
echo "VIKUNJA_SERVICE_JWTSECRET=$(openssl rand -hex 32)"
|
||||
```
|
||||
|
||||
## Automated Configuration Script
|
||||
|
||||
Create a script to generate all secrets at once:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# save as: ~/homelab/generate-secrets.sh
|
||||
|
||||
# Colors for output
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
echo -e "${YELLOW}Homelab Secrets Generator${NC}\n"
|
||||
|
||||
echo "This script will help you generate secure secrets for your homelab."
|
||||
echo "You'll need to manually copy these values into the respective .env files."
|
||||
echo ""
|
||||
|
||||
# LLDAP
|
||||
echo -e "${GREEN}=== LLDAP (compose/core/lldap/.env) ===${NC}"
|
||||
echo "LLDAP_JWT_SECRET=$(openssl rand -hex 32)"
|
||||
echo "LLDAP_LDAP_USER_PASS=<choose-a-strong-password-manually>"
|
||||
echo ""
|
||||
|
||||
# Tinyauth
|
||||
echo -e "${GREEN}=== Tinyauth (compose/core/tinyauth/.env) ===${NC}"
|
||||
echo "LDAP_BIND_PASSWORD=<same-as-LLDAP_LDAP_USER_PASS-above>"
|
||||
echo "SESSION_SECRET=$(openssl rand -hex 32)"
|
||||
echo ""
|
||||
|
||||
# Immich
|
||||
echo -e "${GREEN}=== Immich (compose/media/frontend/immich/.env) ===${NC}"
|
||||
echo "DB_PASSWORD=$(openssl rand -base64 32 | tr -d /=+ | cut -c1-32)"
|
||||
echo ""
|
||||
|
||||
# Linkwarden
|
||||
echo -e "${GREEN}=== Linkwarden (compose/services/linkwarden/.env) ===${NC}"
|
||||
echo "NEXTAUTH_SECRET=$(openssl rand -hex 32)"
|
||||
echo "POSTGRES_PASSWORD=$(openssl rand -base64 32 | tr -d /=+ | cut -c1-32)"
|
||||
echo "MEILI_MASTER_KEY=$(openssl rand -hex 16)"
|
||||
echo ""
|
||||
|
||||
# Vikunja
|
||||
VIKUNJA_PASS=$(openssl rand -base64 32 | tr -d /=+ | cut -c1-32)
|
||||
echo -e "${GREEN}=== Vikunja (compose/services/vikunja/.env) ===${NC}"
|
||||
echo "VIKUNJA_DATABASE_PASSWORD=$VIKUNJA_PASS"
|
||||
echo "POSTGRES_PASSWORD=$VIKUNJA_PASS # Must match above!"
|
||||
echo "VIKUNJA_SERVICE_JWTSECRET=$(openssl rand -hex 32)"
|
||||
echo ""
|
||||
|
||||
echo -e "${YELLOW}Done! Copy these values into your .env files.${NC}"
|
||||
echo ""
|
||||
echo "Don't forget to:"
|
||||
echo "1. Choose a strong LLDAP_LDAP_USER_PASS manually"
|
||||
echo "2. Use the same password for LDAP_BIND_PASSWORD in tinyauth"
|
||||
echo "3. Save all secrets in a password manager"
|
||||
```
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
chmod +x ~/homelab/generate-secrets.sh
|
||||
~/homelab/generate-secrets.sh > secrets.txt
|
||||
|
||||
# Review and copy secrets
|
||||
cat secrets.txt
|
||||
|
||||
# Keep this file safe or delete after copying to .env files
|
||||
```
|
||||
|
||||
## Security Best Practices
|
||||
|
||||
### 1. Use a Password Manager
|
||||
|
||||
Store all secrets in a password manager:
|
||||
- **1Password**: Great for teams
|
||||
- **Bitwarden**: Self-hostable option
|
||||
- **KeePassXC**: Offline, open-source
|
||||
|
||||
Create an entry for each service with:
|
||||
- Service name
|
||||
- URL
|
||||
- All secrets from `.env` file
|
||||
- Admin credentials
|
||||
|
||||
### 2. Never Commit Secrets
|
||||
|
||||
The repository `.gitignore` already excludes `.env` files, but double-check:
|
||||
|
||||
```bash
|
||||
# Verify .env files are ignored
|
||||
git status
|
||||
|
||||
# Should NOT show any .env files
|
||||
```
|
||||
|
||||
### 3. Backup Your Secrets
|
||||
|
||||
```bash
|
||||
# Create encrypted backup of all .env files
|
||||
cd ~/homelab
|
||||
tar czf env-backup-$(date +%Y%m%d).tar.gz $(find compose -name ".env")
|
||||
|
||||
# Encrypt with GPG
|
||||
gpg -c env-backup-$(date +%Y%m%d).tar.gz
|
||||
|
||||
# Store encrypted file safely
|
||||
mv env-backup-*.tar.gz.gpg ~/backups/
|
||||
|
||||
# Delete unencrypted tar
|
||||
rm env-backup-*.tar.gz
|
||||
```
|
||||
|
||||
### 4. Rotate Secrets Regularly
|
||||
|
||||
Change critical secrets periodically:
|
||||
- **Admin passwords**: Every 90 days
|
||||
- **JWT secrets**: Every 180 days
|
||||
- **Database passwords**: When personnel changes
|
||||
|
||||
### 5. Limit Secret Access
|
||||
|
||||
- Don't share raw secrets over email/chat
|
||||
- Use password manager's sharing features
|
||||
- Delete shared secrets when no longer needed
|
||||
|
||||
## Verification
|
||||
|
||||
### Check All Secrets Are Set
|
||||
|
||||
```bash
|
||||
# Should return 0 (no changeme_ values left)
|
||||
grep -r "changeme_" ~/homelab/compose | wc -l
|
||||
```
|
||||
|
||||
### Test Service Startup
|
||||
|
||||
```bash
|
||||
# Start a service and check for password errors
|
||||
cd ~/homelab/compose/core/lldap
|
||||
docker compose up -d
|
||||
docker compose logs
|
||||
|
||||
# Should NOT see:
|
||||
# - "invalid password"
|
||||
# - "authentication failed"
|
||||
# - "secret not set"
|
||||
```
|
||||
|
||||
### Verify SSO Works
|
||||
|
||||
1. Start LLDAP and Tinyauth
|
||||
2. Access protected service (e.g., https://tasks.fig.systems)
|
||||
3. Should redirect to auth.fig.systems
|
||||
4. Login with LLDAP credentials
|
||||
5. Should redirect back to service
|
||||
|
||||
If this works, your LLDAP ↔ Tinyauth passwords match! ✅
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
### ❌ Using Weak Passwords
|
||||
|
||||
**Don't:**
|
||||
```env
|
||||
LLDAP_LDAP_USER_PASS=password123
|
||||
```
|
||||
|
||||
**Do:**
|
||||
```env
|
||||
LLDAP_LDAP_USER_PASS=MyS3cur3P@ssw0rd!2024#HomeL@b
|
||||
```
|
||||
|
||||
### ❌ Mismatched Passwords
|
||||
|
||||
**Don't:**
|
||||
```env
|
||||
# In lldap/.env
|
||||
LLDAP_LDAP_USER_PASS=password1
|
||||
|
||||
# In tinyauth/.env
|
||||
LDAP_BIND_PASSWORD=password2 # Different!
|
||||
```
|
||||
|
||||
**Do:**
|
||||
```env
|
||||
# In lldap/.env
|
||||
LLDAP_LDAP_USER_PASS=MyS3cur3P@ssw0rd!2024#HomeL@b
|
||||
|
||||
# In tinyauth/.env
|
||||
LDAP_BIND_PASSWORD=MyS3cur3P@ssw0rd!2024#HomeL@b # Same!
|
||||
```
|
||||
|
||||
### ❌ Using Same Secret Everywhere
|
||||
|
||||
**Don't:**
|
||||
```env
|
||||
# Same secret in multiple places
|
||||
LLDAP_JWT_SECRET=abc123
|
||||
NEXTAUTH_SECRET=abc123
|
||||
SESSION_SECRET=abc123
|
||||
```
|
||||
|
||||
**Do:**
|
||||
```env
|
||||
# Unique secret for each
|
||||
LLDAP_JWT_SECRET=a1b2c3d4e5f67890...
|
||||
NEXTAUTH_SECRET=f6g7h8i9j0k1l2m3...
|
||||
SESSION_SECRET=x9y8z7w6v5u4t3s2...
|
||||
```
|
||||
|
||||
### ❌ Forgetting to Update Both Password Fields
|
||||
|
||||
In Vikunja `.env`, both must match:
|
||||
```env
|
||||
# Both must be the same!
|
||||
VIKUNJA_DATABASE_PASSWORD=aB3dEf7HiJ9kLmN2oPqR5sTuV8wXyZ1
|
||||
POSTGRES_PASSWORD=aB3dEf7HiJ9kLmN2oPqR5sTuV8wXyZ1
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Authentication failed" in Tinyauth
|
||||
|
||||
**Cause**: LDAP_BIND_PASSWORD doesn't match LLDAP_LDAP_USER_PASS
|
||||
|
||||
**Fix**:
|
||||
```bash
|
||||
# Check LLDAP password
|
||||
grep LLDAP_LDAP_USER_PASS ~/homelab/compose/core/lldap/.env
|
||||
|
||||
# Check Tinyauth password
|
||||
grep LDAP_BIND_PASSWORD ~/homelab/compose/core/tinyauth/.env
|
||||
|
||||
# They should be identical!
|
||||
```
|
||||
|
||||
### "Invalid JWT" errors
|
||||
|
||||
**Cause**: JWT_SECRET is too short or invalid format
|
||||
|
||||
**Fix**:
|
||||
```bash
|
||||
# Regenerate with proper length
|
||||
openssl rand -hex 32
|
||||
|
||||
# Update in .env file
|
||||
```
|
||||
|
||||
### "Database connection failed"
|
||||
|
||||
**Cause**: Database password mismatch
|
||||
|
||||
**Fix**:
|
||||
```bash
|
||||
# Check both password fields match
|
||||
grep -E "(POSTGRES_PASSWORD|DATABASE_PASSWORD)" compose/services/vikunja/.env
|
||||
|
||||
# Both should be identical
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
Once all secrets are configured:
|
||||
1. ✅ [Deploy services](../getting-started.md#step-6-deploy-services)
|
||||
2. ✅ [Configure SSO](../services/sso-setup.md)
|
||||
3. ✅ [Set up backups](../operations/backups.md)
|
||||
4. ✅ Store secrets in password manager
|
||||
5. ✅ Create encrypted backup of .env files
|
||||
|
||||
## Reference
|
||||
|
||||
### Quick Command Reference
|
||||
|
||||
```bash
|
||||
# Generate 64-char hex
|
||||
openssl rand -hex 32
|
||||
|
||||
# Generate 32-char password
|
||||
openssl rand -base64 32 | tr -d /=+ | cut -c1-32
|
||||
|
||||
# Generate 32-char hex
|
||||
openssl rand -hex 16
|
||||
|
||||
# Find all changeme_ values
|
||||
grep -r "changeme_" compose/
|
||||
|
||||
# Count remaining secrets to configure
|
||||
grep -r "changeme_" compose/ | wc -l
|
||||
|
||||
# Backup all .env files (encrypted)
|
||||
tar czf env-files.tar.gz $(find compose -name ".env")
|
||||
gpg -c env-files.tar.gz
|
||||
```
|
||||
|
||||
### Secret Types Quick Reference
|
||||
|
||||
| Secret Type | Command | Example Length | Used By |
|
||||
|-------------|---------|----------------|---------|
|
||||
| JWT Secret | `openssl rand -hex 32` | 64 chars | LLDAP, Vikunja, NextAuth |
|
||||
| Session Secret | `openssl rand -hex 32` | 64 chars | Tinyauth |
|
||||
| DB Password | `openssl rand -base64 32 \| tr -d /=+ \| cut -c1-32` | 32 chars | Postgres, Immich |
|
||||
| API Key | `openssl rand -hex 16` | 32 chars | Meilisearch |
|
||||
| Admin Password | Manual | 16+ chars | LLDAP admin |
|
||||
|
||||
---
|
||||
|
||||
**Remember**: Strong, unique secrets are your first line of defense. Take the time to generate them properly! 🔐
|
||||
567
docs/quick-reference.md
Normal file
567
docs/quick-reference.md
Normal file
|
|
@ -0,0 +1,567 @@
|
|||
# Quick Reference Guide
|
||||
|
||||
Fast reference for common tasks and commands.
|
||||
|
||||
## Service URLs
|
||||
|
||||
All services accessible via:
|
||||
- Primary domain: `*.fig.systems`
|
||||
- Secondary domain: `*.edfig.dev`
|
||||
|
||||
### Core Services
|
||||
```
|
||||
https://traefik.fig.systems # Reverse proxy dashboard
|
||||
https://lldap.fig.systems # User directory
|
||||
https://auth.fig.systems # SSO authentication
|
||||
```
|
||||
|
||||
### Dashboard & Management
|
||||
```
|
||||
https://home.fig.systems # Homarr dashboard (START HERE!)
|
||||
https://backup.fig.systems # Backrest backup manager
|
||||
```
|
||||
|
||||
### Media Services
|
||||
```
|
||||
https://flix.fig.systems # Jellyfin media server
|
||||
https://photos.fig.systems # Immich photo library
|
||||
https://requests.fig.systems # Jellyseerr media requests
|
||||
https://sonarr.fig.systems # TV show automation
|
||||
https://radarr.fig.systems # Movie automation
|
||||
https://sabnzbd.fig.systems # Usenet downloader
|
||||
https://qbt.fig.systems # qBittorrent client
|
||||
```
|
||||
|
||||
### Utility Services
|
||||
```
|
||||
https://links.fig.systems # Linkwarden bookmarks
|
||||
https://tasks.fig.systems # Vikunja task management
|
||||
https://garage.fig.systems # LubeLogger vehicle tracking
|
||||
https://books.fig.systems # Calibre-web ebook library
|
||||
https://booklore.fig.systems # Book tracking
|
||||
https://rss.fig.systems # FreshRSS reader
|
||||
https://files.fig.systems # File Browser
|
||||
```
|
||||
|
||||
## Common Commands
|
||||
|
||||
### Docker Compose
|
||||
|
||||
```bash
|
||||
# Start service
|
||||
cd ~/homelab/compose/path/to/service
|
||||
docker compose up -d
|
||||
|
||||
# View logs
|
||||
docker compose logs -f
|
||||
|
||||
# Restart service
|
||||
docker compose restart
|
||||
|
||||
# Stop service
|
||||
docker compose down
|
||||
|
||||
# Update and restart
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
|
||||
# Rebuild service
|
||||
docker compose up -d --force-recreate
|
||||
```
|
||||
|
||||
### Docker Management
|
||||
|
||||
```bash
|
||||
# List all containers
|
||||
docker ps
|
||||
|
||||
# List all containers (including stopped)
|
||||
docker ps -a
|
||||
|
||||
# View logs
|
||||
docker logs <container_name>
|
||||
docker logs -f <container_name> # Follow logs
|
||||
|
||||
# Execute command in container
|
||||
docker exec -it <container_name> bash
|
||||
|
||||
# View resource usage
|
||||
docker stats
|
||||
|
||||
# Remove stopped containers
|
||||
docker container prune
|
||||
|
||||
# Remove unused images
|
||||
docker image prune -a
|
||||
|
||||
# Remove unused volumes (CAREFUL!)
|
||||
docker volume prune
|
||||
|
||||
# Complete cleanup
|
||||
docker system prune -a --volumes
|
||||
```
|
||||
|
||||
### Service Management
|
||||
|
||||
```bash
|
||||
# Start all core services
|
||||
cd ~/homelab/compose/core
|
||||
for dir in traefik lldap tinyauth; do
|
||||
cd $dir && docker compose up -d && cd ..
|
||||
done
|
||||
|
||||
# Stop all services
|
||||
cd ~/homelab
|
||||
find compose -name "compose.yaml" -execdir docker compose down \;
|
||||
|
||||
# Restart single service
|
||||
cd ~/homelab/compose/services/servicename
|
||||
docker compose restart
|
||||
|
||||
# View all running containers
|
||||
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
|
||||
```
|
||||
|
||||
### System Checks
|
||||
|
||||
```bash
|
||||
# Check all containers
|
||||
docker ps --format "table {{.Names}}\t{{.Status}}"
|
||||
|
||||
# Check network
|
||||
docker network inspect homelab
|
||||
|
||||
# Check disk usage
|
||||
docker system df
|
||||
df -h
|
||||
|
||||
# Check logs for errors
|
||||
docker compose logs --tail=100 | grep -i error
|
||||
|
||||
# Test DNS resolution
|
||||
dig home.fig.systems +short
|
||||
|
||||
# Test SSL
|
||||
curl -I https://home.fig.systems
|
||||
```
|
||||
|
||||
## Secret Generation
|
||||
|
||||
```bash
|
||||
# JWT/Session secrets (64 char)
|
||||
openssl rand -hex 32
|
||||
|
||||
# Database passwords (32 char alphanumeric)
|
||||
openssl rand -base64 32 | tr -d /=+ | cut -c1-32
|
||||
|
||||
# API keys (32 char hex)
|
||||
openssl rand -hex 16
|
||||
|
||||
# Find what needs updating
|
||||
grep -r "changeme_" ~/homelab/compose
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Service Won't Start
|
||||
|
||||
```bash
|
||||
# Check logs
|
||||
docker compose logs
|
||||
|
||||
# Check container status
|
||||
docker compose ps
|
||||
|
||||
# Check for port conflicts
|
||||
sudo netstat -tulpn | grep :80
|
||||
sudo netstat -tulpn | grep :443
|
||||
|
||||
# Recreate container
|
||||
docker compose down
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
### SSL Certificate Issues
|
||||
|
||||
```bash
|
||||
# Check Traefik logs
|
||||
docker logs traefik | grep -i certificate
|
||||
|
||||
# Check Let's Encrypt logs
|
||||
docker logs traefik | grep -i letsencrypt
|
||||
|
||||
# Verify DNS
|
||||
dig home.fig.systems +short
|
||||
|
||||
# Test port 80 accessibility
|
||||
curl -I http://home.fig.systems
|
||||
```
|
||||
|
||||
### SSO Not Working
|
||||
|
||||
```bash
|
||||
# Check LLDAP
|
||||
docker logs lldap
|
||||
|
||||
# Check Tinyauth
|
||||
docker logs tinyauth
|
||||
|
||||
# Verify passwords match
|
||||
grep LLDAP_LDAP_USER_PASS ~/homelab/compose/core/lldap/.env
|
||||
grep LDAP_BIND_PASSWORD ~/homelab/compose/core/tinyauth/.env
|
||||
|
||||
# Test LDAP connection
|
||||
docker exec tinyauth nc -zv lldap 3890
|
||||
```
|
||||
|
||||
### Database Connection Failures
|
||||
|
||||
```bash
|
||||
# Check database container
|
||||
docker ps | grep postgres
|
||||
|
||||
# View database logs
|
||||
docker logs <db_container_name>
|
||||
|
||||
# Test connection from app container
|
||||
docker exec <app_container> nc -zv <db_container> 5432
|
||||
|
||||
# Verify password in .env
|
||||
cat .env | grep POSTGRES_PASSWORD
|
||||
```
|
||||
|
||||
## File Locations
|
||||
|
||||
### Configuration
|
||||
```
|
||||
~/homelab/compose/ # All services
|
||||
~/homelab/compose/core/ # Core infrastructure
|
||||
~/homelab/compose/media/ # Media services
|
||||
~/homelab/compose/services/ # Utility services
|
||||
```
|
||||
|
||||
### Service Data
|
||||
```
|
||||
compose/<service>/config/ # Service configuration
|
||||
compose/<service>/data/ # Service data
|
||||
compose/<service>/db/ # Database files
|
||||
compose/<service>/.env # Environment variables
|
||||
```
|
||||
|
||||
### Media Files
|
||||
```
|
||||
/media/movies/ # Movies
|
||||
/media/tv/ # TV shows
|
||||
/media/music/ # Music
|
||||
/media/photos/ # Photos
|
||||
/media/books/ # Books
|
||||
/media/downloads/ # Active downloads
|
||||
/media/complete/ # Completed downloads
|
||||
```
|
||||
|
||||
### Logs
|
||||
```
|
||||
docker logs <container_name> # Container logs
|
||||
compose/<service>/logs/ # Service-specific logs (if configured)
|
||||
/var/lib/docker/volumes/ # Volume data
|
||||
```
|
||||
|
||||
## Network
|
||||
|
||||
### Create Network
|
||||
```bash
|
||||
docker network create homelab
|
||||
```
|
||||
|
||||
### Inspect Network
|
||||
```bash
|
||||
docker network inspect homelab
|
||||
```
|
||||
|
||||
### Connect Container to Network
|
||||
```bash
|
||||
docker network connect homelab <container_name>
|
||||
```
|
||||
|
||||
## GPU (NVIDIA GTX 1070)
|
||||
|
||||
### Check GPU Status
|
||||
```bash
|
||||
nvidia-smi
|
||||
```
|
||||
|
||||
### Test GPU in Docker
|
||||
```bash
|
||||
docker run --rm --gpus all nvidia/cuda:12.2.0-base-ubuntu22.04 nvidia-smi
|
||||
```
|
||||
|
||||
### Monitor GPU Usage
|
||||
```bash
|
||||
watch -n 1 nvidia-smi
|
||||
```
|
||||
|
||||
### Check GPU in Container
|
||||
```bash
|
||||
docker exec jellyfin nvidia-smi
|
||||
docker exec immich_machine_learning nvidia-smi
|
||||
```
|
||||
|
||||
## Backup
|
||||
|
||||
### Backup Configuration Files
|
||||
```bash
|
||||
cd ~/homelab
|
||||
tar czf homelab-config-$(date +%Y%m%d).tar.gz \
|
||||
$(find compose -name ".env") \
|
||||
$(find compose -name "compose.yaml")
|
||||
```
|
||||
|
||||
### Backup Service Data
|
||||
```bash
|
||||
# Example: Backup Immich
|
||||
cd ~/homelab/compose/media/frontend/immich
|
||||
tar czf immich-backup-$(date +%Y%m%d).tar.gz upload/ config/
|
||||
```
|
||||
|
||||
### Restore Configuration
|
||||
```bash
|
||||
tar xzf homelab-config-YYYYMMDD.tar.gz
|
||||
```
|
||||
|
||||
## Updates
|
||||
|
||||
### Update Single Service
|
||||
```bash
|
||||
cd ~/homelab/compose/path/to/service
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
### Update All Services
|
||||
```bash
|
||||
cd ~/homelab
|
||||
for dir in $(find compose -name "compose.yaml" -exec dirname {} \;); do
|
||||
echo "Updating $dir"
|
||||
cd $dir
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
cd ~/homelab
|
||||
done
|
||||
```
|
||||
|
||||
### Update Docker
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt upgrade docker-ce docker-ce-cli containerd.io
|
||||
```
|
||||
|
||||
## Performance
|
||||
|
||||
### Check Resource Usage
|
||||
```bash
|
||||
# Overall system
|
||||
htop
|
||||
|
||||
# Docker containers
|
||||
docker stats
|
||||
|
||||
# Disk usage
|
||||
df -h
|
||||
docker system df
|
||||
|
||||
# Network usage
|
||||
iftop
|
||||
```
|
||||
|
||||
### Clean Up Disk Space
|
||||
```bash
|
||||
# Docker cleanup
|
||||
docker system prune -a
|
||||
|
||||
# Remove old logs
|
||||
sudo journalctl --vacuum-time=7d
|
||||
|
||||
# Find large files
|
||||
du -h /media | sort -rh | head -20
|
||||
```
|
||||
|
||||
## DNS Configuration
|
||||
|
||||
### Cloudflare Example
|
||||
```
|
||||
Type: A
|
||||
Name: *
|
||||
Content: YOUR_SERVER_IP
|
||||
Proxy: Off (disable for Let's Encrypt)
|
||||
TTL: Auto
|
||||
```
|
||||
|
||||
### Local DNS (Pi-hole/hosts file)
|
||||
```
|
||||
192.168.1.100 home.fig.systems
|
||||
192.168.1.100 flix.fig.systems
|
||||
192.168.1.100 photos.fig.systems
|
||||
# ... etc
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
### List All Services with Secrets
|
||||
```bash
|
||||
find ~/homelab/compose -name ".env" -exec echo {} \;
|
||||
```
|
||||
|
||||
### Check for Unconfigured Secrets
|
||||
```bash
|
||||
grep -r "changeme_" ~/homelab/compose | wc -l
|
||||
# Should be 0
|
||||
```
|
||||
|
||||
### Backup All .env Files
|
||||
```bash
|
||||
cd ~/homelab
|
||||
tar czf env-files-$(date +%Y%m%d).tar.gz $(find compose -name ".env")
|
||||
gpg -c env-files-$(date +%Y%m%d).tar.gz
|
||||
```
|
||||
|
||||
## Monitoring
|
||||
|
||||
### Service Health
|
||||
```bash
|
||||
# Check all containers are running
|
||||
docker ps --format "{{.Names}}: {{.Status}}" | grep -v "Up"
|
||||
|
||||
# Check for restarts
|
||||
docker ps --format "{{.Names}}: {{.Status}}" | grep "Restarting"
|
||||
|
||||
# Check logs for errors
|
||||
docker compose logs --tail=100 | grep -i error
|
||||
```
|
||||
|
||||
### SSL Certificate Expiry
|
||||
```bash
|
||||
# Check cert expiry
|
||||
echo | openssl s_client -servername home.fig.systems -connect home.fig.systems:443 2>/dev/null | openssl x509 -noout -dates
|
||||
```
|
||||
|
||||
### Disk Space
|
||||
```bash
|
||||
# Overall
|
||||
df -h
|
||||
|
||||
# Docker
|
||||
docker system df
|
||||
|
||||
# Media
|
||||
du -sh /media/*
|
||||
```
|
||||
|
||||
## Common File Paths
|
||||
|
||||
```bash
|
||||
# Core services
|
||||
~/homelab/compose/core/traefik/
|
||||
~/homelab/compose/core/lldap/
|
||||
~/homelab/compose/core/tinyauth/
|
||||
|
||||
# Media
|
||||
~/homelab/compose/media/frontend/jellyfin/
|
||||
~/homelab/compose/media/frontend/immich/
|
||||
~/homelab/compose/media/automation/sonarr/
|
||||
|
||||
# Utilities
|
||||
~/homelab/compose/services/homarr/
|
||||
~/homelab/compose/services/backrest/
|
||||
~/homelab/compose/services/linkwarden/
|
||||
|
||||
# Documentation
|
||||
~/homelab/docs/
|
||||
~/homelab/README.md
|
||||
```
|
||||
|
||||
## Port Reference
|
||||
|
||||
```
|
||||
80 - HTTP (Traefik)
|
||||
443 - HTTPS (Traefik)
|
||||
3890 - LLDAP
|
||||
6881 - qBittorrent (TCP/UDP)
|
||||
8096 - Jellyfin
|
||||
2283 - Immich
|
||||
```
|
||||
|
||||
## Default Credentials
|
||||
|
||||
⚠️ **Change these immediately after first login!**
|
||||
|
||||
### qBittorrent
|
||||
```
|
||||
Username: admin
|
||||
Password: adminadmin
|
||||
```
|
||||
|
||||
### Microbin
|
||||
```
|
||||
Check compose/services/microbin/.env
|
||||
MICROBIN_ADMIN_USERNAME
|
||||
MICROBIN_ADMIN_PASSWORD
|
||||
```
|
||||
|
||||
### All Other Services
|
||||
Use SSO (LLDAP) or create admin account on first visit.
|
||||
|
||||
## Quick Deployment
|
||||
|
||||
### Deploy Everything
|
||||
```bash
|
||||
cd ~/homelab
|
||||
chmod +x deploy-all.sh
|
||||
./deploy-all.sh
|
||||
```
|
||||
|
||||
### Deploy Core Only
|
||||
```bash
|
||||
cd ~/homelab/compose/core/traefik && docker compose up -d
|
||||
cd ../lldap && docker compose up -d
|
||||
cd ../tinyauth && docker compose up -d
|
||||
```
|
||||
|
||||
### Deploy Media Stack
|
||||
```bash
|
||||
cd ~/homelab/compose/media/frontend
|
||||
for dir in */; do cd "$dir" && docker compose up -d && cd ..; done
|
||||
|
||||
cd ~/homelab/compose/media/automation
|
||||
for dir in */; do cd "$dir" && docker compose up -d && cd ..; done
|
||||
```
|
||||
|
||||
## Emergency Procedures
|
||||
|
||||
### Stop All Services
|
||||
```bash
|
||||
cd ~/homelab
|
||||
find compose -name "compose.yaml" -execdir docker compose down \;
|
||||
```
|
||||
|
||||
### Remove All Containers (Nuclear Option)
|
||||
```bash
|
||||
docker stop $(docker ps -aq)
|
||||
docker rm $(docker ps -aq)
|
||||
```
|
||||
|
||||
### Reset Network
|
||||
```bash
|
||||
docker network rm homelab
|
||||
docker network create homelab
|
||||
```
|
||||
|
||||
### Reset Service
|
||||
```bash
|
||||
cd ~/homelab/compose/path/to/service
|
||||
docker compose down -v # REMOVES VOLUMES!
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**For detailed guides, see the [docs folder](./README.md).**
|
||||
366
docs/services/README.md
Normal file
366
docs/services/README.md
Normal file
|
|
@ -0,0 +1,366 @@
|
|||
# Services Overview
|
||||
|
||||
Complete list of all services in the homelab with descriptions and use cases.
|
||||
|
||||
## Core Infrastructure (Required)
|
||||
|
||||
### Traefik
|
||||
- **URL**: https://traefik.fig.systems
|
||||
- **Purpose**: Reverse proxy with automatic SSL/TLS
|
||||
- **Why**: Routes all traffic, manages Let's Encrypt certificates
|
||||
- **Required**: ✅ Yes - Nothing works without this
|
||||
|
||||
### LLDAP
|
||||
- **URL**: https://lldap.fig.systems
|
||||
- **Purpose**: Lightweight LDAP directory for user management
|
||||
- **Why**: Centralized user database for SSO
|
||||
- **Required**: ✅ Yes (if using SSO)
|
||||
- **Default Login**: admin / <your LLDAP_LDAP_USER_PASS>
|
||||
|
||||
### Tinyauth
|
||||
- **URL**: https://auth.fig.systems
|
||||
- **Purpose**: SSO forward authentication middleware
|
||||
- **Why**: Single login for all services
|
||||
- **Required**: ✅ Yes (if using SSO)
|
||||
|
||||
## Dashboard & Management
|
||||
|
||||
### Homarr
|
||||
- **URL**: https://home.fig.systems
|
||||
- **Purpose**: Service dashboard with auto-discovery
|
||||
- **Why**: See all your services in one place, monitor status
|
||||
- **Required**: ⬜ No, but highly recommended
|
||||
- **Features**:
|
||||
- Auto-discovers Docker containers
|
||||
- Customizable widgets
|
||||
- Service status monitoring
|
||||
- Integration with media services
|
||||
|
||||
### Backrest
|
||||
- **URL**: https://backup.fig.systems
|
||||
- **Purpose**: Backup management with web UI (uses Restic)
|
||||
- **Why**: Encrypted, deduplicated backups to Backblaze B2
|
||||
- **Required**: ⬜ No, but critical for data safety
|
||||
- **Features**:
|
||||
- Web-based backup management
|
||||
- Scheduled backups
|
||||
- File browsing and restore
|
||||
- Encryption at rest
|
||||
- S3-compatible storage support
|
||||
|
||||
## Media Services
|
||||
|
||||
### Jellyfin
|
||||
- **URL**: https://flix.fig.systems
|
||||
- **Purpose**: Media server (Netflix alternative)
|
||||
- **Why**: Watch your movies/TV shows anywhere
|
||||
- **Required**: ⬜ No
|
||||
- **Features**:
|
||||
- Stream to any device
|
||||
- Hardware transcoding (with GPU)
|
||||
- Live TV & DVR
|
||||
- Mobile apps available
|
||||
- Subtitle support
|
||||
|
||||
### Immich
|
||||
- **URL**: https://photos.fig.systems
|
||||
- **Purpose**: Photo and video management (Google Photos alternative)
|
||||
- **Why**: Self-hosted photo library with ML features
|
||||
- **Required**: ⬜ No
|
||||
- **Features**:
|
||||
- Face recognition (with GPU)
|
||||
- Object detection
|
||||
- Mobile apps with auto-upload
|
||||
- Timeline view
|
||||
- Album organization
|
||||
|
||||
### Jellyseerr
|
||||
- **URL**: https://requests.fig.systems
|
||||
- **Purpose**: Media request management
|
||||
- **Why**: Let users request movies/shows
|
||||
- **Required**: ⬜ No (only if using Sonarr/Radarr)
|
||||
- **Features**:
|
||||
- Request movies and TV shows
|
||||
- Integration with Jellyfin
|
||||
- User permissions
|
||||
- Notification system
|
||||
|
||||
## Media Automation
|
||||
|
||||
### Sonarr
|
||||
- **URL**: https://sonarr.fig.systems
|
||||
- **Purpose**: TV show automation
|
||||
- **Why**: Automatically download and organize TV shows
|
||||
- **Required**: ⬜ No
|
||||
- **Features**:
|
||||
- Episode tracking
|
||||
- Automatic downloading
|
||||
- Quality management
|
||||
- Calendar view
|
||||
|
||||
### Radarr
|
||||
- **URL**: https://radarr.fig.systems
|
||||
- **Purpose**: Movie automation
|
||||
- **Why**: Automatically download and organize movies
|
||||
- **Required**: ⬜ No
|
||||
- **Features**:
|
||||
- Movie tracking
|
||||
- Automatic downloading
|
||||
- Quality profiles
|
||||
- Collection management
|
||||
|
||||
### SABnzbd
|
||||
- **URL**: https://sabnzbd.fig.systems
|
||||
- **Purpose**: Usenet downloader
|
||||
- **Why**: Download from Usenet newsgroups
|
||||
- **Required**: ⬜ No (only if using Usenet)
|
||||
- **Features**:
|
||||
- Fast downloads
|
||||
- Automatic verification and repair
|
||||
- Category-based processing
|
||||
- Password support
|
||||
|
||||
### qBittorrent
|
||||
- **URL**: https://qbt.fig.systems
|
||||
- **Purpose**: BitTorrent client
|
||||
- **Why**: Download torrents
|
||||
- **Required**: ⬜ No (only if using torrents)
|
||||
- **Features**:
|
||||
- Web-based UI
|
||||
- RSS support
|
||||
- Sequential downloading
|
||||
- IP filtering
|
||||
|
||||
## Productivity Services
|
||||
|
||||
### Linkwarden
|
||||
- **URL**: https://links.fig.systems
|
||||
- **Purpose**: Bookmark manager
|
||||
- **Why**: Save and organize web links
|
||||
- **Required**: ⬜ No
|
||||
- **Features**:
|
||||
- Collaborative bookmarking
|
||||
- Full-text search
|
||||
- Screenshots and PDFs
|
||||
- Tags and collections
|
||||
- Browser extensions
|
||||
|
||||
### Vikunja
|
||||
- **URL**: https://tasks.fig.systems
|
||||
- **Purpose**: Task management (Todoist alternative)
|
||||
- **Why**: Track tasks and projects
|
||||
- **Required**: ⬜ No
|
||||
- **Features**:
|
||||
- Kanban boards
|
||||
- Lists and sub-tasks
|
||||
- Due dates and reminders
|
||||
- Collaboration
|
||||
- CalDAV support
|
||||
|
||||
### FreshRSS
|
||||
- **URL**: https://rss.fig.systems
|
||||
- **Purpose**: RSS/Atom feed reader
|
||||
- **Why**: Aggregate news and blogs
|
||||
- **Required**: ⬜ No
|
||||
- **Features**:
|
||||
- Web-based reader
|
||||
- Mobile apps via API
|
||||
- Filtering and search
|
||||
- Multi-user support
|
||||
|
||||
## Specialized Services
|
||||
|
||||
### LubeLogger
|
||||
- **URL**: https://garage.fig.systems
|
||||
- **Purpose**: Vehicle maintenance tracker
|
||||
- **Why**: Track mileage, maintenance, costs
|
||||
- **Required**: ⬜ No
|
||||
- **Features**:
|
||||
- Service records
|
||||
- Fuel tracking
|
||||
- Cost analysis
|
||||
- Reminder system
|
||||
- Export data
|
||||
|
||||
### Calibre-web
|
||||
- **URL**: https://books.fig.systems
|
||||
- **Purpose**: Ebook library manager
|
||||
- **Why**: Manage and read ebooks
|
||||
- **Required**: ⬜ No
|
||||
- **Features**:
|
||||
- Web-based ebook reader
|
||||
- Format conversion
|
||||
- Metadata management
|
||||
- Send to Kindle
|
||||
- OPDS support
|
||||
|
||||
### Booklore
|
||||
- **URL**: https://booklore.fig.systems
|
||||
- **Purpose**: Book tracking and reviews
|
||||
- **Why**: Track reading progress and reviews
|
||||
- **Required**: ⬜ No
|
||||
- **Features**:
|
||||
- Reading lists
|
||||
- Progress tracking
|
||||
- Reviews and ratings
|
||||
- Import from Goodreads
|
||||
|
||||
### RSSHub
|
||||
- **URL**: https://rsshub.fig.systems
|
||||
- **Purpose**: RSS feed generator
|
||||
- **Why**: Generate RSS feeds for sites without them
|
||||
- **Required**: ⬜ No
|
||||
- **Features**:
|
||||
- 1000+ source support
|
||||
- Custom routes
|
||||
- Filter and transform feeds
|
||||
|
||||
### MicroBin
|
||||
- **URL**: https://paste.fig.systems
|
||||
- **Purpose**: Encrypted pastebin with file upload
|
||||
- **Why**: Share code snippets and files
|
||||
- **Required**: ⬜ No
|
||||
- **Features**:
|
||||
- Encryption support
|
||||
- File uploads
|
||||
- Burn after reading
|
||||
- Custom expiry
|
||||
- Password protection
|
||||
|
||||
### File Browser
|
||||
- **URL**: https://files.fig.systems
|
||||
- **Purpose**: Web-based file manager
|
||||
- **Why**: Browse and manage media files
|
||||
- **Required**: ⬜ No
|
||||
- **Features**:
|
||||
- Upload/download files
|
||||
- Preview images and videos
|
||||
- Text editor
|
||||
- File sharing
|
||||
- User permissions
|
||||
|
||||
## Service Categories
|
||||
|
||||
### Minimum Viable Setup
|
||||
Just want to get started? Deploy these:
|
||||
1. Traefik
|
||||
2. LLDAP
|
||||
3. Tinyauth
|
||||
4. Homarr
|
||||
|
||||
### Media Enthusiast Setup
|
||||
For streaming media:
|
||||
1. Core services (above)
|
||||
2. Jellyfin
|
||||
3. Sonarr
|
||||
4. Radarr
|
||||
5. qBittorrent
|
||||
6. Jellyseerr
|
||||
|
||||
### Complete Homelab
|
||||
Everything:
|
||||
1. Core services
|
||||
2. All media services
|
||||
3. All productivity services
|
||||
4. Backrest for backups
|
||||
|
||||
## Resource Requirements
|
||||
|
||||
### Light (2 Core, 4GB RAM)
|
||||
- Core services
|
||||
- Homarr
|
||||
- 2-3 utility services
|
||||
|
||||
### Medium (4 Core, 8GB RAM)
|
||||
- Core services
|
||||
- Media services (without transcoding)
|
||||
- Most utility services
|
||||
|
||||
### Heavy (6+ Core, 16GB+ RAM)
|
||||
- All services
|
||||
- GPU transcoding
|
||||
- Multiple concurrent users
|
||||
|
||||
## Quick Deploy Checklist
|
||||
|
||||
**Before deploying a service:**
|
||||
- ✅ Core infrastructure is running
|
||||
- ✅ `.env` file configured with secrets
|
||||
- ✅ DNS record created
|
||||
- ✅ Understand what the service does
|
||||
- ✅ Know how to configure it
|
||||
|
||||
**After deploying:**
|
||||
- ✅ Check container is running: `docker ps`
|
||||
- ✅ Check logs: `docker compose logs`
|
||||
- ✅ Access web UI and complete setup
|
||||
- ✅ Test SSO if applicable
|
||||
- ✅ Add to Homarr dashboard
|
||||
|
||||
## Service Dependencies
|
||||
|
||||
```
|
||||
Traefik (required for all)
|
||||
├── LLDAP
|
||||
│ └── Tinyauth
|
||||
│ └── All SSO-protected services
|
||||
├── Jellyfin
|
||||
│ └── Jellyseerr
|
||||
│ ├── Sonarr
|
||||
│ └── Radarr
|
||||
│ ├── SABnzbd
|
||||
│ └── qBittorrent
|
||||
├── Immich
|
||||
│ └── Backrest (for backups)
|
||||
└── All other services
|
||||
```
|
||||
|
||||
## When to Use Each Service
|
||||
|
||||
### Use Jellyfin if:
|
||||
- You have a movie/TV collection
|
||||
- Want to stream from anywhere
|
||||
- Have family/friends who want access
|
||||
- Want apps on all devices
|
||||
|
||||
### Use Immich if:
|
||||
- You want Google Photos alternative
|
||||
- Have lots of photos to manage
|
||||
- Want ML features (face recognition)
|
||||
- Have mobile devices
|
||||
|
||||
### Use Sonarr/Radarr if:
|
||||
- You watch a lot of TV/movies
|
||||
- Want automatic downloads
|
||||
- Don't want to manually search
|
||||
- Want quality control
|
||||
|
||||
### Use Backrest if:
|
||||
- You care about your data (you should!)
|
||||
- Want encrypted cloud backups
|
||||
- Have important photos/documents
|
||||
- Want easy restore process
|
||||
|
||||
### Use Linkwarden if:
|
||||
- You save lots of bookmarks
|
||||
- Want full-text search
|
||||
- Share links with team
|
||||
- Want offline archives
|
||||
|
||||
### Use Vikunja if:
|
||||
- You need task management
|
||||
- Work with teams
|
||||
- Want Kanban boards
|
||||
- Need CalDAV for calendar integration
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. Review which services you actually need
|
||||
2. Start with core + 2-3 services
|
||||
3. Deploy and configure each fully
|
||||
4. Add more services gradually
|
||||
5. Monitor resource usage
|
||||
|
||||
---
|
||||
|
||||
**Remember**: You don't need all services. Start small and add what you actually use!
|
||||
707
docs/troubleshooting/common-issues.md
Normal file
707
docs/troubleshooting/common-issues.md
Normal file
|
|
@ -0,0 +1,707 @@
|
|||
# Common Issues and Solutions
|
||||
|
||||
This guide covers the most common problems you might encounter and how to fix them.
|
||||
|
||||
## Table of Contents
|
||||
- [Service Won't Start](#service-wont-start)
|
||||
- [SSL/TLS Certificate Errors](#ssltls-certificate-errors)
|
||||
- [SSO Authentication Issues](#sso-authentication-issues)
|
||||
- [Access Issues](#access-issues)
|
||||
- [Performance Problems](#performance-problems)
|
||||
- [Database Errors](#database-errors)
|
||||
- [Network Issues](#network-issues)
|
||||
- [GPU Problems](#gpu-problems)
|
||||
|
||||
## Service Won't Start
|
||||
|
||||
### Symptom
|
||||
Container exits immediately or shows "Exited (1)" status.
|
||||
|
||||
### Diagnosis
|
||||
```bash
|
||||
cd ~/homelab/compose/path/to/service
|
||||
|
||||
# Check container status
|
||||
docker compose ps
|
||||
|
||||
# View logs
|
||||
docker compose logs
|
||||
|
||||
# Check for specific errors
|
||||
docker compose logs | grep -i error
|
||||
```
|
||||
|
||||
### Common Causes and Fixes
|
||||
|
||||
#### 1. Environment Variables Not Set
|
||||
|
||||
**Error in logs:**
|
||||
```
|
||||
Error: POSTGRES_PASSWORD is not set
|
||||
Error: required environment variable 'XXX' is missing
|
||||
```
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Check .env file exists
|
||||
ls -la .env
|
||||
|
||||
# Check for changeme_ values
|
||||
grep "changeme_" .env
|
||||
|
||||
# Update with proper secrets (see secrets guide)
|
||||
nano .env
|
||||
|
||||
# Restart
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
#### 2. Port Already in Use
|
||||
|
||||
**Error in logs:**
|
||||
```
|
||||
Error: bind: address already in use
|
||||
Error: failed to bind to port 80: address already in use
|
||||
```
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Find what's using the port
|
||||
sudo netstat -tulpn | grep :80
|
||||
sudo netstat -tulpn | grep :443
|
||||
|
||||
# Stop conflicting service
|
||||
sudo systemctl stop apache2 # Example
|
||||
sudo systemctl stop nginx # Example
|
||||
|
||||
# Or change port in compose.yaml
|
||||
```
|
||||
|
||||
#### 3. Network Not Created
|
||||
|
||||
**Error in logs:**
|
||||
```
|
||||
network homelab declared as external, but could not be found
|
||||
```
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Create network
|
||||
docker network create homelab
|
||||
|
||||
# Verify
|
||||
docker network ls | grep homelab
|
||||
|
||||
# Restart service
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
#### 4. Volume Permission Issues
|
||||
|
||||
**Error in logs:**
|
||||
```
|
||||
Permission denied: '/config'
|
||||
mkdir: cannot create directory '/data': Permission denied
|
||||
```
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Check directory ownership
|
||||
ls -la ./config ./data
|
||||
|
||||
# Fix ownership (replace 1000:1000 with your UID:GID)
|
||||
sudo chown -R 1000:1000 ./config ./data
|
||||
|
||||
# Restart
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
#### 5. Dependency Not Running
|
||||
|
||||
**Error in logs:**
|
||||
```
|
||||
Failed to connect to database
|
||||
Connection refused: postgres:5432
|
||||
```
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Start dependency first
|
||||
cd ~/homelab/compose/path/to/dependency
|
||||
docker compose up -d
|
||||
|
||||
# Wait for it to be healthy
|
||||
docker compose logs -f
|
||||
|
||||
# Then start the service
|
||||
cd ~/homelab/compose/path/to/service
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
## SSL/TLS Certificate Errors
|
||||
|
||||
### Symptom
|
||||
Browser shows "Your connection is not private" or "NET::ERR_CERT_AUTHORITY_INVALID"
|
||||
|
||||
### Diagnosis
|
||||
```bash
|
||||
# Check Traefik logs
|
||||
docker logs traefik | grep -i certificate
|
||||
docker logs traefik | grep -i letsencrypt
|
||||
docker logs traefik | grep -i error
|
||||
|
||||
# Test certificate
|
||||
echo | openssl s_client -servername home.fig.systems -connect home.fig.systems:443 2>/dev/null | openssl x509 -noout -dates
|
||||
```
|
||||
|
||||
### Common Causes and Fixes
|
||||
|
||||
#### 1. DNS Not Configured
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Test DNS resolution
|
||||
dig home.fig.systems +short
|
||||
|
||||
# Should return your server's IP
|
||||
# If not, configure DNS A records:
|
||||
# *.fig.systems -> YOUR_SERVER_IP
|
||||
```
|
||||
|
||||
#### 2. Port 80 Not Accessible
|
||||
|
||||
Let's Encrypt needs port 80 for HTTP-01 challenge.
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Test from external network
|
||||
curl -I http://home.fig.systems
|
||||
|
||||
# Check firewall
|
||||
sudo ufw status
|
||||
sudo ufw allow 80/tcp
|
||||
sudo ufw allow 443/tcp
|
||||
|
||||
# Check port forwarding on router
|
||||
# Ensure ports 80 and 443 are forwarded to server
|
||||
```
|
||||
|
||||
#### 3. Rate Limiting
|
||||
|
||||
Let's Encrypt has limits: 5 certificates per domain per week.
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Check Traefik logs for rate limit errors
|
||||
docker logs traefik | grep -i "rate limit"
|
||||
|
||||
# Wait for rate limit to reset (1 week)
|
||||
# Or use Let's Encrypt staging environment for testing
|
||||
|
||||
# Enable staging in traefik/compose.yaml:
|
||||
# - --certificatesresolvers.letsencrypt.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
|
||||
```
|
||||
|
||||
#### 4. First Startup - Certificates Not Yet Generated
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Wait 2-5 minutes for certificate generation
|
||||
docker logs traefik -f
|
||||
|
||||
# Look for:
|
||||
# "Certificate obtained for domain"
|
||||
```
|
||||
|
||||
#### 5. Certificate Expired
|
||||
|
||||
Traefik should auto-renew, but if manual renewal needed:
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Remove old certificates
|
||||
cd ~/homelab/compose/core/traefik
|
||||
rm -rf ./acme.json
|
||||
|
||||
# Restart Traefik
|
||||
docker compose restart
|
||||
|
||||
# Wait for new certificates
|
||||
docker logs traefik -f
|
||||
```
|
||||
|
||||
## SSO Authentication Issues
|
||||
|
||||
### Symptom
|
||||
- Can't login to SSO-protected services
|
||||
- Redirected to auth page but login fails
|
||||
- "Invalid credentials" error
|
||||
|
||||
### Diagnosis
|
||||
```bash
|
||||
# Check LLDAP is running
|
||||
docker ps | grep lldap
|
||||
|
||||
# Check Tinyauth is running
|
||||
docker ps | grep tinyauth
|
||||
|
||||
# View logs
|
||||
docker logs lldap
|
||||
docker logs tinyauth
|
||||
```
|
||||
|
||||
### Common Causes and Fixes
|
||||
|
||||
#### 1. Password Mismatch
|
||||
|
||||
LDAP_BIND_PASSWORD must match LLDAP_LDAP_USER_PASS.
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Check both passwords
|
||||
grep LLDAP_LDAP_USER_PASS ~/homelab/compose/core/lldap/.env
|
||||
grep LDAP_BIND_PASSWORD ~/homelab/compose/core/tinyauth/.env
|
||||
|
||||
# They must be EXACTLY the same!
|
||||
|
||||
# If different, update tinyauth/.env
|
||||
cd ~/homelab/compose/core/tinyauth
|
||||
nano .env
|
||||
# Set LDAP_BIND_PASSWORD to match LLDAP_LDAP_USER_PASS
|
||||
|
||||
# Restart Tinyauth
|
||||
docker compose restart
|
||||
```
|
||||
|
||||
#### 2. User Doesn't Exist in LLDAP
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Access LLDAP web UI
|
||||
# Go to: https://lldap.fig.systems
|
||||
|
||||
# Login with admin credentials
|
||||
# Username: admin
|
||||
# Password: <your LLDAP_LDAP_USER_PASS>
|
||||
|
||||
# Create user:
|
||||
# - Click "Create user"
|
||||
# - Set username, email, password
|
||||
# - Add to "lldap_admin" group
|
||||
|
||||
# Try logging in again
|
||||
```
|
||||
|
||||
#### 3. LLDAP or Tinyauth Not Running
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Start LLDAP
|
||||
cd ~/homelab/compose/core/lldap
|
||||
docker compose up -d
|
||||
|
||||
# Wait for it to be ready
|
||||
docker compose logs -f
|
||||
|
||||
# Start Tinyauth
|
||||
cd ~/homelab/compose/core/tinyauth
|
||||
docker compose up -d
|
||||
docker compose logs -f
|
||||
```
|
||||
|
||||
#### 4. Network Issue Between Tinyauth and LLDAP
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Test connection
|
||||
docker exec tinyauth nc -zv lldap 3890
|
||||
|
||||
# Should show: Connection to lldap 3890 port [tcp/*] succeeded!
|
||||
|
||||
# If not, check both are on homelab network
|
||||
docker network inspect homelab
|
||||
```
|
||||
|
||||
## Access Issues
|
||||
|
||||
### Symptom
|
||||
- Can't access service from browser
|
||||
- Connection timeout
|
||||
- "This site can't be reached"
|
||||
|
||||
### Diagnosis
|
||||
```bash
|
||||
# Test from server
|
||||
curl -I https://home.fig.systems
|
||||
|
||||
# Test DNS
|
||||
dig home.fig.systems +short
|
||||
|
||||
# Check container is running
|
||||
docker ps | grep servicename
|
||||
|
||||
# Check Traefik routing
|
||||
docker logs traefik | grep servicename
|
||||
```
|
||||
|
||||
### Common Causes and Fixes
|
||||
|
||||
#### 1. Service Not Running
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
cd ~/homelab/compose/path/to/service
|
||||
docker compose up -d
|
||||
docker compose logs -f
|
||||
```
|
||||
|
||||
#### 2. Traefik Not Running
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
cd ~/homelab/compose/core/traefik
|
||||
docker compose up -d
|
||||
docker compose logs -f
|
||||
```
|
||||
|
||||
#### 3. DNS Not Resolving
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Check DNS
|
||||
dig service.fig.systems +short
|
||||
|
||||
# Should return your server IP
|
||||
# If not, add/update DNS A record
|
||||
```
|
||||
|
||||
#### 4. Firewall Blocking
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Check firewall
|
||||
sudo ufw status
|
||||
|
||||
# Allow if needed
|
||||
sudo ufw allow 80/tcp
|
||||
sudo ufw allow 443/tcp
|
||||
```
|
||||
|
||||
#### 5. Wrong Traefik Labels
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Check compose.yaml has correct labels
|
||||
cd ~/homelab/compose/path/to/service
|
||||
cat compose.yaml | grep -A 10 "labels:"
|
||||
|
||||
# Should have:
|
||||
# traefik.enable: true
|
||||
# traefik.http.routers.servicename.rule: Host(`service.fig.systems`)
|
||||
# etc.
|
||||
```
|
||||
|
||||
## Performance Problems
|
||||
|
||||
### Symptom
|
||||
- Services running slowly
|
||||
- High CPU/RAM usage
|
||||
- System unresponsive
|
||||
|
||||
### Diagnosis
|
||||
```bash
|
||||
# Overall system
|
||||
htop
|
||||
|
||||
# Docker resources
|
||||
docker stats
|
||||
|
||||
# Disk usage
|
||||
df -h
|
||||
docker system df
|
||||
```
|
||||
|
||||
### Common Causes and Fixes
|
||||
|
||||
#### 1. Insufficient RAM
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Check RAM usage
|
||||
free -h
|
||||
|
||||
# If low, either:
|
||||
# 1. Add more RAM
|
||||
# 2. Stop unused services
|
||||
# 3. Add resource limits to compose files
|
||||
|
||||
# Example resource limit:
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 2G
|
||||
reservations:
|
||||
memory: 1G
|
||||
```
|
||||
|
||||
#### 2. Disk Full
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Check disk usage
|
||||
df -h
|
||||
|
||||
# Clean Docker
|
||||
docker system prune -a
|
||||
|
||||
# Remove old logs
|
||||
sudo journalctl --vacuum-time=7d
|
||||
|
||||
# Check media folder
|
||||
du -sh /media/*
|
||||
```
|
||||
|
||||
#### 3. Too Many Services Running
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Stop unused services
|
||||
cd ~/homelab/compose/services/unused-service
|
||||
docker compose down
|
||||
|
||||
# Or deploy only what you need
|
||||
```
|
||||
|
||||
#### 4. Database Not Optimized
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# For postgres services, add to .env:
|
||||
POSTGRES_INITDB_ARGS=--data-checksums
|
||||
|
||||
# Increase shared buffers (if enough RAM):
|
||||
# Edit compose.yaml, add to postgres:
|
||||
command: postgres -c shared_buffers=256MB -c max_connections=200
|
||||
```
|
||||
|
||||
## Database Errors
|
||||
|
||||
### Symptom
|
||||
- "Connection refused" to database
|
||||
- "Authentication failed for user"
|
||||
- "Database does not exist"
|
||||
|
||||
### Diagnosis
|
||||
```bash
|
||||
# Check database container
|
||||
docker ps | grep postgres
|
||||
|
||||
# View database logs
|
||||
docker logs <postgres_container_name>
|
||||
|
||||
# Test connection from app
|
||||
docker exec <app_container> nc -zv <db_container> 5432
|
||||
```
|
||||
|
||||
### Common Causes and Fixes
|
||||
|
||||
#### 1. Password Mismatch
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Check passwords match in .env
|
||||
cat .env | grep PASSWORD
|
||||
|
||||
# For example, in Vikunja:
|
||||
# VIKUNJA_DATABASE_PASSWORD and POSTGRES_PASSWORD must match!
|
||||
|
||||
# Update if needed
|
||||
nano .env
|
||||
docker compose down
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
#### 2. Database Not Initialized
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Remove database and reinitialize
|
||||
docker compose down
|
||||
rm -rf ./db/ # CAREFUL: This deletes all data!
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
#### 3. Database Still Starting
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Wait for database to be ready
|
||||
docker logs <postgres_container> -f
|
||||
|
||||
# Look for "database system is ready to accept connections"
|
||||
|
||||
# Then restart app
|
||||
docker compose restart <app_service>
|
||||
```
|
||||
|
||||
## Network Issues
|
||||
|
||||
### Symptom
|
||||
- Containers can't communicate
|
||||
- "Connection refused" between services
|
||||
|
||||
### Diagnosis
|
||||
```bash
|
||||
# Inspect network
|
||||
docker network inspect homelab
|
||||
|
||||
# Test connectivity
|
||||
docker exec container1 ping container2
|
||||
docker exec container1 nc -zv container2 PORT
|
||||
```
|
||||
|
||||
### Common Causes and Fixes
|
||||
|
||||
#### 1. Containers Not on Same Network
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Check compose.yaml has networks section
|
||||
networks:
|
||||
homelab:
|
||||
external: true
|
||||
|
||||
# Ensure service is using the network
|
||||
services:
|
||||
servicename:
|
||||
networks:
|
||||
- homelab
|
||||
```
|
||||
|
||||
#### 2. Network Doesn't Exist
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
docker network create homelab
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
#### 3. DNS Resolution Between Containers
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Use container name, not localhost
|
||||
# Wrong: http://localhost:5432
|
||||
# Right: http://postgres:5432
|
||||
|
||||
# Or use service name from compose.yaml
|
||||
```
|
||||
|
||||
## GPU Problems
|
||||
|
||||
### Symptom
|
||||
- "No hardware acceleration available"
|
||||
- GPU not detected in container
|
||||
- "Failed to open GPU"
|
||||
|
||||
### Diagnosis
|
||||
```bash
|
||||
# Check GPU on host
|
||||
nvidia-smi
|
||||
|
||||
# Check GPU in container
|
||||
docker exec jellyfin nvidia-smi
|
||||
|
||||
# Check Docker GPU runtime
|
||||
docker run --rm --gpus all nvidia/cuda:12.2.0-base-ubuntu22.04 nvidia-smi
|
||||
```
|
||||
|
||||
### Common Causes and Fixes
|
||||
|
||||
#### 1. NVIDIA Container Toolkit Not Installed
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Install toolkit
|
||||
sudo apt install nvidia-container-toolkit
|
||||
|
||||
# Configure runtime
|
||||
sudo nvidia-ctk runtime configure --runtime=docker
|
||||
|
||||
# Restart Docker
|
||||
sudo systemctl restart docker
|
||||
```
|
||||
|
||||
#### 2. Runtime Not Specified in Compose
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Edit compose.yaml
|
||||
nano compose.yaml
|
||||
|
||||
# Uncomment:
|
||||
runtime: nvidia
|
||||
deploy:
|
||||
resources:
|
||||
reservations:
|
||||
devices:
|
||||
- driver: nvidia
|
||||
count: all
|
||||
capabilities: [gpu]
|
||||
|
||||
# Restart
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
#### 3. GPU Already in Use
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Check processes using GPU
|
||||
nvidia-smi
|
||||
|
||||
# Kill process if needed
|
||||
sudo kill <PID>
|
||||
|
||||
# Restart service
|
||||
docker compose restart
|
||||
```
|
||||
|
||||
#### 4. GPU Not Passed Through to VM (Proxmox)
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# From Proxmox host, check GPU passthrough
|
||||
lspci | grep -i nvidia
|
||||
|
||||
# From VM, check GPU visible
|
||||
lspci | grep -i nvidia
|
||||
|
||||
# If not visible, reconfigure passthrough (see GPU guide)
|
||||
```
|
||||
|
||||
## Getting More Help
|
||||
|
||||
If your issue isn't listed here:
|
||||
|
||||
1. **Check service-specific logs**:
|
||||
```bash
|
||||
cd ~/homelab/compose/path/to/service
|
||||
docker compose logs --tail=200
|
||||
```
|
||||
|
||||
2. **Search container logs for errors**:
|
||||
```bash
|
||||
docker compose logs | grep -i error
|
||||
docker compose logs | grep -i fail
|
||||
```
|
||||
|
||||
3. **Check FAQ**: See [FAQ](./faq.md)
|
||||
|
||||
4. **Debugging Guide**: See [Debugging Guide](./debugging.md)
|
||||
|
||||
5. **Service Documentation**: Check service's official documentation
|
||||
|
||||
---
|
||||
|
||||
**Most issues can be solved by checking logs and environment variables!**
|
||||
484
docs/troubleshooting/faq.md
Normal file
484
docs/troubleshooting/faq.md
Normal file
|
|
@ -0,0 +1,484 @@
|
|||
# Frequently Asked Questions (FAQ)
|
||||
|
||||
Common questions and answers about the homelab setup.
|
||||
|
||||
## General Questions
|
||||
|
||||
### Q: What is this homelab setup?
|
||||
|
||||
**A:** This is a GitOps-based infrastructure for self-hosting services using Docker Compose. It includes:
|
||||
- 20+ pre-configured services (media, productivity, utilities)
|
||||
- Automatic SSL/TLS with Let's Encrypt via Traefik
|
||||
- Single Sign-On (SSO) with LLDAP and Tinyauth
|
||||
- Automated backups with Backrest
|
||||
- Service discovery dashboard with Homarr
|
||||
|
||||
### Q: What are the minimum hardware requirements?
|
||||
|
||||
**A:**
|
||||
- **CPU**: 2+ cores (4+ recommended)
|
||||
- **RAM**: 8GB minimum (16GB+ recommended)
|
||||
- **Storage**: 100GB for containers, additional space for media
|
||||
- **Network**: Static IP recommended, ports 80 and 443 accessible
|
||||
- **GPU** (Optional): NVIDIA GPU for hardware transcoding
|
||||
|
||||
### Q: Do I need my own domain name?
|
||||
|
||||
**A:** Yes, you need at least one domain (two configured by default: `fig.systems` and `edfig.dev`). You can:
|
||||
- Register a domain from any registrar
|
||||
- Update all compose files to use your domain
|
||||
- Configure wildcard DNS (`*.yourdomain.com`)
|
||||
|
||||
### Q: Can I run this on a Raspberry Pi?
|
||||
|
||||
**A:** Partially. ARM64 architecture is supported by most services, but:
|
||||
- Performance will be limited
|
||||
- No GPU acceleration available
|
||||
- Some services may not have ARM images
|
||||
- 8GB RAM minimum recommended (Pi 4 or Pi 5)
|
||||
|
||||
### Q: How much does this cost to run?
|
||||
|
||||
**A:**
|
||||
- **Server**: $0 (if using existing hardware) or $5-20/month (VPS)
|
||||
- **Domain**: $10-15/year
|
||||
- **Backblaze B2**: ~$0.60/month for 100GB photos
|
||||
- **Electricity**: Varies by hardware and location
|
||||
- **Total**: $15-30/year minimum
|
||||
|
||||
## Setup Questions
|
||||
|
||||
### Q: Why won't my services start?
|
||||
|
||||
**A:** Common causes:
|
||||
1. **Environment variables not set**: Check for `changeme_*` in `.env` files
|
||||
2. **Ports already in use**: Check if 80/443 are available
|
||||
3. **Network not created**: Run `docker network create homelab`
|
||||
4. **DNS not configured**: Services need valid DNS records
|
||||
5. **Insufficient resources**: Check RAM and disk space
|
||||
|
||||
**Debug:**
|
||||
```bash
|
||||
cd compose/path/to/service
|
||||
docker compose logs
|
||||
docker compose ps
|
||||
```
|
||||
|
||||
### Q: How do I know if everything is working?
|
||||
|
||||
**A:** Check these indicators:
|
||||
1. **All containers running**: `docker ps` shows all services
|
||||
2. **SSL certificates valid**: Visit https://home.fig.systems (no cert errors)
|
||||
3. **Dashboard accessible**: Homarr shows all services
|
||||
4. **SSO working**: Can login to protected services
|
||||
5. **No errors in logs**: `docker compose logs` shows no critical errors
|
||||
|
||||
### Q: What order should I deploy services?
|
||||
|
||||
**A:** Follow this order:
|
||||
1. **Core**: Traefik → LLDAP → Tinyauth
|
||||
2. **Configure**: Create LLDAP users
|
||||
3. **Media**: Jellyfin → Immich → Jellyseerr → Sonarr → Radarr → Downloaders
|
||||
4. **Utility**: Homarr → Backrest → Everything else
|
||||
|
||||
### Q: Do I need to configure all 20 services?
|
||||
|
||||
**A:** No! Deploy only what you need:
|
||||
- **Core** (required): Traefik, LLDAP, Tinyauth
|
||||
- **Media** (optional): Jellyfin, Immich, Sonarr, Radarr
|
||||
- **Utility** (pick what you want): Homarr, Backrest, Linkwarden, Vikunja, etc.
|
||||
|
||||
## Configuration Questions
|
||||
|
||||
### Q: What secrets do I need to change?
|
||||
|
||||
**A:** Search for `changeme_*` in all `.env` files:
|
||||
```bash
|
||||
grep -r "changeme_" compose/
|
||||
```
|
||||
|
||||
Critical secrets:
|
||||
- **LLDAP_LDAP_USER_PASS**: Admin password for LLDAP
|
||||
- **LLDAP_JWT_SECRET**: 64-character hex string
|
||||
- **SESSION_SECRET**: 64-character hex string for Tinyauth
|
||||
- **DB_PASSWORD**: Database passwords (Immich, Vikunja, Linkwarden)
|
||||
- **NEXTAUTH_SECRET**: NextAuth secret for Linkwarden
|
||||
- **VIKUNJA_SERVICE_JWTSECRET**: JWT secret for Vikunja
|
||||
|
||||
### Q: How do I generate secure secrets?
|
||||
|
||||
**A:** Use these commands:
|
||||
|
||||
```bash
|
||||
# 64-character hex (for JWT secrets, session secrets)
|
||||
openssl rand -hex 32
|
||||
|
||||
# 32-character password (for databases)
|
||||
openssl rand -base64 32 | tr -d /=+ | cut -c1-32
|
||||
|
||||
# 32-character hex (for API keys)
|
||||
openssl rand -hex 16
|
||||
```
|
||||
|
||||
See [Secrets Management Guide](../guides/secrets-management.md) for details.
|
||||
|
||||
### Q: Can I change the domains from fig.systems to my own?
|
||||
|
||||
**A:** Yes! You need to:
|
||||
1. Find and replace in all `compose.yaml` files:
|
||||
```bash
|
||||
find compose -name "compose.yaml" -exec sed -i 's/fig\.systems/yourdomain.com/g' {} \;
|
||||
find compose -name "compose.yaml" -exec sed -i 's/edfig\.dev/yourotherdomain.com/g' {} \;
|
||||
```
|
||||
2. Update DNS records to point to your server
|
||||
3. Update `.env` files with new URLs (e.g., `NEXTAUTH_URL`, `VIKUNJA_SERVICE_PUBLICURL`)
|
||||
|
||||
### Q: Do all passwords need to match?
|
||||
|
||||
**A:** No, but some must match:
|
||||
- **LLDAP_LDAP_USER_PASS** must equal **LDAP_BIND_PASSWORD** (in tinyauth)
|
||||
- **VIKUNJA_DATABASE_PASSWORD** must equal **POSTGRES_PASSWORD** (in vikunja)
|
||||
- **Linkwarden POSTGRES_PASSWORD** is used in DATABASE_URL
|
||||
|
||||
All other passwords should be unique!
|
||||
|
||||
## SSL/TLS Questions
|
||||
|
||||
### Q: Why am I getting SSL certificate errors?
|
||||
|
||||
**A:** Common causes:
|
||||
1. **DNS not configured**: Ensure domains point to your server
|
||||
2. **Ports not accessible**: Let's Encrypt needs port 80 for HTTP challenge
|
||||
3. **Rate limiting**: Let's Encrypt has rate limits (5 certs per domain/week)
|
||||
4. **First startup**: Certs take a few minutes to generate
|
||||
|
||||
**Debug:**
|
||||
```bash
|
||||
docker logs traefik | grep -i error
|
||||
docker logs traefik | grep -i certificate
|
||||
```
|
||||
|
||||
### Q: How long do SSL certificates last?
|
||||
|
||||
**A:** Let's Encrypt certificates:
|
||||
- Valid for 90 days
|
||||
- Traefik auto-renews at 30 days before expiration
|
||||
- Renewals happen automatically in the background
|
||||
|
||||
### Q: Can I use my own SSL certificates?
|
||||
|
||||
**A:** Yes, but it requires modifying Traefik configuration. The default Let's Encrypt setup is recommended.
|
||||
|
||||
## SSO Questions
|
||||
|
||||
### Q: What is SSO and do I need it?
|
||||
|
||||
**A:** SSO (Single Sign-On) lets you log in once and access all services:
|
||||
- **LLDAP**: Stores users and passwords
|
||||
- **Tinyauth**: Authenticates users before allowing service access
|
||||
- **Benefits**: One login for all services, centralized user management
|
||||
- **Optional**: Some services can work without SSO (have their own auth)
|
||||
|
||||
### Q: Why can't I log into SSO-protected services?
|
||||
|
||||
**A:** Check:
|
||||
1. **LLDAP is running**: `docker ps | grep lldap`
|
||||
2. **Tinyauth is running**: `docker ps | grep tinyauth`
|
||||
3. **User exists in LLDAP**: Go to https://lldap.fig.systems and verify
|
||||
4. **Passwords match**: LDAP_BIND_PASSWORD = LLDAP_LDAP_USER_PASS
|
||||
5. **User in correct group**: Check user is in `lldap_admin` group
|
||||
|
||||
**Debug:**
|
||||
```bash
|
||||
cd compose/core/tinyauth
|
||||
docker compose logs -f
|
||||
```
|
||||
|
||||
### Q: Can I disable SSO for a service?
|
||||
|
||||
**A:** Yes! Comment out the middleware line in compose.yaml:
|
||||
```yaml
|
||||
# traefik.http.routers.servicename.middlewares: tinyauth
|
||||
```
|
||||
|
||||
Then restart the service:
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
### Q: How do I reset my LLDAP admin password?
|
||||
|
||||
**A:**
|
||||
1. Stop LLDAP: `cd compose/core/lldap && docker compose down`
|
||||
2. Update `LLDAP_LDAP_USER_PASS` in `.env`
|
||||
3. Remove the database: `rm -rf data/`
|
||||
4. Restart: `docker compose up -d`
|
||||
5. Recreate users in LLDAP UI
|
||||
|
||||
⚠️ **Warning**: This deletes all users!
|
||||
|
||||
## Service-Specific Questions
|
||||
|
||||
### Q: Jellyfin shows "Playback Error" - what's wrong?
|
||||
|
||||
**A:** Common causes:
|
||||
1. **Media file corrupt**: Test file with VLC
|
||||
2. **Permissions**: Check file ownership (`ls -la /media/movies`)
|
||||
3. **Codec not supported**: Enable transcoding or use different file
|
||||
4. **GPU not configured**: If using GPU, verify NVIDIA Container Toolkit
|
||||
|
||||
### Q: Immich won't upload photos - why?
|
||||
|
||||
**A:** Check:
|
||||
1. **Database connected**: `docker logs immich_postgres`
|
||||
2. **Upload directory writable**: Check permissions on `./upload`
|
||||
3. **Disk space**: `df -h`
|
||||
4. **File size limits**: Check browser console for errors
|
||||
|
||||
### Q: Why isn't Homarr showing my services?
|
||||
|
||||
**A:** Homarr needs:
|
||||
1. **Docker socket access**: Volume mount `/var/run/docker.sock`
|
||||
2. **Labels on services**: Each service needs `homarr.name` label
|
||||
3. **Same network**: Homarr must be on `homelab` network
|
||||
4. **Time to detect**: Refresh page or wait 30 seconds
|
||||
|
||||
### Q: Backrest shows "Repository not initialized" - what do I do?
|
||||
|
||||
**A:**
|
||||
1. Go to https://backup.fig.systems
|
||||
2. Click "Add Repository"
|
||||
3. Configure Backblaze B2 settings
|
||||
4. Click "Initialize Repository"
|
||||
|
||||
See [Backup Guide](../services/backup.md) for detailed setup.
|
||||
|
||||
### Q: Sonarr/Radarr can't find anything - help!
|
||||
|
||||
**A:**
|
||||
1. **Add indexers**: Settings → Indexers → Add indexer
|
||||
2. **Configure download client**: Settings → Download Clients → Add
|
||||
3. **Set root folder**: Series/Movies → Add Root Folder → `/media/tv` or `/media/movies`
|
||||
4. **Test indexers**: Settings → Indexers → Test
|
||||
|
||||
### Q: qBittorrent shows "Unauthorized" - what's the password?
|
||||
|
||||
**A:** Default credentials:
|
||||
- Username: `admin`
|
||||
- Password: `adminadmin`
|
||||
|
||||
⚠️ **Change this immediately** in qBittorrent settings!
|
||||
|
||||
## Media Questions
|
||||
|
||||
### Q: Where should I put my media files?
|
||||
|
||||
**A:** Use the /media directory structure:
|
||||
- Movies: `/media/movies/Movie Name (Year)/movie.mkv`
|
||||
- TV: `/media/tv/Show Name/Season 01/episode.mkv`
|
||||
- Music: `/media/music/Artist/Album/song.flac`
|
||||
- Photos: `/media/photos/` (any structure)
|
||||
- Books: `/media/books/` (any structure)
|
||||
|
||||
### Q: How do I add more media storage?
|
||||
|
||||
**A:**
|
||||
1. Mount additional drive to `/media2` (or any path)
|
||||
2. Update compose files to include new volume:
|
||||
```yaml
|
||||
volumes:
|
||||
- /media:/media:ro
|
||||
- /media2:/media2:ro # Add this
|
||||
```
|
||||
3. Restart service: `docker compose up -d`
|
||||
4. Add new library in service UI
|
||||
|
||||
### Q: Can Sonarr/Radarr automatically download shows/movies?
|
||||
|
||||
**A:** Yes! That's their purpose:
|
||||
1. Add indexers (for searching)
|
||||
2. Add download client (SABnzbd or qBittorrent)
|
||||
3. Add a series/movie
|
||||
4. Enable monitoring
|
||||
5. Sonarr/Radarr will search, download, and organize automatically
|
||||
|
||||
### Q: How do I enable hardware transcoding in Jellyfin?
|
||||
|
||||
**A:** See [GPU Setup Guide](../guides/gpu-setup.md) for full instructions.
|
||||
|
||||
Quick steps:
|
||||
1. Install NVIDIA Container Toolkit on host
|
||||
2. Uncomment GPU sections in `jellyfin/compose.yaml`
|
||||
3. Restart Jellyfin
|
||||
4. Enable in Jellyfin: Dashboard → Playback → Hardware Acceleration → NVIDIA NVENC
|
||||
|
||||
## Network Questions
|
||||
|
||||
### Q: Can I access services only from my local network?
|
||||
|
||||
**A:** Yes, don't expose ports 80/443 to internet:
|
||||
1. Use firewall to block external access
|
||||
2. Use local DNS (Pi-hole, AdGuard Home)
|
||||
3. Point domains to local IP (192.168.x.x)
|
||||
4. Use self-signed certs or no HTTPS
|
||||
|
||||
**Or** use Traefik's IP allowlist middleware.
|
||||
|
||||
### Q: Can I use a VPN with these services?
|
||||
|
||||
**A:** Yes, options:
|
||||
1. **VPN on download clients**: Add VPN container for qBittorrent/SABnzbd
|
||||
2. **VPN to access homelab**: Use WireGuard/Tailscale to access from anywhere
|
||||
3. **VPN for entire server**: All traffic goes through VPN (not recommended)
|
||||
|
||||
### Q: Why can't I access services from outside my network?
|
||||
|
||||
**A:** Check:
|
||||
1. **Port forwarding**: Ports 80 and 443 forwarded to homelab server
|
||||
2. **Firewall**: Allow ports 80/443 through firewall
|
||||
3. **DNS**: Domains point to your public IP
|
||||
4. **ISP**: Some ISPs block ports 80/443 (use CloudFlare Tunnel)
|
||||
|
||||
## Backup Questions
|
||||
|
||||
### Q: What should I backup?
|
||||
|
||||
**A:** Priority order:
|
||||
1. **High**: Immich photos (`compose/media/frontend/immich/upload`)
|
||||
2. **High**: Configuration files (all `.env` files, compose files)
|
||||
3. **Medium**: Service data directories (`./config`, `./data` in each service)
|
||||
4. **Low**: Media files (usually have source elsewhere)
|
||||
|
||||
### Q: How do I restore from backup?
|
||||
|
||||
**A:** See [Backup Operations Guide](../operations/backups.md).
|
||||
|
||||
Quick steps:
|
||||
1. Install fresh homelab setup
|
||||
2. Restore `.env` files and configs
|
||||
3. Use Backrest to restore data
|
||||
4. Restart services
|
||||
|
||||
### Q: Does Backrest backup everything automatically?
|
||||
|
||||
**A:** Only what you configure:
|
||||
- Default: Immich photos and homelab configs
|
||||
- Add more paths in `backrest/compose.yaml` volumes
|
||||
- Create backup plans in Backrest UI for each path
|
||||
|
||||
## Performance Questions
|
||||
|
||||
### Q: Services are running slow - how do I optimize?
|
||||
|
||||
**A:**
|
||||
1. **Check resources**: `docker stats` - are you out of RAM/CPU?
|
||||
2. **Reduce services**: Stop unused services
|
||||
3. **Use SSD**: Move Docker to SSD storage
|
||||
4. **Add RAM**: Minimum 8GB, 16GB+ recommended
|
||||
5. **Enable GPU**: For Jellyfin and Immich
|
||||
|
||||
### Q: Docker is using too much disk space - what do I do?
|
||||
|
||||
**A:**
|
||||
```bash
|
||||
# Check Docker disk usage
|
||||
docker system df
|
||||
|
||||
# Clean up
|
||||
docker system prune -a --volumes
|
||||
|
||||
# WARNING: This removes all stopped containers and unused volumes!
|
||||
```
|
||||
|
||||
Better approach - clean specific services:
|
||||
```bash
|
||||
cd compose/path/to/service
|
||||
docker compose down
|
||||
docker volume rm $(docker volume ls -q | grep servicename)
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
### Q: How do I limit RAM/CPU for a service?
|
||||
|
||||
**A:** Add resource limits to compose.yaml:
|
||||
```yaml
|
||||
services:
|
||||
servicename:
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '2.0'
|
||||
memory: 4G
|
||||
reservations:
|
||||
memory: 2G
|
||||
```
|
||||
|
||||
## Update Questions
|
||||
|
||||
### Q: How do I update a service?
|
||||
|
||||
**A:**
|
||||
```bash
|
||||
cd compose/path/to/service
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
See [Updates Guide](../operations/updates.md) for details.
|
||||
|
||||
### Q: How often should I update?
|
||||
|
||||
**A:**
|
||||
- **Security updates**: Weekly
|
||||
- **Feature updates**: Monthly
|
||||
- **Major versions**: When stable
|
||||
|
||||
Use Watchtower for automatic updates (optional).
|
||||
|
||||
### Q: Will updating break my configuration?
|
||||
|
||||
**A:** Usually no, but:
|
||||
- Always backup before major updates
|
||||
- Check release notes for breaking changes
|
||||
- Test in staging environment if critical
|
||||
|
||||
## Security Questions
|
||||
|
||||
### Q: Is this setup secure?
|
||||
|
||||
**A:** Reasonably secure with best practices:
|
||||
- ✅ SSL/TLS encryption
|
||||
- ✅ SSO authentication
|
||||
- ✅ Secrets in environment files
|
||||
- ⚠️ Some services exposed to internet
|
||||
- ⚠️ Depends on keeping services updated
|
||||
|
||||
See [Security Guide](../guides/security.md) for hardening.
|
||||
|
||||
### Q: Should I expose my homelab to the internet?
|
||||
|
||||
**A:** Depends on your risk tolerance:
|
||||
- **Yes**: Convenient access from anywhere, Let's Encrypt works
|
||||
- **No**: More secure, requires VPN for external access
|
||||
- **Hybrid**: Expose only essential services, use VPN for sensitive ones
|
||||
|
||||
### Q: What if someone gets my LLDAP password?
|
||||
|
||||
**A:** They can access all SSO-protected services. Mitigations:
|
||||
- Use strong, unique passwords
|
||||
- Enable 2FA where supported
|
||||
- Review LLDAP access logs
|
||||
- Use fail2ban to block brute force
|
||||
- Consider VPN-only access
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
For specific error messages and debugging, see:
|
||||
- [Common Issues](./common-issues.md)
|
||||
- [Debugging Guide](./debugging.md)
|
||||
|
||||
Still stuck? Check:
|
||||
1. Service logs: `docker compose logs`
|
||||
2. Traefik logs: `docker logs traefik`
|
||||
3. Container status: `docker ps -a`
|
||||
4. Network connectivity: `docker network inspect homelab`
|
||||
Loading…
Reference in a new issue