Files
homelab/k8s/apps/paperless/paperless-ai.yaml
T
rock d826510a98 feat(paperless-ai): configure for production with Paperless API + LLM integration
- Add ConfigMap with production paperless-ai config
- Mount .env config file for app startup
- Enable auto-tagging, correspondent extraction, document type detection
- Set LLM API endpoint and token file location
- Configure 60s scan interval for document processing
2026-09-15 00:13:02 +09:00

128 lines
4.7 KiB
YAML

# Secret paperless-ai-config managed via SOPS (argocd/secrets/paperless-ai-secrets.enc.yaml)
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: paperless-ai
namespace: paperless
labels:
app.kubernetes.io/name: paperless-ai
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: paperless-ai
template:
metadata:
labels:
app.kubernetes.io/name: paperless-ai
spec:
tolerations:
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
volumes:
- name: paperless-ai-data
persistentVolumeClaim:
claimName: paperless-ai-data
- name: paperless-ai-env-config
configMap:
name: paperless-ai-env
initContainers:
- name: fetch-llm-token
image: curlimages/curl:8.12.0
securityContext:
runAsUser: 0
fsGroup: 0
command:
- sh
- -c
- |
set -e
echo "[init] Fetching JWT token from Authentik for paperless-ai-agent..."
# Get JWT token via client_credentials grant
# Client secret sourced from environment (injected from paperless-ai-config Secret)
TOKEN_RESPONSE=$(curl -s -X POST https://authentik.riotpiao.com/application/o/token/ \
-d "grant_type=client_credentials" \
-d "client_id=paperless-ai-agent" \
-d "client_secret=${LLM_AUTH_CLIENT_SECRET}" \
-d "scope=openid llm:inference" 2>/dev/null)
# Extract token from JSON response using sed (handles spaces after colons)
TOKEN=$(echo "$TOKEN_RESPONSE" | sed -n 's/.*"access_token"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')
if [ -z "$TOKEN" ]; then
echo "[error] Failed to get token. Response: $TOKEN_RESPONSE"
exit 1
fi
# Store token in file for main container to read
# Write to both locations for compatibility
mkdir -p /tmp/llm-token /app/data 2>/dev/null || true
echo "$TOKEN" | tee /tmp/llm-token/llm_token.txt > /dev/null 2>&1
echo "$TOKEN" > /app/data/llm_token.txt 2>/dev/null || true
echo "[init] Token fetched and stored"
[ -f /tmp/llm-token/llm_token.txt ] && echo " -> /tmp/llm-token/llm_token.txt"
[ -f /app/data/llm_token.txt ] && echo " -> /app/data/llm_token.txt"
env:
- name: LLM_AUTH_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: paperless-ai-config
key: LLM_AUTH_CLIENT_SECRET
volumeMounts:
- name: paperless-ai-data
mountPath: /app/data
containers:
- name: paperless-ai
image: clusterzx/paperless-ai:latest
env:
# Paperless-ngx connection
- name: PAPERLESS_API_URL
value: "http://paperless.paperless.svc.cluster.local:8000"
- name: PAPERLESS_API_TOKEN
valueFrom:
secretKeyRef:
name: paperless-ai-config
key: PAPERLESS_API_TOKEN
- name: PAPERLESS_USERNAME
value: "admin"
# LLM API — via public gateway with JWT auth
- name: AI_PROVIDER
value: "custom"
- name: CUSTOM_BASE_URL
value: "https://api.riotpiao.com/v1"
# Token will be read from file at runtime by the application
# The init container fetches it and stores in /app/data/llm_token.txt
- name: CUSTOM_API_KEY_FILE
value: "/app/data/llm_token.txt"
- name: CUSTOM_MODEL
value: "qwen2.5:3b-instruct"
# Behavior - scan for new documents and tag them
- name: SCAN_INTERVAL
value: "60"
- name: PROCESS_PREDEFINED_DOCUMENTS
value: "no"
- name: ADD_AI_TAG
value: "yes"
- name: AI_TAG_NAME
value: "ai-processed"
- name: USE_PROMPT_TAGS
value: "yes"
- name: ADD_AI_DESCRIPTIONS
value: "yes"
volumeMounts:
- name: paperless-ai-data
mountPath: /app/data
- name: paperless-ai-env-config
mountPath: /app/data/.env
subPath: paperless-ai-config.env
resources:
requests:
cpu: 100m
memory: 512Mi
limits:
cpu: "1"
memory: 2Gi