Files
thomasandClaude ce844412e5 Jobsuche: Agent pro Benutzer in isoliertem Docker-Container
Jeder Suchlauf läuft nun in einem frischen Container pro Benutzer, dessen
pro-Benutzer-Home als ~/.claude gemountet ist — Memories und Session-Contexte
liegen damit strikt getrennt pro Benutzer. Die Such-Skills sind Shared-Code
aus dem Image und werden im Container nur nach ~/.claude/skills verlinkt.

Der Host-Runner startet pro Lauf `docker run --rm` und führt bis zu
JOBSUCHE_MAX_PARALLEL (Default 4) Läufe parallel über verschiedene Benutzer
aus (jeder hat eigenen Ollama-Key = getrennte Rate-Limits). Der alte gemeinsame
~/.claude-Pfad wird vom Runner nicht mehr beschrieben.

- source/agent/: neues Agent-Image (Dockerfile + entrypoint + drei Skills)
- scripts/jobsuche-runner.js: agentStarten als docker run, ensureAgentDir, runPool
- scripts/jobsuche-runner.sh + bin/-Kopie: Image-Guard
- package.json: docker:build-agent (lokal, ohne Registry-Push)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-14 15:41:22 +02:00

72 lines
2.9 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# Cron-Einstiegspunkt für die Jobsuche (Multi-User).
#
# Ersetzt jobsuche-cron.sh + jobsuche-remote-cron.sh: Diese beiden hatten das
# Suchprofil (sieben Städte, Rollen, Buzzwords) fest im Prompt stehen und liefen
# mit EINEM globalen API-Token aus der .env — beides ist mit der Multi-User-
# Plattform hinfällig.
#
# Jetzt: Jeder Benutzer pflegt sein Suchprofil und seinen Zeitplan in der App
# (/jobsuche). Dieses Skript ruft nur noch den Runner auf, der fällige und manuell
# angeforderte Läufe abarbeitet — je Benutzer mit dessen eigenem Ollama- und
# API-Schlüssel. Jeder Suchlauf läuft isoliert im eigenen Docker-Container pro
# Benutzer; der Runner selbst bleibt auf dem Host (Docker-CLI + DB-Zugriff).
#
# Cron (alle 5 Minuten — die Uhrzeit steuert der Benutzer, nicht der Cron):
# */5 * * * * /opt/jobbi-bewerbung/bin/jobsuche-runner.sh
#
# Manueller Lauf: /opt/jobbi-bewerbung/bin/jobsuche-runner.sh
set -uo pipefail
export HOME="${HOME:-/root}"
export PATH="/root/.local/bin:/usr/local/bin:/usr/bin:/bin:$PATH"
# Node läuft unter nvm — der Cron-Pfad kennt das Verzeichnis nicht, also nvm
# laden, damit `node` (und der Default-Node des Benutzers) gefunden wird. Ohne
# das schlug jeder Cron-Tick mit `node: command not found` fehl und die
# wartenden Suchläufe blieben ewig im Status 'angefordert' hängen.
export NVM_DIR="${NVM_DIR:-$HOME/.nvm}"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
PROJECT_DIR="/opt/jobbi-bewerbung"
LOG_DIR="$PROJECT_DIR/logs"
RUNNER="$PROJECT_DIR/source/scripts/jobsuche-runner.js"
# Agent-Image (pro Suchlauf ein frischer Container). Wird lokal gebaut:
# npm --prefix "$PROJECT_DIR/source" run docker:build-agent
AGENT_IMAGE="${JOBSUCHE_AGENT_IMAGE:-jobbi-bewerbung-agent:latest}"
mkdir -p "$LOG_DIR"
LOG="$LOG_DIR/jobsuche-runner.log"
# Einzelinstanz: ein noch laufender Suchlauf darf vom nächsten Cron-Tick nicht
# ein zweites Mal gestartet werden.
exec 9>"$LOG_DIR/jobsuche-runner.lock"
if ! flock -n 9; then
exit 0
fi
cd "$PROJECT_DIR" || exit 1
# API-Erreichbarkeit prüfen — ohne den Tracker kann der Agent nichts importieren.
if ! curl -fsS --max-time 10 http://localhost:4327/api/v1/health >/dev/null 2>&1; then
echo "$(date -Is) FEHLER: NextJobs (localhost:4327) nicht erreichbar Lauf übersprungen." >> "$LOG"
exit 1
fi
# Agent-Image muss vorhanden sein, sonst stapeln sich fehlgeschlagene Läufe.
if ! docker image inspect "$AGENT_IMAGE" >/dev/null 2>&1; then
echo "$(date -Is) FEHLER: Agent-Image '$AGENT_IMAGE' fehlt bitte bauen: npm --prefix $PROJECT_DIR/source run docker:build-agent" >> "$LOG"
exit 1
fi
node "$RUNNER" >> "$LOG" 2>&1
STATUS=$?
# Log der Runner-Steuerung kurz halten (die eigentlichen Suchlauf-Logs liegen
# je Lauf separat und werden vom Runner selbst rotiert).
if [ -f "$LOG" ] && [ "$(wc -l < "$LOG")" -gt 5000 ]; then
tail -n 2000 "$LOG" > "$LOG.tmp" && mv "$LOG.tmp" "$LOG"
fi
exit $STATUS