docs(apps): expand configuration and integration guides

This commit is contained in:
Eduardo David Paredes Vara
2026-08-09 17:15:58 +00:00
parent 4563322851
commit 587495c195
22 changed files with 477 additions and 51 deletions
+15
View File
@@ -2,6 +2,21 @@
Base de conocimiento y documentación desplegada con MariaDB, acceso por Traefik y envío de correo mediante `mail-relay`.
## Arquitectura y propósito
`bookstack` sirve la aplicación y guarda adjuntos/configuración en `BOOKSTACK_DATA_PATH`; `bookstack-db` conserva páginas, permisos y estructura en MariaDB. La base sólo usa la red interna `bookstack`. La aplicación se añade a `proxy` para Traefik y a `mail_internal` para enviar correo sin publicar la base de datos ni el relay.
## Configuración
- `BOOKSTACK_DOMAIN` y `APP_URL` deben coincidir para que enlaces, cookies y redirecciones HTTPS sean válidos.
- `APP_KEY` cifra datos de aplicación: genérala una vez, mantenla estable y respáldala como secreto.
- Las variables `BOOKSTACK_DB_*` conectan ambos contenedores; las contraseñas deben existir sólo en `.env`.
- `BOOKSTACK_PUID` y `BOOKSTACK_PGID` deben tener acceso a `BOOKSTACK_DATA_PATH`.
- `BOOKSTACK_LANG` y `BOOKSTACK_DARK_MODE` fijan los valores iniciales de interfaz.
- `BOOKSTACK_MAIL_FROM*` identifica el remitente; el transporte usa el servicio interno `mail-relay`.
Separar datos y base permite actualizar la imagen sin perder contenido y respaldar cada componente con el método adecuado.
## Requisitos
- Docker Compose
+14 -1
View File
@@ -2,9 +2,22 @@
changedetection.io published at `https://changedetection.sherlockhomeless.net`.
Deploy with:
## Qué hace y cómo funciona
Supervisa páginas y avisa cuando cambia su contenido. `changedetection` guarda reglas e histórico en `CHANGEDETECTION_DATA_PATH`; `changedetection-browser` renderiza sitios con JavaScript mediante Playwright. El navegador sólo está en `changedetection_internal`, porque su puerto de depuración no debe exponerse.
## Configuración
- `CHANGEDETECTION_DOMAIN` forma `BASE_URL` y debe coincidir con Traefik.
- `CHANGEDETECTION_IMAGE` y `CHANGEDETECTION_BROWSER_IMAGE` fijan las versiones de aplicación y navegador.
- `CHANGEDETECTION_DATA_PATH` contiene toda la configuración que debe respaldarse.
- `PLAYWRIGHT_DRIVER_URL` ya apunta al sidecar; elige el fetcher Playwright dentro de la UI sólo para páginas que lo necesiten, ya que consume más recursos.
- El router dinámico combina CrowdSec, Authentik y Sablier: seguridad, control de identidad y arranque bajo demanda, respectivamente.
## Despliegue
```bash
docker compose --env-file .env config
docker compose --env-file .env up -d
```
+14 -1
View File
@@ -2,9 +2,22 @@
Actual Budget published at `https://finance.sherlockhomeless.net`.
Deploy with:
## Qué hace y cómo funciona
Actual Budget permite administrar presupuesto personal con un modelo local-first y sincronización mediante el servidor. Los datos del servidor se guardan en `ACTUALBUDGET_DATA_PATH`; no hay base de datos separada.
## Configuración
- `ACTUALBUDGET_DOMAIN` define el dominio publicado.
- `ACTUALBUDGET_IMAGE` controla la versión que se despliega.
- `ACTUALBUDGET_DATA_PATH` debe incluirse en backups y tener permisos de escritura.
- La red interna aísla el servicio y `proxy` permite a Traefik alcanzarlo.
- El router externo aplica CrowdSec, Authentik y Sablier. Authentik protege el acceso al servidor, pero no sustituye las credenciales/cifrado que configure Actual Budget.
## Despliegue
```bash
docker compose --env-file .env config
docker compose --env-file .env up -d
```
+12 -1
View File
@@ -2,10 +2,21 @@
Lector RSS personal publicado en `rss.sherlockhomeless.net`.
## Qué hace y arquitectura
FreshRSS agrega feeds, actualiza artículos mediante cron y ofrece una API compatible con clientes móviles. Este despliegue usa SQLite: datos, usuarios y configuración viven en `FRESHRSS_DATA_PATH`; las extensiones se separan en `FRESHRSS_EXTENSIONS_PATH`.
## Configuración
- `FRESHRSS_DOMAIN` define el dominio usado por Traefik.
- `FRESHRSS_CRON_MIN` controla la frecuencia de actualización; una frecuencia agresiva aumenta carga y peticiones a los sitios origen.
- `FRESHRSS_ENV` debe permanecer en producción.
- La web pasa por Authentik, pero la ruta de API no puede usar ese forward-auth porque los clientes móviles no completan el flujo web. Activa la API en el perfil de FreshRSS y usa una contraseña API distinta de la contraseña principal.
- No usa Sablier para que cron pueda actualizar feeds incluso sin visitas.
## Despliegue
```bash
cp .env.example .env
docker compose --env-file .env config
docker compose --env-file .env up -d
```
+17 -1
View File
@@ -4,9 +4,25 @@ Ghost publication for the personal site currently exposed as:
- `https://me.thehomelesssherlock.com`
Deploy with Docker Compose from this directory:
## Qué hace y arquitectura
Es el sitio personal y portfolio. `ghost-me-db` conserva contenido en MySQL y `ghost-me` sirve Ghost con el tema local `theme-source-personal`. `routes.yaml` separa inicio, blog y proyectos mediante colecciones y etiquetas.
## Configuración
- `GHOST_ME_DOMAIN` es el dominio canónico; `GHOST_ME_DOMAIN_ALT` redirige permanentemente al principal.
- `GHOST_ME_DB_*` configura MySQL y debe permanecer sólo en `.env`.
- `GHOST_ME_CONTENT_PATH` conserva uploads y configuración de Ghost.
- `GHOST_ME_ROUTES_PATH` monta las rutas de contenido y debe apuntar a `./routes.yaml`.
- `GHOST_ME_MAIL_FROM` y `mail_internal` permiten correo mediante `mail-relay`.
- El tema se monta desde el repositorio para poder versionarlo; valida sus cambios con `npm test` dentro de `theme-source-personal` antes de actualizarlo.
La base queda aislada en `ghost_me_internal`; únicamente Ghost se conecta a `proxy` y `mail_internal`.
## Despliegue
```bash
docker compose --env-file .env config
docker compose --env-file .env up -d
```
+12
View File
@@ -2,6 +2,18 @@
Ghost publica `news.sherlockhomeless.net` como archivo de informes diarios.
## Arquitectura y configuración
- `ghost-db` conserva contenido y miembros en MySQL; sólo pertenece a `ghost_internal`.
- `ghost` sirve la publicación, persiste temas y medios en `GHOST_CONTENT_PATH`, usa `mail-relay` y se publica mediante `proxy`.
- `ghost-ops-gate` protege el índice privado `/ops` comprobando el miembro autenticado contra `GHOST_OPS_ALLOWED_EMAIL` y consultando posts con `GHOST_CONTENT_API_KEY`.
`GHOST_DOMAIN` fija la URL canónica; las variables `GHOST_DB_*` deben coincidir entre Ghost y MySQL. `GHOST_MAIL_FROM` controla el remitente. La Content API key sólo permite lectura, pero sigue siendo secreta y debe vivir únicamente en `.env`.
Los overrides de `theme-overrides/headline` ocultan publicaciones etiquetadas `#private-ops`. Deben aplicarse sobre la versión compatible del tema; tras actualizar Ghost o Headline, revisa diferencias antes de copiarlos.
La capa `/ops` no reemplaza la seguridad de cada post: usa miembros de Ghost, etiqueta interna y visibilidad adecuada, además del gate.
## Despliegue
```bash
+22
View File
@@ -8,3 +8,25 @@ Guacamole runs in Docker and connects to the host XFCE desktop through local `xr
- Backend RDP target: `host.docker.internal:3389`
Use a local host account that is allowed to start an XRDP session.
## Qué hace y arquitectura
Apache Guacamole ofrece escritorio remoto desde el navegador. `guacamole` gestiona usuarios y conexiones, `guacd` traduce el protocolo web a RDP y PostgreSQL conserva la configuración. Sólo la aplicación web llega a `proxy`; guacd y PostgreSQL permanecen en la red interna.
## Configuración
- `GUACAMOLE_DOMAIN` define el acceso publicado por Traefik.
- `GUACAMOLE_DB_*` debe coincidir en PostgreSQL y Guacamole.
- `GUACAMOLE_DATA_PATH` persiste la base; `initdb` sólo inicializa una base vacía.
- `host.docker.internal` se fija a `10.0.4.1` para alcanzar XRDP del host. Si cambia la IP del bridge/host, actualiza ambos servicios.
- `WEBAPP_CONTEXT=ROOT` elimina el prefijo `/guacamole`.
Authentik protege el perímetro, pero Guacamole mantiene sus propios usuarios y permisos sobre conexiones. Evita cuentas compartidas y no publiques el puerto RDP en la zona pública.
## Despliegue
```bash
cd guacamole
docker compose --env-file .env config
docker compose --env-file .env up -d
```
+8
View File
@@ -2,6 +2,10 @@
Stack para desplegar [Homepage](https://gethomepage.dev/) detrás de Traefik como dashboard principal en `www.sherlockhomeless.net`.
## Qué hace y arquitectura
Homepage crea un portal a partir de los YAML guardados en `HOMEPAGE_CONFIG_PATH` y descubre servicios mediante labels `homepage.*`. El socket Docker está montado en sólo lectura para descubrir contenedores, pero ese acceso sigue revelando metadatos sensibles; la UI se protege con CrowdSec y Authentik.
## 🚀 Despliegue con Docker Compose
Asegurate de tener `homepage/.env` configurado y despliega:
@@ -31,3 +35,7 @@ mkdir -p /opt/homepage/config
```
Homepage leerá su configuración desde `/opt/homepage/config` y expondrá la UI interna en el puerto `3000`, publicado externamente a través de Traefik y protegido con Authentik mediante `ths-authentik@docker`.
`HOMEPAGE_ALLOWED_HOSTS` evita peticiones con cabeceras Host inesperadas y debe incluir el dominio público. `TRAEFIK_AUTH_MIDDLEWARE` referencia un middleware existente, no credenciales de Authentik. El router adicional redirige el dominio raíz a `www`; se mantiene separado para no mezclar la redirección con el servicio real.
Respalda los YAML de configuración, pero no incluyas tokens de widgets directamente: usa el mecanismo de secretos/variables admitido por Homepage.
+6
View File
@@ -2,6 +2,12 @@
Coleccion de herramientas tecnicas self-hosted.
## Qué hace y configuración
IT-Tools reúne conversores, generadores y utilidades que se ejecutan principalmente en el navegador. `IT_TOOLS_BASE_IMAGE` fija la imagen upstream usada por el build y `IT_TOOLS_IMAGE` nombra la imagen local resultante. `IT_TOOLS_DOMAIN` y `TRAEFIK_DOCKER_NETWORK` controlan la publicación por Traefik.
La imagen se construye localmente porque el `Dockerfile` aplica un parche al generador FIGlet. Esta decisión evita depender de una URL rota del upstream; al actualizar la imagen base, verifica si el parche sigue siendo necesario y que aplique sin ocultar cambios incompatibles.
- URL: `https://it.sherlockhomeless.net/`
- Contenedor: `it-tools`
- Red externa: `proxy`
+16
View File
@@ -2,6 +2,22 @@
Servicio para guardar, buscar y enriquecer enlaces. Incluye Karakeep, un navegador Chromium para capturas y Meilisearch para indexación.
## Arquitectura y propósito
Karakeep guarda el contenido principal en `/opt/karakeep/data`, delega la búsqueda a `karakeep-meilisearch` y usa `karakeep-chrome` para renderizar páginas dinámicas y generar capturas. Sólo la aplicación se une a `proxy`; Chrome y Meilisearch permanecen en `karakeep_internal`.
## Configuración
- `KARAKEEP_DOMAIN` define la URL canónica usada por NextAuth.
- `NEXTAUTH_SECRET` firma sesiones; debe ser aleatorio y estable.
- `MEILI_MASTER_KEY` protege el índice. Debe coincidir en Karakeep y Meilisearch y nunca contener un valor real en `stack.env`.
- `DISABLE_SIGNUPS` debe permanecer activado tras crear las cuentas necesarias.
- `OCR_LANGS` controla los idiomas de reconocimiento.
- Las variables `INFERENCE_*`, `OPENAI_API_KEY` y `EMBEDDING_TEXT_MODEL` habilitan etiquetado, resumen y embeddings. Si se usa LiteLLM, configura una URL compatible soportada por Karakeep y entrega una clave de LiteLLM, nunca `auth.json` de Codex.
- `INFERENCE_NUM_WORKERS` y los límites de contexto/salida controlan consumo y concurrencia; aumenta estos valores sólo después de medir memoria y cuota.
Chrome se ejecuta con `--no-sandbox`; por eso no debe exponerse a redes externas.
## Requisitos
- Docker Compose
+86 -9
View File
@@ -1,14 +1,83 @@
# LiteLLM
Proxy unificado para proveedores de modelos LLM, con configuración en `config.yaml`, proveedor local en `codex_provider.py` y PostgreSQL para persistencia.
LiteLLM es la pasarela central de modelos del repositorio. Ofrece una API compatible con OpenAI a aplicaciones como Open WebUI, n8n y Paperless AI, mientras mantiene las credenciales reales de los proveedores en un único servicio.
## Requisitos
## Qué despliega
- Docker Compose
- Red externa `proxy`
- Un archivo `.env` local con las claves de proveedores, claves maestras de LiteLLM y credenciales PostgreSQL
- El archivo de autenticación de Codex montado en la ruta definida por el Compose
- Enrutamiento dinámico de Traefik configurado fuera de esta aplicación
- `litellm`: proxy, catálogo de modelos y proveedor personalizado de Codex.
- `litellm-db`: PostgreSQL para configuración y estado persistente de LiteLLM.
- `config.yaml`: alias públicos y proveedor asociado a cada modelo.
- `codex_provider.py`: adaptación entre la API de LiteLLM y la API Responses de Codex.
Esta separación evita configurar una credencial de OpenAI o Codex distinta en cada consumidor. Las aplicaciones sólo conocen la URL de LiteLLM, una clave de acceso de LiteLLM y el alias del modelo.
## Redes y exposición
LiteLLM pertenece a su red interna `litellm` y a la red externa `proxy`. PostgreSQL sólo está en la red interna. Los consumidores conectados a `proxy` pueden usar:
```text
http://litellm:4000/v1
```
El acceso público y la interfaz se enrutan mediante la configuración dinámica de Traefik en `/opt/traefik/dynamic/litellm.yml`. La API debe exigir `LITELLM_MASTER_KEY`; la protección SSO de la interfaz no sustituye esa clave.
## Configuración
El `.env` local debe definir, como mínimo:
| Variable | Función | Motivo |
| --- | --- | --- |
| `LITELLM_MASTER_KEY` | Autentica a los consumidores de la API | Impide usar los modelos sólo por alcanzar la red |
| `LITELLM_SALT_KEY` | Cifra datos sensibles almacenados por LiteLLM | Debe permanecer estable tras el primer arranque |
| `POSTGRES_USER`, `POSTGRES_PASSWORD`, `POSTGRES_DB` | Base de datos interna | No se exponen fuera de la red `litellm` |
| `LITELLM_DB_DATA_PATH` | Persistencia de PostgreSQL | Permite recrear contenedores sin perder estado |
| `DEEPSEEK_API_KEY` | Acceso directo a DeepSeek | Sólo se necesita para los alias `thsllm-*` |
`config.yaml` publica alias estables. Los consumidores deben pedir el alias, no el identificador interno del proveedor. Así se puede cambiar el backend sin reconfigurar cada aplicación.
## Autenticación de Codex
El Compose monta:
```text
/home/felidae/.codex/auth.json -> /root/.codex/auth.json
```
La variable `CODEX_AUTH_FILE` apunta a la ruta interior. El montaje es de lectura y escritura porque `codex_provider.py` renueva el access token mediante el refresh token y guarda el resultado en el mismo archivo.
Flujo:
1. El usuario inicia sesión con Codex en el host y genera `~/.codex/auth.json`.
2. Docker monta ese archivo únicamente dentro de LiteLLM.
3. El proveedor lee `access_token`, `refresh_token` y `account_id`.
4. Si el JWT vence en menos de 60 segundos, solicita un token nuevo y actualiza el archivo montado.
5. LiteLLM envía la petición a Codex y devuelve una respuesta compatible con OpenAI al consumidor.
El archivo contiene credenciales reutilizables. No debe copiarse al repositorio, incluirse en imágenes, logs, backups sin cifrar ni montarse en Paperless, n8n u Open WebUI. `.gitignore` excluye `.codex`, pero conviene comprobar antes de cada commit:
```bash
git status --ignored --short | grep codex
```
El usuario que ejecuta Docker debe poder leer y escribir el archivo. Si el host o usuario cambia, actualiza la ruta del volumen en `docker-compose.yml`; una ruta inexistente puede terminar creada como directorio y provocar errores de autenticación.
## Modelos Codex
Los alias `gpt-*` configurados con `custom_llm_provider: codex` pasan por `codex_provider.py`. Internamente se usa el prefijo `cx-` para evitar colisiones con los modelos OpenAI nativos de LiteLLM; el proveedor vuelve a convertirlo antes de llamar a Codex.
El proveedor admite llamadas síncronas, asíncronas y streaming. Codex responde siempre mediante streaming; para una llamada no streaming, el proveedor agrega los fragmentos antes de responder.
## Configurar consumidores
Un consumidor compatible con OpenAI necesita:
```text
Base URL: http://litellm:4000/v1
API key: valor de LITELLM_MASTER_KEY
Model: gpt-5.6-sol
```
Usa la URL interna cuando ambos contenedores compartan `proxy`. Usa la URL HTTPS sólo para clientes externos. Nunca uses el token de Codex como API key del consumidor.
## Despliegue
@@ -18,11 +87,19 @@ docker compose --env-file .env config
docker compose --env-file .env up -d
```
## Operación
## Verificación
```bash
docker compose --env-file .env ps
docker compose --env-file .env logs -f litellm
curl -sS http://127.0.0.1:4000/v1/models \
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
```
La API se autentica con `LITELLM_MASTER_KEY`; no publiques esa clave ni el `.env`.
Si no se publica el puerto en el host, ejecuta la prueba desde un contenedor unido a `proxy` o usa el dominio HTTPS.
Errores `401` que mencionen Codex suelen indicar que `auth.json` falta, no tiene permisos o ya no puede renovarse. Errores `401` devueltos antes de seleccionar modelo suelen indicar una `LITELLM_MASTER_KEY` incorrecta.
## Persistencia y copias de seguridad
Respalda la ruta `LITELLM_DB_DATA_PATH`. Trata `auth.json` como un secreto independiente: si se respalda, debe hacerse cifrado y con acceso restringido. No restaures simultáneamente versiones distintas del archivo desde varios hosts, porque la rotación del refresh token puede invalidar la copia anterior.
+14
View File
@@ -2,6 +2,20 @@
Aplicación de notas ligeras respaldada por PostgreSQL. El contenedor `memos-proxy` actúa como punto de entrada hacia Memos.
## Arquitectura y propósito
`memos-db` conserva usuarios y notas, `memos` ofrece la aplicación en la red interna y `memos-proxy` aplica la adaptación HTTP necesaria antes del enrutamiento externo. La base y Memos no se publican directamente.
## Configuración
- `MEMOS_DB_NAME`, `MEMOS_DB_USER` y `MEMOS_DB_PASSWORD` deben coincidir entre PostgreSQL y el DSN generado por el Compose.
- `MEMOS_DOMAIN` establece la URL pública que Memos usa en enlaces y respuestas.
- `TZ` mantiene consistencia en fechas y tareas.
- `/opt/memos/postgres` contiene la base y `/opt/memos/data` los recursos propios de la aplicación.
- `proxy/server.js` se monta en sólo lectura; cualquier cambio requiere recrear `memos-proxy`.
El proxy tiene `traefik.enable=false` porque el routing se administra externamente. No actives un segundo router sin comprobar prioridades y autenticación.
## Requisitos
- Docker Compose
+32
View File
@@ -1,11 +1,43 @@
# n8n Observability Toolkit
Carpeta dedicada para automatizar en n8n:
- Resumen diario de estado del servidor
- Alertas de caida real de servicios
- Informes automaticos de logs y errores
- Resumen IA (texto ejecutivo)
No despliega un contenedor propio. Los scripts se ejecutan en el host porque necesitan consultar systemd, Docker, certificados y endpoints locales; n8n los invoca mediante una credencial SSH con permisos limitados.
## Configuración
- Copia `config/services.example.json` a una ubicación local no versionada y define los endpoints que deben comprobarse.
- `HEALTH_ENDPOINTS` permite pasar endpoints directamente; `HEALTH_EXPECTED_CODES` ajusta los códigos aceptados.
- `TARGET_CONTAINERS` limita los contenedores incluidos en el resumen de logs.
- `SINCE` fija la ventana temporal, por ejemplo `24 hours ago`.
- `CERT_EXCLUDE_DOMAINS` omite dominios que no deban auditarse.
- Las variables `OPENCLAW_*` configuran únicamente la comprobación/renovación OAuth del proveedor indicado; no deben imprimirse tokens.
Se recomienda un usuario SSH dedicado que pueda ejecutar estos scripts y los comandos de lectura necesarios, sin shell administrativa general. Si requiere `sudo`, limita comandos y argumentos en `sudoers`.
## Integración con LiteLLM y Codex
El nodo de IA de n8n debe consumir LiteLLM mediante su API compatible con OpenAI, usando una clave de LiteLLM y un alias de modelo. n8n no necesita acceso al archivo `auth.json` de Codex. LiteLLM mantiene y renueva esa sesión, mientras n8n sólo envía el digest ya filtrado.
```text
n8n -> http://litellm:4000/v1 -> alias de modelo -> proveedor Codex
```
Esta separación permite revocar el acceso de n8n sin cerrar la sesión de Codex y evita distribuir el refresh token. El chequeo `openclaw_codex_oauth` de este toolkit es independiente del montaje usado por LiteLLM; no asumas que validar uno valida automáticamente el otro.
## Instalación
No se usa Docker Compose. Conserva el directorio en el host, da permisos de ejecución a los scripts y configura en n8n la conexión SSH:
```bash
chmod +x n8n-observability/scripts/*.sh n8n-observability/scripts/ops-report
```
## Estructura
- `scripts/ops-report`: motor Python unificado para `summary`, `logs`, `health` y `all`
+15
View File
@@ -2,6 +2,21 @@
Plataforma de archivos y colaboración con MariaDB, Redis, tareas cron y OnlyOffice Document Server.
## Arquitectura y propósito
MariaDB guarda metadatos, Redis aporta bloqueo y caché, `nextcloud` sirve la web y `nextcloud-cron` ejecuta tareas en segundo plano sobre los mismos volúmenes. OnlyOffice es un servicio independiente para editar documentos y se integra mediante JWT.
## Configuración
- `NC_DOMAIN`, `TRUSTED_PROXIES` y las variables `OVERWRITE*` hacen que Nextcloud genere HTTPS correctamente detrás de Traefik.
- `MYSQL_*` debe coincidir en Nextcloud, cron y MariaDB.
- `NEXTCLOUD_ADMIN_*` sólo inicializa la primera instalación; después administra usuarios desde Nextcloud.
- `SMTP_*` configura notificaciones a través de `mail_internal`.
- `OO_DOMAIN`, `OO_JWT_SECRET` y `OO_SECURE_LINK_SECRET` protegen la comunicación con OnlyOffice; el JWT configurado en la app de Nextcloud debe ser idéntico.
- `/opt/nextcloud/html`, `config`, `data`, `custom_apps` y `themes` se comparten con cron para ejecutar el mismo código y configuración.
Redis no sustituye una copia de seguridad. Respalda MariaDB, configuración y datos de forma consistente, preferiblemente activando antes el modo mantenimiento.
## Requisitos
- Docker Compose
+14
View File
@@ -2,6 +2,20 @@
Servicio para compartir secretos de un solo uso, con Redis para persistencia temporal y autenticación OIDC mediante Authentik.
## Arquitectura y propósito
OneTimeSecret cifra y entrega secretos temporales; Redis mantiene su estado. El navegador recibe el enlace, pero la política de acceso exige autenticación OIDC. El Compose usa `AUTH_SSO_ONLY=true`, desactiva altas y evita cuentas locales como vía habitual.
## Configuración
- `OTS_SECRET` alimenta las distintas claves criptográficas internas. Debe ser largo, aleatorio, estable y exclusivo de esta app.
- `OTS_DOMAIN` debe coincidir con `OIDC_REDIRECT_URI` y con el cliente creado en Authentik.
- `OTS_OIDC_ISSUER`, `OTS_OIDC_CLIENT_ID` y `OTS_OIDC_CLIENT_SECRET` enlazan el cliente OIDC.
- `OTS_DATA_PATH` conserva datos de aplicación y `OTS_REDIS_PATH` el estado de Redis.
- Las imágenes se fijan con `OTS_IMAGE` y `OTS_REDIS_IMAGE` para controlar actualizaciones.
Un secreto de un solo uso sigue siendo sensible mientras exista. Restringe backups, logs y acceso administrativo a Redis.
## Requisitos
- Docker Compose
+14
View File
@@ -2,6 +2,20 @@
Repositorio privado de gists y fragmentos de código, publicado mediante Traefik y autenticado por OIDC.
## Arquitectura y propósito
OpenGist concentra snippets versionados en un único contenedor. La ruta `OPENGIST_DATA_PATH` almacena repositorios, configuración y base de datos, mientras `proxy` proporciona acceso HTTPS.
## Configuración
- `OPENGIST_DOMAIN` se usa como URL externa y debe coincidir con el dominio de Traefik.
- `OPENGIST_OIDC_PROVIDER_NAME` define el texto mostrado al iniciar sesión.
- `OPENGIST_OIDC_CLIENT_ID`, `OPENGIST_OIDC_CLIENT_SECRET` y `OPENGIST_OIDC_DISCOVERY_URL` conectan Authentik mediante discovery OIDC.
- `OPENGIST_DATA_PATH` debe ser escribible por el contenedor y estar incluido en las copias de seguridad.
- `TRAEFIK_DOCKER_NETWORK` debe apuntar a `proxy` para que Traefik elija la interfaz correcta.
OIDC centraliza identidad, pero los permisos sobre cada gist siguen administrándose en OpenGist.
## Requisitos
- Docker Compose
+30 -28
View File
@@ -1,40 +1,42 @@
# Open WebUI — Interfaz web para LLMs
# Open WebUI
Open WebUI conectado al stack de Ollama. Expone una UI de chat accesible en `chat.sherlockhomeless.net`, protegida por CrowdSec. Tiene su propio sistema de login, no usa Authentik.
Interfaz de chat para los modelos publicados por LiteLLM. Ollama está deshabilitado explícitamente; este despliegue usa únicamente la API compatible con OpenAI.
## Prerequisitos
## Arquitectura
- Stack **Ollama** desplegado y en la red `proxy`
- DNS + Tunnel registrado para `chat.sherlockhomeless.net`
Open WebUI se une a `proxy`, desde donde Traefik lo publica y puede alcanzar `litellm:4000`. Los chats, usuarios y ajustes se guardan en `OPENWEBUI_DATA_PATH`.
```bash
cd cloudflared
./add-domain.sh chat
```
## Configuración
| Variable | Uso |
| --- | --- |
| `OPENAI_API_BASE_URL` | `http://litellm:4000/v1` para tráfico interno |
| `OPENAI_API_KEY` | Valor de `LITELLM_MASTER_KEY`, no una credencial de Codex |
| `WEBUI_SECRET_KEY` | Firma sesiones; debe ser aleatoria y estable |
| `OPENWEBUI_DOMAIN`, `WEBUI_URL` | URL pública detrás de Traefik |
| `ENABLE_SIGNUP` | Debe desactivarse salvo durante un alta controlada |
| `ENABLE_LOGIN_FORM` | Mantiene o elimina el login local según la estrategia SSO |
| `WEBUI_AUTH_TRUSTED_*_HEADER` | Cabeceras de identidad entregadas por el proxy autenticado |
Las cabeceras de usuario sólo son seguras si Open WebUI no puede alcanzarse evitando Traefik y si el proxy elimina cualquier cabecera equivalente enviada por el cliente. `WEBUI_SECRET_KEY` no debe cambiarse en cada recreación porque invalidaría sesiones.
## Relación con Codex
Open WebUI nunca monta ni lee `auth.json`. Envía una petición OpenAI-compatible a LiteLLM; LiteLLM valida su clave, selecciona el alias y, si corresponde, usa su proveedor Codex. Esto limita la exposición del refresh token a un único contenedor.
## Despliegue
```bash
mkdir -p /opt/openwebui/data
# Editar openwebui/.env: cambiar WEBUI_SECRET_KEY por un valor aleatorio
openssl rand -hex 32
docker compose --env-file openwebui/.env -f openwebui/docker-compose.yml up -d
cd openwebui
docker compose --env-file .env config
docker compose --env-file .env up -d
```
## Primer acceso
## Verificación
La primera cuenta registrada se convierte en administrador. Después de crearla, pon `ENABLE_SIGNUP=false` en `.env` y redespliega para bloquear nuevos registros.
```bash
docker compose --env-file .env ps
docker compose --env-file .env logs -f openwebui
```
## Conexión con Ollama
OpenWebUI se conecta a Ollama via red interna Docker: `http://ollama:11434`.
Ambos contenedores deben estar en la red `proxy`.
## Variables clave
| Variable | Descripción |
|----------|-------------|
| `WEBUI_SECRET_KEY` | Clave para firmar sesiones — generar con `openssl rand -hex 32` |
| `OLLAMA_BASE_URL` | URL interna de Ollama (`http://ollama:11434`) |
| `ENABLE_SIGNUP` | `false` para bloquear nuevos registros |
| `WEBUI_NAME` | Nombre mostrado en la interfaz |
Si no aparecen modelos, prueba primero `/v1/models` contra LiteLLM con la misma clave. Si los modelos aparecen pero fallan sólo los alias Codex, revisa el montaje y renovación de `auth.json` en LiteLLM.
+81 -10
View File
@@ -1,14 +1,83 @@
# Paperless-ngx
Gestión documental con PostgreSQL, Redis, Tika y Gotenberg. El despliegue también incluye Paperless AI y una sincronización unidireccional desde una carpeta de Nextcloud.
Paperless-ngx convierte documentos en un archivo digital consultable. Importa ficheros, extrae texto, ejecuta OCR, clasifica metadatos y conserva el original junto con su versión procesada.
## Requisitos
## Qué despliega
- Docker Compose
- Redes externas `proxy` y `mail_internal`
- Un archivo `.env` local con dominios, credenciales, correo, proxy de confianza y acceso WebDAV a Nextcloud
- Directorios persistentes bajo `/opt/paperless`, `/opt/paperless-ai` y `/opt/rclone`
- Script `/opt/paperless/rclone-sync.sh`
- `paperless`: aplicación principal y consumidor de documentos.
- `paperless-db`: PostgreSQL para metadatos.
- `paperless-redis`: cola y caché.
- `paperless-tika`: extracción de texto de formatos Office y similares.
- `paperless-gotenberg`: conversión de documentos a PDF.
- `paperless-ai`: clasificación y enriquecimiento asistido por un LLM.
- `paperless-inbox-sync`: copia periódica desde una carpeta WebDAV de Nextcloud hacia `consume`.
Los servicios de datos viven en `paperless_internal`. Paperless y Paperless AI también se unen a `proxy` para ser alcanzables por Traefik y por servicios compartidos como LiteLLM.
## Configuración principal
El `.env` local agrupa:
| Grupo | Variables principales | Por qué existe |
| --- | --- | --- |
| PostgreSQL | `PAPERLESS_DBNAME`, `PAPERLESS_DBUSER`, `PAPERLESS_DBPASS` | Conserva índices, usuarios y metadatos |
| URL y seguridad | `PAPERLESS_DOMAIN`, `PAPERLESS_SECRET_KEY`, `PAPERLESS_ALLOWED_HOSTS`, `TRUSTED_PROXIES` | Genera enlaces correctos y valida peticiones tras Traefik |
| Administrador | `PAPERLESS_ADMIN_USER`, `PAPERLESS_ADMIN_PASSWORD`, `PAPERLESS_ADMIN_MAIL` | Crea el usuario inicial; cambia la contraseña tras el alta |
| Correo | variables `PAPERLESS_EMAIL_*` | Notificaciones mediante `mail_internal` |
| Nextcloud | `NC_DOMAIN`, `NC_WEBDAV_USER`, `NC_WEBDAV_PASS` | Lee la bandeja de entrada remota |
| Sincronización | `RCLONE_SYNC_INTERVAL`, `PAPERLESS_INBOX_DIR` | Controla frecuencia y carpeta origen |
`PAPERLESS_CONSUMER_POLLING` hace la importación más fiable cuando los archivos llegan por sincronización o montaje y no generan eventos `inotify` normales.
## Persistencia
| Ruta | Contenido |
| --- | --- |
| `/opt/paperless/pgdata` | PostgreSQL |
| `/opt/paperless/data` | Índices y estado de Paperless |
| `/opt/paperless/media` | Originales y documentos procesados |
| `/opt/paperless/export` | Exportaciones |
| `/opt/paperless/consume` | Bandeja de importación |
| `/opt/paperless-ai/data` | Configuración y estado de Paperless AI |
| `/opt/rclone` | Configuración auxiliar de rclone |
La copia de seguridad debe mantener coherencia entre PostgreSQL, `data` y `media`. Respaldar sólo la base de datos no conserva los documentos.
## Integración de Paperless AI con LiteLLM y Codex
Paperless AI no se conecta directamente a Codex. Se configura como cliente compatible con OpenAI y llama a LiteLLM:
```text
API provider: OpenAI compatible
Base URL: http://litellm:4000/v1
API key: valor de LITELLM_MASTER_KEY
Model: gpt-5.6-sol
```
Ambos contenedores comparten la red externa `proxy`, por lo que `litellm` se resuelve por DNS interno. La configuración de Paperless AI se guarda en `/opt/paperless-ai/data`; actualmente no se declara mediante variables en el Compose y debe introducirse desde su interfaz.
Flujo de una clasificación:
```text
Paperless -> Paperless AI -> LiteLLM -> proveedor Codex -> Codex
```
Esta arquitectura es intencionada:
- `auth.json` y el refresh token de Codex permanecen sólo en LiteLLM.
- Paperless AI recibe una clave de LiteLLM revocable, no la sesión de Codex.
- El alias de modelo puede cambiar de proveedor sin reconfigurar Paperless AI.
- LiteLLM centraliza control, logs y futuros límites de consumo.
No montes `/home/felidae/.codex/auth.json` en Paperless AI. Tampoco uses el dominio público de LiteLLM desde Docker salvo que necesites atravesar Traefik; la URL interna evita una vuelta innecesaria por DNS público y TLS.
Antes de activar clasificación automática, prueba con pocos documentos y revisa qué contenido se envía al modelo. Los documentos pueden contener datos personales o confidenciales.
## Sincronización desde Nextcloud
`paperless-inbox-sync` usa WebDAV y el script `/opt/paperless/rclone-sync.sh` para copiar la carpeta configurada hacia `/consume`. Es un flujo unidireccional; comprueba el comportamiento exacto del script antes de cambiarlo por una sincronización con borrado.
La contraseña WebDAV debe ser una contraseña de aplicación dedicada, con el mínimo acceso necesario. No uses la contraseña principal del usuario de Nextcloud.
## Despliegue
@@ -18,11 +87,13 @@ docker compose --env-file .env config
docker compose --env-file .env up -d
```
## Operación
## Verificación y operación
```bash
docker compose --env-file .env ps
docker compose --env-file .env logs -f paperless paperless-ai paperless-inbox-sync
docker compose --env-file .env logs -f paperless
docker compose --env-file .env logs -f paperless-ai
docker compose --env-file .env logs -f paperless-inbox-sync
```
La sincronización copia documentos desde Nextcloud a `/opt/paperless/consume`; revisa sus logs antes de cambiar rutas o credenciales WebDAV.
Comprueba que PostgreSQL, Redis, Tika y Gotenberg estén sanos antes de diagnosticar la aplicación. Si no entran documentos, revisa primero el sync, después `/opt/paperless/consume` y finalmente los logs del consumidor.
+13
View File
@@ -2,6 +2,19 @@
Servicio self-hosted para manipular PDF.
## Qué hace y configuración
Stirling PDF combina, divide, convierte, firma y transforma documentos desde una interfaz web. `SECURITY_ENABLELOGIN=false` deja la autenticación en Traefik + Authentik; no debe publicarse una ruta alternativa que evite ese middleware.
- `STIRLING_PDF_IMAGE` fija la versión.
- `STIRLING_PDF_DOMAIN` define el dominio público.
- `STIRLING_PDF_CONFIG_PATH` guarda configuración.
- `STIRLING_PDF_CUSTOM_PATH` contiene personalización.
- `STIRLING_PDF_LOGS_PATH` conserva logs y debe tener rotación.
- `STIRLING_PDF_PIPELINE_PATH` guarda automatizaciones.
Los documentos procesados pueden ser confidenciales. Revisa retención de temporales, permisos de los volúmenes y evita registrar nombres o contenido sensible.
- URL: `https://pdf.sherlockhomeless.net/`
- Contenedor: `stirling-pdf`
- Datos persistentes: `/opt/stirling-pdf/`
+14
View File
@@ -2,6 +2,20 @@
Pastebin con cifrado de extremo a extremo en el navegador, ejecutado en modo de sólo lectura y publicado mediante Traefik.
## Arquitectura y propósito
PrivateBin cifra y descifra en el navegador: el servidor almacena ciphertext, no el texto claro. El contenedor tiene sistema raíz de sólo lectura, usuario sin privilegios y únicamente escribe en `PRIVATEBIN_DATA_PATH`.
## Configuración
- `PRIVATEBIN_DOMAIN` define la URL expuesta por Traefik.
- `PRIVATEBIN_IMAGE` debe fijarse a una versión revisada para evitar cambios inesperados.
- `PRIVATEBIN_DATA_PATH` conserva los pastes cifrados y necesita permisos para UID/GID `65534`.
- `nginx-site.conf` separa las operaciones públicas de lectura de las rutas de creación/borrado protegidas por autenticación externa.
- `TRAEFIK_DOCKER_NETWORK` debe coincidir con la red `proxy` existente.
El cifrado del navegador no protege metadatos, disponibilidad ni clientes comprometidos. Mantén TLS y revisa la política de expiración.
## Requisitos
- Docker Compose
+13
View File
@@ -2,6 +2,19 @@
Proveedor de arranque bajo demanda para servicios Docker. Se conecta al socket de Docker y a la red externa `proxy`.
## Arquitectura y propósito
Sablier recibe peticiones desde el middleware correspondiente y arranca contenedores que estaban detenidos, permitiendo reducir consumo de servicios esporádicos. La versión se controla con `SABLIER_VERSION`.
## Configuración
- La red `proxy` permite comunicación con Traefik y los servicios activables.
- El socket Docker se monta en sólo lectura, pero sigue otorgando capacidad de inspección y control significativo sobre el host.
- Los servicios gestionados necesitan sus propias etiquetas/middleware de Sablier y una política de parada coherente.
- No gestiones con Sablier bases de datos u otros componentes con arranque lento sin ajustar timeouts y dependencias.
La etiqueta `prune.protect` debe aplicarse a servicios bajo demanda para que una limpieza no elimine contenedores detenidos que Sablier espera arrancar.
## Requisitos
- Docker Compose
+15
View File
@@ -2,6 +2,21 @@
Gestor de tareas y proyectos con PostgreSQL, soporte CalDAV y envío de recordatorios por correo.
## Arquitectura y propósito
`vikunja` ofrece interfaz, API y CalDAV; `vikunja-db` guarda usuarios, proyectos y tareas. PostgreSQL sólo está en `vikunja_internal`; Vikunja se conecta además a `proxy` y `mail_internal`.
## Configuración
- `VIKUNJA_DOMAIN` forma `VIKUNJA_SERVICE_PUBLICURL`; incluye HTTPS y la barra final esperada.
- `VIKUNJA_JWT_SECRET` firma sesiones. Debe ser aleatorio, exclusivo y estable.
- `VIKUNJA_DB_*` debe coincidir en aplicación, healthcheck y PostgreSQL.
- Las variables `VIKUNJA_MAILER_*` configuran SMTP y recordatorios.
- El registro público está desactivado; crea usuarios de forma administrativa.
- `/opt/vikunja/files` guarda adjuntos y `/opt/vikunja/postgres` la base; ambos son necesarios para una restauración completa.
CalDAV está activado para clientes externos; publica siempre mediante HTTPS y revoca credenciales de clientes perdidos.
## Requisitos
- Docker Compose