reddit-intel: retirar los manifiestos, el proyecto queda decomisado
Reddit nos ha denegado el acceso a la API —la misma respuesta que a roswell-corpus—, así que la promoción a k3s que describía PROMOTION.md no va a ocurrir nunca. Estos manifiestos nunca llegaron a aplicarse (el app-of-apps no es recursivo y no había Application), así que quitarlos no cambia nada en el clúster; el namespace vacío se ha borrado a mano. El contenedor de n97 se paró el 2026-07-27 tras once días devolviendo 401, con la base de datos vacía: nunca registró un solo post. Copia final en ~/decommissioned/reddit-intel-final-2026-07-27.tar.gz y el código sigue en su repo. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,61 +0,0 @@
|
|||||||
# reddit-intel — promoción de docker compose (n97) a k3s
|
|
||||||
|
|
||||||
Estado: **INACTIVO**. Los manifiestos de este directorio existen solo en git;
|
|
||||||
el app-of-apps `k8s-manifests` no es recursivo, así que ArgoCD no los
|
|
||||||
sincroniza. La app corre en docker compose en chemavx-n97
|
|
||||||
(`/opt/reddit-intel`, semana de calibración desde 2026-07-06).
|
|
||||||
|
|
||||||
## Checklist de activación (en este orden)
|
|
||||||
|
|
||||||
1. **Imagen en el registro.** Primer build manual, o `workflow_dispatch` del
|
|
||||||
workflow "Build reddit-intel image" en el repo
|
|
||||||
`git.chemavx.xyz/chemavx/reddit-intel` (requiere secrets `CI_TOKEN` y
|
|
||||||
`TELEGRAM_BOT_TOKEN` configurados en ese repo). El workflow actualiza el
|
|
||||||
tag de `deployment.yaml` aquí; si el build es manual, sustituir el
|
|
||||||
placeholder `:00000000` a mano por el sha8 real.
|
|
||||||
|
|
||||||
2. **Secrets en Infisical** (proyecto "homelab", env `prod`, path
|
|
||||||
`/reddit-intel`) — mismos valores que el `.env` del compose:
|
|
||||||
`reddit-client-id`, `reddit-client-secret`, `llm-api-key`,
|
|
||||||
`dashboard-auth-token`, `telegram-bot-token`, `telegram-chat-id`
|
|
||||||
(los dos de telegram pueden ir vacíos).
|
|
||||||
|
|
||||||
3. **Congelar el compose y copiar la BD al PVC:**
|
|
||||||
```bash
|
|
||||||
# en n97
|
|
||||||
cd /opt/reddit-intel && docker compose down # para la app (checkpoint WAL limpio)
|
|
||||||
/opt/reddit-intel/scripts/backup.sh # backup final pre-migración
|
|
||||||
|
|
||||||
# activar la app (crea PVCs y arranca el pod con BD vacía)
|
|
||||||
kubectl apply -f reddit-intel/argocd-app.yaml
|
|
||||||
kubectl -n reddit-intel rollout status deploy/reddit-intel
|
|
||||||
|
|
||||||
# parar el pod y volcar la BD del host al PVC
|
|
||||||
kubectl -n reddit-intel scale deploy/reddit-intel --replicas=0
|
|
||||||
kubectl -n reddit-intel run pvc-loader --image=busybox --restart=Never \
|
|
||||||
--overrides='{"spec":{"nodeSelector":{"kubernetes.io/hostname":"chemavx-n97"},"containers":[{"name":"pvc-loader","image":"busybox","command":["sleep","600"],"volumeMounts":[{"name":"data","mountPath":"/data"}]}],"volumes":[{"name":"data","persistentVolumeClaim":{"claimName":"reddit-intel-data"}}]}}'
|
|
||||||
kubectl -n reddit-intel wait --for=condition=Ready pod/pvc-loader
|
|
||||||
kubectl -n reddit-intel cp /opt/reddit-intel/data/reddit-intel.db pvc-loader:/data/reddit-intel.db
|
|
||||||
kubectl -n reddit-intel delete pod pvc-loader
|
|
||||||
kubectl -n reddit-intel scale deploy/reddit-intel --replicas=1
|
|
||||||
```
|
|
||||||
(El `docker compose down` previo garantiza que no hay `-wal`/`-shm`
|
|
||||||
pendientes: basta copiar el `.db`.)
|
|
||||||
|
|
||||||
4. **Verificar:** `kubectl -n reddit-intel logs deploy/reddit-intel` debe
|
|
||||||
mostrar `scheduler_start jobs=monitor,detector,analyzer,karma,learning`;
|
|
||||||
el dashboard responde vía `svc/reddit-intel` (port-forward o el ingress
|
|
||||||
que se decida — pendiente de elegir exposición).
|
|
||||||
|
|
||||||
5. **Desmantelar la fase compose:** quitar la línea del crontab de chemavx en
|
|
||||||
n97 (el CronJob `reddit-intel-db-backup` de aquí la reemplaza) y archivar
|
|
||||||
`/opt/reddit-intel` cuando la semana de convivencia confirme que todo va bien.
|
|
||||||
|
|
||||||
## Notas
|
|
||||||
|
|
||||||
- El CronJob de backup (`backup-cronjob.yaml`) replica el patrón researchowl:
|
|
||||||
`sqlite3 .backup` + `integrity_check` + retención 7, contra el PVC.
|
|
||||||
- Un solo replica siempre (`strategy: Recreate`): SQLite WAL + APScheduler
|
|
||||||
in-process no admiten dos pods.
|
|
||||||
- El namespace `reddit-intel` ya existe en el clúster (creado durante la
|
|
||||||
preparación); `CreateNamespace=true` lo cubre igualmente.
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
# INACTIVO hasta la promoción: el app-of-apps k8s-manifests NO es recursivo,
|
|
||||||
# así que este fichero solo existe en git — nadie lo aplica automáticamente.
|
|
||||||
# La activación es manual: ver PROMOTION.md en este directorio.
|
|
||||||
apiVersion: argoproj.io/v1alpha1
|
|
||||||
kind: Application
|
|
||||||
metadata:
|
|
||||||
name: reddit-intel
|
|
||||||
namespace: argocd
|
|
||||||
annotations:
|
|
||||||
notifications.argoproj.io/subscribe.on-sync-failed.telegram: "5138407666"
|
|
||||||
notifications.argoproj.io/subscribe.on-health-degraded.telegram: "5138407666"
|
|
||||||
spec:
|
|
||||||
project: default
|
|
||||||
source:
|
|
||||||
repoURL: https://git.chemavx.xyz/chemavx/k8s-manifests
|
|
||||||
targetRevision: HEAD
|
|
||||||
path: reddit-intel
|
|
||||||
destination:
|
|
||||||
server: https://kubernetes.default.svc
|
|
||||||
namespace: reddit-intel
|
|
||||||
syncPolicy:
|
|
||||||
automated:
|
|
||||||
prune: true
|
|
||||||
selfHeal: true
|
|
||||||
syncOptions:
|
|
||||||
- CreateNamespace=true
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: PersistentVolumeClaim
|
|
||||||
metadata:
|
|
||||||
annotations:
|
|
||||||
# Never let ArgoCD prune this PVC: it holds the DB backups.
|
|
||||||
argocd.argoproj.io/sync-options: Prune=false
|
|
||||||
name: reddit-intel-backups
|
|
||||||
namespace: reddit-intel
|
|
||||||
spec:
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteOnce
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
storage: 2Gi
|
|
||||||
|
|
||||||
---
|
|
||||||
apiVersion: batch/v1
|
|
||||||
kind: CronJob
|
|
||||||
metadata:
|
|
||||||
name: reddit-intel-db-backup
|
|
||||||
namespace: reddit-intel
|
|
||||||
labels:
|
|
||||||
app: reddit-intel
|
|
||||||
spec:
|
|
||||||
schedule: "0 3 * * *"
|
|
||||||
timeZone: "Europe/Madrid"
|
|
||||||
concurrencyPolicy: Forbid
|
|
||||||
successfulJobsHistoryLimit: 3
|
|
||||||
failedJobsHistoryLimit: 3
|
|
||||||
jobTemplate:
|
|
||||||
spec:
|
|
||||||
backoffLimit: 2
|
|
||||||
activeDeadlineSeconds: 600
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: reddit-intel-db-backup
|
|
||||||
spec:
|
|
||||||
restartPolicy: Never
|
|
||||||
containers:
|
|
||||||
- name: backup
|
|
||||||
image: keinos/sqlite3:latest
|
|
||||||
command:
|
|
||||||
- /bin/sh
|
|
||||||
- -c
|
|
||||||
- |
|
|
||||||
set -eu
|
|
||||||
STAMP=$(date +%Y%m%d)
|
|
||||||
DEST="/backups/reddit-intel-${STAMP}.db"
|
|
||||||
echo "Backing up /data/reddit-intel.db -> ${DEST}"
|
|
||||||
sqlite3 -cmd ".timeout 30000" /data/reddit-intel.db ".backup '${DEST}'"
|
|
||||||
RESULT=$(sqlite3 "${DEST}" "PRAGMA integrity_check;")
|
|
||||||
if [ "${RESULT}" != "ok" ]; then
|
|
||||||
echo "Integrity check FAILED: ${RESULT}"
|
|
||||||
rm -f "${DEST}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "Integrity check ok"
|
|
||||||
# Retention: keep the 7 most recent backups
|
|
||||||
for f in $(ls -1t /backups/reddit-intel-*.db | tail -n +8); do
|
|
||||||
echo "Pruning old backup ${f}"
|
|
||||||
rm -f "${f}"
|
|
||||||
done
|
|
||||||
ls -lh /backups/
|
|
||||||
volumeMounts:
|
|
||||||
# NOT readOnly: the source DB runs in WAL mode and sqlite readers
|
|
||||||
# must be able to touch the -shm/-wal sidecar files. The job only
|
|
||||||
# ever reads the DB (.backup); it never modifies application data.
|
|
||||||
- name: data
|
|
||||||
mountPath: /data
|
|
||||||
- name: backups
|
|
||||||
mountPath: /backups
|
|
||||||
volumes:
|
|
||||||
- name: data
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: reddit-intel-data
|
|
||||||
- name: backups
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: reddit-intel-backups
|
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Namespace
|
|
||||||
metadata:
|
|
||||||
name: reddit-intel
|
|
||||||
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: PersistentVolumeClaim
|
|
||||||
metadata:
|
|
||||||
annotations:
|
|
||||||
# Never let ArgoCD prune this PVC: it holds the SQLite DB.
|
|
||||||
argocd.argoproj.io/sync-options: Prune=false
|
|
||||||
name: reddit-intel-data
|
|
||||||
namespace: reddit-intel
|
|
||||||
spec:
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteOnce
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
storage: 2Gi
|
|
||||||
|
|
||||||
---
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: reddit-intel
|
|
||||||
namespace: reddit-intel
|
|
||||||
labels:
|
|
||||||
app: reddit-intel
|
|
||||||
spec:
|
|
||||||
replicas: 1
|
|
||||||
# Single-replica app on a RWO local-path SQLite DB (WAL) with an in-process
|
|
||||||
# APScheduler: Recreate avoids two pods briefly sharing /data/reddit-intel.db.
|
|
||||||
strategy:
|
|
||||||
type: Recreate
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: reddit-intel
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: reddit-intel
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: reddit-intel
|
|
||||||
# Placeholder tag: el workflow manual (repo reddit-intel) lo sustituye
|
|
||||||
# por el sha8 real en cada build. Ver PROMOTION.md.
|
|
||||||
image: git.chemavx.xyz/chemavx/reddit-intel:00000000
|
|
||||||
imagePullPolicy: Always
|
|
||||||
ports:
|
|
||||||
- containerPort: 8080
|
|
||||||
env:
|
|
||||||
- name: DB_PATH
|
|
||||||
value: "/data/reddit-intel.db"
|
|
||||||
- name: REDDIT_USERNAME
|
|
||||||
value: "ExclusionZoneUAP"
|
|
||||||
- name: REDDIT_USER_AGENT
|
|
||||||
value: "linux:reddit-intel:v1.0 (by /u/ExclusionZoneUAP)"
|
|
||||||
- name: LLM_PROVIDER
|
|
||||||
value: "anthropic"
|
|
||||||
- name: LLM_MODEL_SCORING
|
|
||||||
value: "claude-haiku-4-5"
|
|
||||||
- name: LLM_MODEL_DRAFTING
|
|
||||||
value: "claude-sonnet-5"
|
|
||||||
- name: DAILY_LLM_BUDGET
|
|
||||||
value: "60"
|
|
||||||
- name: REDDIT_CLIENT_ID
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: reddit-intel-secrets
|
|
||||||
key: reddit-client-id
|
|
||||||
- name: REDDIT_CLIENT_SECRET
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: reddit-intel-secrets
|
|
||||||
key: reddit-client-secret
|
|
||||||
- name: LLM_API_KEY
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: reddit-intel-secrets
|
|
||||||
key: llm-api-key
|
|
||||||
- name: DASHBOARD_AUTH_TOKEN
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: reddit-intel-secrets
|
|
||||||
key: dashboard-auth-token
|
|
||||||
- name: TELEGRAM_BOT_TOKEN
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: reddit-intel-secrets
|
|
||||||
key: telegram-bot-token
|
|
||||||
- name: TELEGRAM_CHAT_ID
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: reddit-intel-secrets
|
|
||||||
key: telegram-chat-id
|
|
||||||
volumeMounts:
|
|
||||||
- name: data
|
|
||||||
mountPath: /data
|
|
||||||
readinessProbe:
|
|
||||||
httpGet:
|
|
||||||
path: /healthz
|
|
||||||
port: 8080
|
|
||||||
initialDelaySeconds: 10
|
|
||||||
livenessProbe:
|
|
||||||
httpGet:
|
|
||||||
path: /healthz
|
|
||||||
port: 8080
|
|
||||||
initialDelaySeconds: 20
|
|
||||||
periodSeconds: 60
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
memory: "128Mi"
|
|
||||||
cpu: "50m"
|
|
||||||
limits:
|
|
||||||
memory: "512Mi"
|
|
||||||
cpu: "500m"
|
|
||||||
volumes:
|
|
||||||
- name: data
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: reddit-intel-data
|
|
||||||
imagePullSecrets:
|
|
||||||
- name: gitea-registry
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
apiVersion: secrets.infisical.com/v1beta1
|
|
||||||
kind: InfisicalStaticSecret
|
|
||||||
metadata:
|
|
||||||
name: gitea-registry
|
|
||||||
namespace: reddit-intel
|
|
||||||
spec:
|
|
||||||
# References the SHARED auth layer in infisical-operator (cross-namespace).
|
|
||||||
infisicalAuthRef:
|
|
||||||
name: infisical-auth
|
|
||||||
namespace: infisical-operator
|
|
||||||
sources:
|
|
||||||
- projectId: 17e98e9d-70f5-43d1-8382-7da818dfcdd0 # project "homelab"
|
|
||||||
environmentSlug: prod
|
|
||||||
secretPath: /registry
|
|
||||||
syncOptions:
|
|
||||||
refreshInterval: 60s
|
|
||||||
targets:
|
|
||||||
- kind: Secret
|
|
||||||
name: gitea-registry
|
|
||||||
namespace: reddit-intel
|
|
||||||
creationPolicy: Owner
|
|
||||||
secretType: kubernetes.io/dockerconfigjson
|
|
||||||
template:
|
|
||||||
engineVersion: v1
|
|
||||||
data:
|
|
||||||
# Reconstruct the docker pull-secret blob from the two discrete /registry fields.
|
|
||||||
.dockerconfigjson: '{"auths":{"git.chemavx.xyz":{"username":"{{ .GITEA_REGISTRY_USERNAME.Value }}","password":"{{ .GITEA_REGISTRY_TOKEN.Value }}","auth":"{{ printf "%s:%s" .GITEA_REGISTRY_USERNAME.Value .GITEA_REGISTRY_TOKEN.Value | encodeBase64 }}"}}}'
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
apiVersion: secrets.infisical.com/v1beta1
|
|
||||||
kind: InfisicalStaticSecret
|
|
||||||
metadata:
|
|
||||||
name: reddit-intel-secrets
|
|
||||||
namespace: reddit-intel
|
|
||||||
spec:
|
|
||||||
# Shared, read-only machine identity (no write grant, no PushSecret).
|
|
||||||
# Source is the /reddit-intel folder. Expected keys (lowercase-hyphenated,
|
|
||||||
# straight passthrough to the deployment's secretKeyRef values):
|
|
||||||
# reddit-client-id, reddit-client-secret, llm-api-key,
|
|
||||||
# dashboard-auth-token, telegram-bot-token, telegram-chat-id
|
|
||||||
# telegram-* pueden crearse vacíos (las notificaciones son opcionales).
|
|
||||||
infisicalAuthRef:
|
|
||||||
name: infisical-auth
|
|
||||||
namespace: infisical-operator
|
|
||||||
sources:
|
|
||||||
- projectId: 17e98e9d-70f5-43d1-8382-7da818dfcdd0 # project "homelab"
|
|
||||||
environmentSlug: prod
|
|
||||||
secretPath: /reddit-intel
|
|
||||||
syncOptions:
|
|
||||||
refreshInterval: 60s
|
|
||||||
targets:
|
|
||||||
- kind: Secret
|
|
||||||
name: reddit-intel-secrets
|
|
||||||
namespace: reddit-intel
|
|
||||||
creationPolicy: Owner
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: reddit-intel
|
|
||||||
namespace: reddit-intel
|
|
||||||
labels:
|
|
||||||
app: reddit-intel
|
|
||||||
spec:
|
|
||||||
selector:
|
|
||||||
app: reddit-intel
|
|
||||||
ports:
|
|
||||||
- name: http
|
|
||||||
port: 80
|
|
||||||
targetPort: 8080
|
|
||||||
Reference in New Issue
Block a user