Blame
|
1 | # Documents Stack |
||||||
| 2 | ||||||||
| 3 | ← [[Home]] |
|||||||
| 4 | ||||||||
|
5 | Services running on PCT 104 (documents, 192.168.2.105). Docker storage on ZFS (`/tank/docker`). Only `/tank/media` and `/tank/appdata/nextcloud` are bind-mounted — not the full tank. |
||||||
|
6 | |||||||
| 7 | --- |
|||||||
| 8 | ||||||||
| 9 | ## Service URLs |
|||||||
| 10 | ||||||||
| 11 | | Service | URL | Port | Stack | |
|||||||
| 12 | |---------|-----|------|-------| |
|||||||
| 13 | | Immich | `photos.carr-family.org` | 2283 | `documents-immich` (compose 10) | |
|||||||
| 14 | | Nextcloud | `cloud.carr-family.org` | 8085 | `documents-nextcloud` (compose 7) | |
|||||||
| 15 | | Paperless-ngx | `paperless.carr-family.org` | 8000 | `documents-paperless` (compose 4) | |
|||||||
| 16 | | paperless-gpt | `paperless-gpt.carr-family.org` | 8080 | `documents-paperless` (compose 4) | |
|||||||
| 17 | | Linkwarden | `links.carr-family.org` | 3000 | `documents-linkwarden` (compose 2) | |
|||||||
| 18 | | Actual Budget | `actual.carr-family.org` | 5006 | `documents-actual-budget` (compose 28) | |
|||||||
| 19 | | OtterWiki | `otterwiki.carr-family.org` | 8081 | standalone (not Swarm) | |
|||||||
| 20 | ||||||||
| 21 | --- |
|||||||
| 22 | ||||||||
| 23 | ## Immich (compose 10) |
|||||||
| 24 | ||||||||
| 25 | Photo management at `photos.carr-family.org`. Services: immich-server, machine-learning, postgres/pgvecto.rs (port 5435), valkey. |
|||||||
| 26 | ||||||||
|
27 | GPU: uses `-cuda` image (`ghcr.io/immich-app/immich-machine-learning:release-cuda`) with `DEVICE=cuda` + `NVIDIA_VISIBLE_DEVICES=all`. `nvidia-container-toolkit` installed in PCT 104; Docker default runtime is `nvidia`. |
||||||
|
28 | |||||||
|
29 | **Redeploy** (env vars stored in Portainer DB — export in shell): |
||||||
|
30 | ```bash |
||||||
| 31 | pct exec 108 -- bash -c 'export DB_PASSWORD=T5dBbAvgHWceH7jhsxjism4b2Cre9NA DB_USERNAME=immich DB_DATABASE_NAME=immich && docker stack deploy -c /mnt/tank/appdata/portainer/compose/10/docker-compose.yml documents-immich' |
|||||||
| 32 | ``` |
|||||||
| 33 | ||||||||
| 34 | --- |
|||||||
| 35 | ||||||||
| 36 | ## Nextcloud (compose 7) |
|||||||
| 37 | ||||||||
| 38 | File cloud at `cloud.carr-family.org`. Services: app (port 8085), cron, postgres:16 (port 5432). |
|||||||
| 39 | ||||||||
|
40 | - Nextcloud data on ZFS at `/mnt/tank/appdata/nextcloud/` (migrated 2026-05-25) |
||||||
|
41 | - `PUID/PGID: 33:33` |
||||||
|
42 | - Obsidian vault lives inside the Nextcloud data tree: `/tank/appdata/nextcloud/data/data/nextcloud/files/obsidian` (bind-mounted into PCT 107 and PCT 109) |
||||||
|
43 | |||||||
| 44 | --- |
|||||||
| 45 | ||||||||
| 46 | ## Paperless-ngx (compose 4) |
|||||||
| 47 | ||||||||
| 48 | Document management at `paperless.carr-family.org`. Services: webserver (port 8000), paperless-gpt (port 8080), redis, postgres (port 5433). |
|||||||
| 49 | ||||||||
| 50 | **Redeploy** (env vars not in .env): |
|||||||
| 51 | ```bash |
|||||||
| 52 | pct exec 108 -- bash -c 'export POSTGRES_DB=paperless POSTGRES_USER=paperless POSTGRES_PASSWORD=eWJarhDasRNBu0LfBwuI6VPOXwnRCUy PAPERLESS_SECRET_KEY=J60Om5l2dsL1pUSWz3AQhqizRFhlii8dRzsynYrAfzbBsV316S PAPERLESS_TIME_ZONE=America/Chicago PAPERLESS_URL=https://paperless.carr-family.org "PAPERLESS_CSRF_TRUSTED_ORIGINS=https://paperless.carr-family.org" && docker stack deploy -c /mnt/tank/appdata/portainer/compose/4/docker-compose.yml documents-paperless' |
|||||||
| 53 | ``` |
|||||||
| 54 | ||||||||
|
55 | ### Paperless Gotchas |
||||||
| 56 | ||||||||
| 57 | **Postgres password gotcha** — `POSTGRES_PASSWORD` only applies on first-init. If the DB container is recreated (e.g. Watchtower update) with existing data, the stored password is unchanged but a mismatch causes `password authentication failed` crash-loop. Fix via local socket (trust auth bypasses password check): |
|||||||
|
58 | ```bash |
||||||
| 59 | DB=$(pct exec 104 -- docker ps --format '{{.Names}}' | grep 'paperless_db\.' | head -1) |
|||||||
| 60 | pct exec 104 -- docker exec $DB psql -U paperless -d paperless -c "ALTER USER paperless PASSWORD 'newpassword'" |
|||||||
| 61 | pct exec 108 -- docker service update --force documents-paperless_webserver |
|||||||
| 62 | ``` |
|||||||
| 63 | ||||||||
|
64 | > Note (2026-05-29): DB passwords and Paperless secret key regenerated after Portainer lost stack env vars. Data intact; sessions invalidated. |
||||||
| 65 | ||||||||
|
66 | ### paperless-gpt |
||||||
| 67 | ||||||||
|
68 | LLM-powered title/tag suggestions + OCR at `paperless-gpt.carr-family.org` (port 8080). Image: `icereed/paperless-gpt:latest`. |
||||||
|
69 | |||||||
|
70 | - **General LLM:** `gpt-4o-mini` via LiteLLM (`http://192.168.2.83:4000`) |
||||||
| 71 | - **OCR LLM:** `llava:7b` via LiteLLM → Ollama on `192.168.2.11` (RTX 3060). `llama3.2-vision:11b` failed — Ollama 0.30.7 on .11 doesn't support `mllama` arch. |
|||||||
| 72 | - **Trigger:** tag a document `paperless-gpt-ocr` to trigger OCR processing |
|||||||
| 73 | - **API token:** `71c8ba36985118d419cf9a1f5f8497290d816e10` |
|||||||
|
74 | |||||||
| 75 | --- |
|||||||
| 76 | ||||||||
| 77 | ## Linkwarden (compose 2) |
|||||||
| 78 | ||||||||
| 79 | Bookmark manager at `links.carr-family.org`. Services: linkwarden (port 3000), meilisearch, postgres (port 5434). |
|||||||
| 80 | ||||||||
| 81 | **API token:** |
|||||||
| 82 | ``` |
|||||||
| 83 | eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0..jE4UUgAXi4UpbmBi.1HbSWJSBdDAHur9EAI28WT2Cbt4rJqzakS_RrjQq9jT34iRJBb7nEW97Ml218sECdaShktMrdxAXrl6zQFXBkM4G2jpWtSEOUlIKlOH0v1KAtXRfpb9b.tNDkqQ1JdOz6gALxNDKhVA |
|||||||
| 84 | ``` |
|||||||
| 85 | ||||||||
|
86 | **PUT /api/v1/links/:id gotcha** — payload must include `collection: {id, name, ownerId}` and tags as `[{id, name}]`. Omitting either returns `400: expected number, received undefined [id]`. |
||||||
| 87 | ||||||||
| 88 | ### Auto-sort Script (PCT 109) |
|||||||
| 89 | ||||||||
| 90 | - **Script:** `/opt/linkwarden-sort/sort.py` |
|||||||
| 91 | - **Cron:** `*/2 * * * *` — runs every 2 minutes, logs to `/var/log/linkwarden-sort.log` |
|||||||
| 92 | ||||||||
| 93 | Moves new links out of Unorganized (id 1) automatically. Categorization priority: |
|||||||
| 94 | 1. AI tags (Linkwarden auto-tags on save) |
|||||||
| 95 | 2. URL patterns — known subreddits, makerworld.com, kemono.cr, etc. |
|||||||
| 96 | 3. TikTok — follows redirect to get `@username`, maps known creators; falls back to username pattern matching |
|||||||
| 97 | 4. Title/meta keywords |
|||||||
|
98 | |||||||
|
99 | To add new rules, edit `TAG_RULES`, `URL_RULES`, `TITLE_RULES`, or `TIKTOK_USER_RULES` at the top of the script. |
||||||
|
100 | |||||||
|
101 | ### Collection IDs |
||||||
|
102 | |||||||
| 103 | | ID | Name | |
|||||||
| 104 | |----|------| |
|||||||
| 105 | | 1 | Unorganized | |
|||||||
| 106 | | 4 | Minecraft | |
|||||||
| 107 | | 7 | 3D-Printing | |
|||||||
| 108 | | 8 | Homelab | |
|||||||
| 109 | | 9 | Self-Host | |
|||||||
| 110 | | 10 | Tabletop/Board Games | |
|||||||
| 111 | | 11 | Video Games | |
|||||||
| 112 | | 14 | Art | |
|||||||
| 113 | | 17 | Satisfactory | |
|||||||
| 114 | | 18 | Dungeons and Dragons | |
|||||||
| 115 | | 19 | Pokemon | |
|||||||
| 116 | ||||||||
| 117 | --- |
|||||||
| 118 | ||||||||
| 119 | ## OtterWiki (standalone — not Swarm) |
|||||||
| 120 | ||||||||
| 121 | This wiki. Docker Compose on PCT 104 at `/mnt/tank/appdata/otterwiki/docker-compose.yml`. |
|||||||
| 122 | ||||||||
| 123 | - **Image:** `redimp/otterwiki:2` |
|||||||
|
124 | - **Port:** 8081 (host-mode on 192.168.2.105) |
||||||
| 125 | - **Static route:** Traefik `routes.yml` → `http://192.168.2.105:8081` |
|||||||
| 126 | - **Repository:** `/mnt/tank/appdata/otterwiki/repository/` — all pages stored as `.md` files, tracked in git |
|||||||
|
127 | - **PUID/PGID:** `33:33` |
||||||
| 128 | ||||||||
|
129 | **Restart:** |
||||||
| 130 | ```bash |
|||||||
| 131 | pct exec 104 -- docker compose -f /mnt/tank/appdata/otterwiki/docker-compose.yml restart |
|||||||
| 132 | ``` |
|||||||
| 133 | ||||||||
| 134 | **To edit pages directly via git** (e.g. bulk imports): |
|||||||
| 135 | ```bash |
|||||||
| 136 | git config --global --add safe.directory /mnt/tank/appdata/otterwiki/repository |
|||||||
| 137 | cd /mnt/tank/appdata/otterwiki/repository |
|||||||
| 138 | git add -A && git commit -m "message" |
|||||||
| 139 | ``` |
|||||||
| 140 | OtterWiki picks up committed changes immediately on next page load. |
|||||||
