Document Agap infrastructure and services

- Add CLAUDE.md with Gitea integration, development guidelines, and wiki interaction instructions
- Add comprehensive README.md with service overview, quick start, and configuration details
- Add service directories: gitea/, openai/, immich-app/, and setup scripts (install-cuda.sh, nvidia-docker-install.sh)
- Update docker-compose.yml structure and immich configuration
- Include restore example script for Immich database backups

This repository now serves as the source of truth for Docker Compose configurations and deployment automation for Agap home server services (Immich, Gitea, Open WebUI).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Alvis
2026-02-21 10:24:33 +00:00
parent 348b3009d9
commit 2c72caf614
12 changed files with 413 additions and 6 deletions

6
.env
View File

@@ -5,10 +5,12 @@
# You can find documentation for all the supported env variables at https://docs.immich.app/install/environment-variables # You can find documentation for all the supported env variables at https://docs.immich.app/install/environment-variables
# The location where your uploaded files are stored # The location where your uploaded files are stored
UPLOAD_LOCATION=/mnt/data/media/upload UPLOAD_LOCATION=/mnt/media/upload
THUMB_LOCATION=/mnt/ssd1/media/thumbs
ENCODED_VIDEO_LOCATION=/mnt/ssd1/media/encoded-video
# The location where your database files are stored. Network shares are not supported for the database # The location where your database files are stored. Network shares are not supported for the database
DB_DATA_LOCATION=/mnt/data/media/postgres DB_DATA_LOCATION=/mnt/ssd1/media/postgres
# To set a timezone, uncomment the next line and change Etc/UTC to a TZ identifier from this list: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List # To set a timezone, uncomment the next line and change Etc/UTC to a TZ identifier from this list: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List
# TZ=Etc/UTC # TZ=Etc/UTC

127
CLAUDE.md Normal file
View File

@@ -0,0 +1,127 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Overview
This repository manages Docker Compose configurations for the **Agap** self-hosted home server. It is not a software project — it is infrastructure-as-config for several independent services.
## Services
| Directory | Service | Port | Notes |
|-----------|---------|------|-------|
| `immich-app/` | Immich (photo management) | 2283 | Main compose via root `docker-compose.yml` |
| `gitea/` | Gitea (git hosting) + Postgres | 3000, 222 | Standalone compose |
| `openai/` | Open WebUI + Ollama (AI chat) | 3125 | Requires NVIDIA GPU |
## Common Commands
All services use Docker Compose. From each service directory:
```bash
# Start a service
docker compose up -d
# Restart
docker compose restart
# View logs
docker compose logs -f
# Pull latest images
docker compose pull
```
The root `docker-compose.yml` is an alias that includes `immich-app/docker-compose.yml`.
### Immich-specific
Environment variables are in the root `.env` file (referenced by `immich-app/docker-compose.yml` as `../.env`):
- `UPLOAD_LOCATION`, `THUMB_LOCATION`, `ENCODED_VIDEO_LOCATION` — media storage paths
- `DB_DATA_LOCATION` — Postgres data directory
**Restore from backup** (see `immich-app/restore_example.sh`):
```bash
docker compose down -v # destroys all data
docker compose create
docker start immich_postgres
sleep 10
gunzip --stdout "/home/alvis/dump.sql.gz" | \
sed "s/SELECT pg_catalog.set_config('search_path', '', false);/SELECT pg_catalog.set_config('search_path', 'public, pg_catalog', true);/g" | \
docker exec -i immich_postgres psql --dbname=postgres --username=postgres
docker compose up -d
```
## GPU / NVIDIA Setup
Before running GPU-dependent services (Open WebUI/Ollama, Immich ML with CUDA):
1. Run `sudo ./nvidia-docker-install.sh` — installs Docker + NVIDIA Container Toolkit
2. Run `./install-cuda.sh` — installs CUDA toolkit (toolkit only, not driver)
## Storage Layout
| Path | Purpose |
|------|---------|
| `/mnt/media/upload` | Immich uploaded originals |
| `/mnt/ssd1/media/thumbs` | Immich thumbnails |
| `/mnt/ssd1/media/encoded-video` | Immich transcoded video |
| `/mnt/ssd1/media/postgres` | Immich Postgres data |
| `/mnt/misc/gitea` | Gitea data |
## Gitea Integration
When changes are made to infrastructure (services, config, setup), update the relevant Gitea wiki pages at `http://localhost:3000/alvis/AgapHost/wiki`.
### Gitea Instance Details
- **URL**: `http://localhost:3000`
- **Repo**: `alvis/AgapHost`
- **Wiki**: `http://localhost:3000/alvis/AgapHost/wiki`
- **API token**: Read from `$GITEA_TOKEN` environment variable — never hardcode it
### Wiki Pages Reference
| Page | Topic |
|------|-------|
| Hello | Overview of Agap — services, stack |
| Home | Index — links to all pages |
| Network | Netplan bridge setup, Caddy reverse proxy |
| Storage | LVM setup and commands |
| Home-Assistant | KVM-based Home Assistant setup |
| 3X-UI | VPN proxy panel |
| Gitea | Git hosting Docker service |
### Read Wiki Pages (API)
```bash
# List all pages
curl -s -H "Authorization: token $GITEA_TOKEN" \
http://localhost:3000/api/v1/repos/alvis/AgapHost/wiki/pages
# Read a page (content is base64 in content_base64 field)
curl -s -H "Authorization: token $GITEA_TOKEN" \
http://localhost:3000/api/v1/repos/alvis/AgapHost/wiki/page/Home
```
### Edit Wiki Pages (Git)
The Gitea REST API does not expose wiki write endpoints. Use git directly:
```bash
# Clone the wiki repo
git clone http://alvis:$GITEA_TOKEN@localhost:3000/alvis/AgapHost.wiki.git /tmp/AgapHost.wiki
# Edit files, then commit and push
cd /tmp/AgapHost.wiki
git config user.email "allogn@gmail.com"
git config user.name "alvis"
git add <files>
git commit -m "<message>"
git push http://alvis:$GITEA_TOKEN@localhost:3000/alvis/AgapHost.wiki.git main
```
### Wiki Style Guidelines
- Use minimalistic style: clean headings, code blocks, brief descriptions
- Remove outdated or redundant content when updating
- Create a new page if a topic doesn't exist yet
- Wiki files are Markdown, named `<PageTitle>.md`

View File

@@ -0,0 +1,60 @@
# Agap Home Server
Docker Compose configurations for the Agap self-hosted home server infrastructure.
## Services
- **Immich** (`immich-app/`) — Photo management and backup (port 2283)
- **Gitea** (`gitea/`) — Self-hosted Git server with web UI (port 3000, SSH 222)
- **Open WebUI** (`openai/`) — AI chat interface with Ollama, GPU-accelerated (port 3125)
## Quick Start
### Start Immich (main service)
```bash
docker compose up -d
```
### Start Gitea (from gitea/ directory)
```bash
cd gitea
docker compose up -d
```
### Start Open WebUI (from openai/ directory)
```bash
cd openai
docker compose up -d
```
## Configuration
Environment variables are in the root `.env` file for Immich:
- `UPLOAD_LOCATION` — where photo originals are stored
- `THUMB_LOCATION` — thumbnail cache directory
- `ENCODED_VIDEO_LOCATION` — transcoded video cache
- `DB_DATA_LOCATION` — Postgres database directory
- `DB_PASSWORD` — Postgres password
## Storage
Media is stored on:
- `/mnt/media/upload` — Immich originals
- `/mnt/ssd1/media/` — Immich thumbnails, encoded video, and Postgres database
- `/mnt/misc/gitea` — Gitea repositories and data
## GPU Support
For GPU acceleration (Open WebUI/Ollama, Immich ML):
1. Install NVIDIA Docker runtime: `sudo ./nvidia-docker-install.sh`
2. Install CUDA toolkit: `./install-cuda.sh`
## Documentation
See [CLAUDE.md](./CLAUDE.md) for detailed developer instructions and Gitea wiki integration guidelines.
See the [Gitea wiki](http://localhost:3000/alvis/AgapHost/wiki) for infrastructure documentation (storage, network, services setup).

View File

@@ -1,2 +0,0 @@
include:
- path: ./immich-app/docker-compose.yaml

3
docker-compose.yml Normal file
View File

@@ -0,0 +1,3 @@
include:
- path: ./immich-app/docker-compose.yml

43
gitea/docker-compose.yml Normal file
View File

@@ -0,0 +1,43 @@
version: "3"
networks:
gitea:
external: false
services:
server:
image: docker.gitea.com/gitea:1.25.3
container_name: gitea
environment:
- USER_UID=1001
- USER_GID=1001
- GITEA__database__DB_TYPE=postgres
- GITEA__database__HOST=db:5432
- GITEA__database__NAME=gitea
- GITEA__database__USER=gitea
- GITEA__database__PASSWD=gitea
restart: always
networks:
- gitea
volumes:
- /home/git/.ssh/:/data/git/.ssh
- /mnt/misc/gitea:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "3000:3000"
- "222:22"
depends_on:
- db
db:
image: docker.io/library/postgres:14
restart: always
environment:
- POSTGRES_USER=gitea
- POSTGRES_PASSWORD=gitea
- POSTGRES_DB=gitea
networks:
- gitea
volumes:
- ./postgres:/var/lib/postgresql/data

View File

@@ -19,9 +19,11 @@ services:
volumes: volumes:
# Do not edit the next line. If you want to change the media storage location on your system, edit the value of UPLOAD_LOCATION in the .env file # Do not edit the next line. If you want to change the media storage location on your system, edit the value of UPLOAD_LOCATION in the .env file
- ${UPLOAD_LOCATION}:/data - ${UPLOAD_LOCATION}:/data
- ${THUMB_LOCATION}:/data/thumbs
- ${ENCODED_VIDEO_LOCATION}:/data/encoded-video
- /etc/localtime:/etc/localtime:ro - /etc/localtime:/etc/localtime:ro
env_file: env_file:
- .env - ../.env
ports: ports:
- '2283:2283' - '2283:2283'
depends_on: depends_on:
@@ -42,7 +44,7 @@ services:
volumes: volumes:
- model-cache:/cache - model-cache:/cache
env_file: env_file:
- .env - ../.env
restart: always restart: always
healthcheck: healthcheck:
disable: false disable: false

Binary file not shown.

15
immich-app/restore_example.sh Executable file
View File

@@ -0,0 +1,15 @@
#!/bin/bash
docker compose down -v # CAUTION! Deletes all Immich data to start from scratch
## Uncomment the next line and replace DB_DATA_LOCATION with your Postgres path to permanently reset the Postgres database
# rm -rf DB_DATA_LOCATION # CAUTION! Deletes all Immich data to start from scratch
docker compose pull # Update to latest version of Immich (if desired)
docker compose create # Create Docker containers for Immich apps without running them
docker start immich_postgres # Start Postgres server
sleep 10 # Wait for Postgres server to start up
# Check the database user if you deviated from the default
# Replace <DB_USERNAME> with the database username - usually postgres unless you have changed it.
gunzip --stdout "/home/alvis/dump.sql.gz" \
| sed "s/SELECT pg_catalog.set_config('search_path', '', false);/SELECT pg_catalog.set_config('search_path', 'public, pg_catalog', true);/g" \
| docker exec -i immich_postgres psql --dbname=postgres --username=postgres # Restore Backup
docker compose up -d # Start remainder of Immich apps

35
install-cuda.sh Executable file
View File

@@ -0,0 +1,35 @@
#!/bin/bash
set -e
# Remove old CUDA GPG key if present
sudo apt-key del 7fa2af80 2>/dev/null || true
# Install prerequisites
sudo apt-get update
sudo apt-get install -y gcc g++ make dkms
# Add NVIDIA CUDA repository (Ubuntu 22.04/24.04)
DISTRO=$(lsb_release -rs | tr -d '.') # e.g., 2204 or 2404
ARCH=$(uname -m) # x86_64 or aarch64
# Download and install the CUDA keyring package
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu${DISTRO}/${ARCH}/cuda-keyring_1.1-1_all.deb
sudo dpkg -i cuda-keyring_1.1-1_all.deb
rm cuda-keyring_1.1-1_all.deb
# Update and install the latest CUDA toolkit
sudo apt-get update
sudo apt-get install -y cuda-toolkit # toolkit only (no driver)
# OR install everything including the driver:
# sudo apt-get install -y cuda
# Add CUDA to PATH and LD_LIBRARY_PATH
CUDA_PATH="/usr/local/cuda"
echo "" >> ~/.bashrc
echo "# CUDA" >> ~/.bashrc
echo "export PATH=${CUDA_PATH}/bin:\$PATH" >> ~/.bashrc
echo "export LD_LIBRARY_PATH=${CUDA_PATH}/lib64:\$LD_LIBRARY_PATH" >> ~/.bashrc
source ~/.bashrc
echo "CUDA installed successfully!"
nvcc --version

99
nvidia-docker-install.sh Executable file
View File

@@ -0,0 +1,99 @@
#!/bin/bash
set -euo pipefail
# =============================================================================
# NVIDIA Container Toolkit + Docker Installation Script
# Enables GPU-accelerated Docker containers
# Tested on Ubuntu 20.04/22.04/24.04, Debian 11/12
# =============================================================================
RED=$'\033[0;31m'
GREEN=$'\033[0;32m'
YELLOW=$'\033[1;33m'
NC=$'\033[0m'
log() { echo -e "${GREEN}[INFO]${NC} $*"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
error() { echo -e "${RED}[ERROR]${NC} $*"; exit 1; }
# --- Pre-flight checks -------------------------------------------------------
[[ $EUID -ne 0 ]] && error "Please run as root or with sudo."
log "Checking for NVIDIA GPU..."
if ! lspci | grep -qi nvidia; then
error "No NVIDIA GPU detected. Aborting."
fi
log "Checking for NVIDIA driver..."
if ! nvidia-smi &>/dev/null; then
warn "NVIDIA driver not found. Attempting to install recommended driver..."
apt-get update -qq
apt-get install -y ubuntu-drivers-common
ubuntu-drivers autoinstall
warn "NVIDIA driver installed. A REBOOT may be required before proceeding."
read -rp "Continue anyway? (y/N): " choice
[[ "$choice" != [yY] ]] && { log "Reboot and re-run this script."; exit 0; }
fi
nvidia-smi
log "NVIDIA driver is working."
# --- Install Docker -----------------------------------------------------------
if ! command -v docker &>/dev/null; then
log "Docker not found. Installing Docker Engine..."
apt-get update -qq
apt-get install -y ca-certificates curl gnupg
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
# Detect distro (works for Ubuntu & Debian)
DISTRO_ID=$(. /etc/os-release && echo "$ID")
DISTRO_CODENAME=$(. /etc/os-release && echo "$VERSION_CODENAME")
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/${DISTRO_ID} ${DISTRO_CODENAME} stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null
apt-get update -qq
apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
systemctl enable --now docker
log "Docker installed successfully."
else
log "Docker is already installed: $(docker --version)"
fi
# --- Install NVIDIA Container Toolkit ----------------------------------------
log "Adding NVIDIA Container Toolkit repository..."
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \
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' | \
tee /etc/apt/sources.list.d/nvidia-container-toolkit.list > /dev/null
apt-get update -qq
apt-get install -y nvidia-container-toolkit
# --- Configure Docker runtime -------------------------------------------------
log "Configuring Docker to use NVIDIA runtime..."
nvidia-ctk runtime configure --runtime=docker
systemctl restart docker
log "Docker restarted with NVIDIA runtime."
# --- Verify -------------------------------------------------------------------
log "Running verification: docker run --gpus all nvidia/cuda nvidia-smi"
echo "---"
docker run --rm --gpus all nvidia/cuda:12.6.3-base-ubuntu24.04 nvidia-smi
echo ""
log "============================================="
log " NVIDIA Docker setup complete!"
log " Usage: docker run --gpus all <image>"
log "============================================="

23
openai/docker-compose.yml Normal file
View File

@@ -0,0 +1,23 @@
services:
open-webui:
image: ghcr.io/open-webui/open-webui:ollama
container_name: open-webui
ports:
- "3125:8080"
volumes:
- ollama:/root/.ollama
- open-webui:/app/backend/data
restart: always
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
environment:
- ANTHROPIC_API_KEY=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
volumes:
ollama:
open-webui: