- HTML 58.3%
- Python 41%
- Dockerfile 0.7%
|
All checks were successful
Build and push RSS feed images / build-scorer (push) Successful in 2m25s
Build and push RSS feed images / build-collector (push) Successful in 2m37s
Build and push RSS feed images / build-frontend (push) Successful in 2m39s
Build and push RSS feed images / deploy (push) Successful in 44s
|
||
|---|---|---|
| .forgejo/workflows | ||
| android | ||
| base | ||
| feedback | ||
| ingestion | ||
| presentation | ||
| scoring | ||
| users/eric | ||
| .gitignore | ||
| README.md | ||
RSS Algorithmic Feed
Self-hosted, algorithmic RSS feed running on k3s. Scores articles by cosine similarity to your reading history + LLM relevance judgement against an editable interest profile + implicit dwell/scroll signals.
Configuration
| Setting | Value |
|---|---|
| Namespace | rss |
| Ollama | On-cluster, CPU only |
| TLS | cert-manager + Let's Encrypt (letsencrypt-prod) |
| Miniflux | https://rss.ignohr.com |
| Frontend | https://feed.ignohr.com |
| Storage | CephRBD (ceph-rbd storageClass) |
RSS sources → Miniflux (rss.ignohr.com)
→ RSSHub (non-native RSS)
→ Mercury Parser (full-text)
↓
Scorer service (Python)
↕ ↕
Ollama Postgres+pgvector
(embeddings) (scores + vectors)
↓
Feedback collector (FastAPI)
↕ events
Frontend SPA (feed.ignohr.com)
Deployment order
1. Secrets (manual, don't commit)
# Edit base/secrets.yaml with real values first
kubectl apply -f base/namespace.yaml
kubectl apply -f base/secrets.yaml
2. Ingestion layer
kubectl apply -f ingestion/postgres.yaml
# Wait for postgres to be ready
kubectl rollout status statefulset/miniflux-postgres -n rss
kubectl apply -f ingestion/miniflux.yaml
kubectl apply -f ingestion/rsshub.yaml
kubectl apply -f ingestion/mercury-parser.yaml
Open rss.ignohr.com, log in, and:
- Add your RSS feeds
- Go to Settings → API Keys → Create an API key
- Update scorer-secrets with the key:
kubectl edit secret scorer-secrets -n rss
3. Scoring layer
# Option A: Ollama on cluster (CPU)
kubectl apply -f scoring/ollama.yaml
# Wait for init container to pull nomic-embed-text (~270MB)
kubectl logs -f deployment/ollama -n rss -c pull-models
# Option B: Ollama on workstation — edit scoring/ollama.yaml,
# delete the StatefulSet/Deployment and uncomment the ExternalName Service
# Build and push scorer image
cd scoring/scorer-app
docker build -t gitea.ignohr.com/isaac/rss-scorer:latest .
docker push gitea.ignohr.com/isaac/rss-scorer:latest
cd ../..
kubectl apply -f scoring/scorer.yaml
kubectl logs -f deployment/scorer -n rss
4. Feedback layer
cd feedback
docker build -t gitea.ignohr.com/isaac/rss-feedback-collector:latest .
docker push gitea.ignohr.com/isaac/rss-feedback-collector:latest
cd ..
kubectl apply -f feedback/collector.yaml
5. Frontend
cd presentation
docker build -t gitea.ignohr.com/isaac/rss-frontend:latest .
docker push gitea.ignohr.com/isaac/rss-frontend:latest
cd ..
kubectl apply -f presentation/frontend.yaml
Open feed.ignohr.com. Articles will appear after the first scorer run (~2 min).
First-run bootstrap
Before you have liked articles, scoring falls back to the interest profile. Open feed.ignohr.com → "Interest profile" → describe what you care about. Example:
Self-hosted infrastructure, Kubernetes, Linux kernel development, AI/ML research (especially local inference), homelab, open source tooling. Not interested in crypto, celebrity news, marketing.
After thumbing 10+ articles, the embedding centroid kicks in and the profile becomes less important.
Tuning
Edit JUDGE_MODEL in scoring/scorer.yaml:
""— LLM judge disabled; pure embedding similarity + profile (fastest)"qwen2.5:1.5b"— fast, decent quality"qwen2.5:7b"— better quality, ~10s/article on CPU
Edit score weights in scoring/scorer-app/main.py → compute_final_score().
pgvector schema
All data lives in the rss namespace Postgres instance:
article_scores— entry embeddings + scorespreference_vectors— liked/disliked centroidsinterest_profile— editable profile textreading_events— raw implicit feedback events
# Connect to postgres directly
kubectl exec -it statefulset/miniflux-postgres -n rss -- psql -U miniflux miniflux
Resource footprint (approximate)
| Component | CPU req | RAM req |
|---|---|---|
| miniflux-postgres | 100m | 256Mi |
| miniflux | 50m | 64Mi |
| rsshub | 50m | 128Mi |
| mercury-parser | 50m | 64Mi |
| ollama (CPU) | 200m | 512Mi |
| scorer | 50m | 128Mi |
| feedback-collector | 25m | 64Mi |
| rss-frontend | 10m | 16Mi |
| Total | 535m | 1.2Gi |
.gitignore
base/secrets.yaml