Add JobSync reference card, observability docs, and RAPIDAPI_KEY plumbing (#289)

## Summary
- Add JobSync service reference card (`docs/reference/services/jobsync.md`) with architecture, secrets, observability, and JSearch API docs
- Add JobSync and Ollama to ringtail's workloads table (both were missing)
- Add JobSync to the reference index
- Wire `RAPIDAPI_KEY` through ExternalSecret and deployment env var for JSearch job search automation
- Document Loki log queries for observability (no metrics endpoint exists)
- Update deploy-jobsync how-to with new env var, observability section, and reference card link

## Deployment and Testing
- [ ] Sign up for RapidAPI JSearch API (free tier: 500 req/month)
- [ ] Add `rapidapi_key` field to "JobSync" 1Password item
- [ ] Merge PR
- [ ] `argocd app sync jobsync` to pick up new env var
- [ ] Verify job search works at https://jobsync.ops.eblu.me/dashboard/automations

Reviewed-on: #289
This commit is contained in:
Erich Blume 2026-03-08 15:06:52 -07:00
commit 770a7b2d6a
7 changed files with 130 additions and 1 deletions

View file

@ -0,0 +1 @@
Add JobSync reference card, update ringtail workloads table, document observability via Loki, and wire RAPIDAPI_KEY through ExternalSecret for job search automation.

View file

@ -39,6 +39,7 @@ All in `argocd/manifests/jobsync/`:
| `AUTH_TRUST_HOST` | Hardcoded | `true` |
| `TZ` | Hardcoded | `America/Los_Angeles` |
| `OLLAMA_BASE_URL` | Hardcoded | `http://ollama.ollama.svc.cluster.local:11434` |
| `RAPIDAPI_KEY` | ExternalSecret | JSearch job search API key |
## Updating the Container
@ -50,11 +51,22 @@ See [[build-jobsync-container]] for nix build details.
## Notes
- **1Password item:** "JobSync" in blumeops vault, fields `auth_secret` and `encryption_key`
- **1Password item:** "JobSync" in blumeops vault, fields `auth_secret`, `encryption_key`, and `rapidapi_key`
- **Caddy route:** `jobsync.ops.eblu.me``https://jobsync.tail8d86e.ts.net` (in `ansible/roles/caddy/defaults/main.yml`)
- **`service-versions.yaml`:** Must have a `jobsync` entry or the pre-commit hook rejects container changes
## Observability
JobSync has no metrics endpoint. Logs are collected by Alloy on ringtail and shipped to Loki. Query in Grafana:
```logql
{namespace="jobsync", app="jobsync"}
```
The app runs a scheduled job search daily at 4 AM. Search failures appear in logs during those executions.
## Related
- [[jobsync]] — Service reference card
- [[build-jobsync-container]]
- [[deploy-k8s-service]]

View file

@ -70,6 +70,8 @@ Sync order: `1password-connect-ringtail` -> `external-secrets-crds-ringtail` ->
| Mosquitto | `mqtt` | MQTT broker for Frigate events |
| [[authentik]] | `authentik` | OIDC identity provider |
| [[ntfy]] | `ntfy` | Push notification server |
| [[ollama]] | `ollama` | LLM inference with GPU (RTX 4080) |
| [[jobsync]] | `jobsync` | Job application tracker |
| nvidia-device-plugin | `nvidia-device-plugin` | Exposes GPU to pods via CDI + nvidia RuntimeClass |
### Manual Cluster Registration

View file

@ -25,6 +25,7 @@ Individual service reference cards with URLs and configuration details.
| [[grafana]] | Dashboards & visualization | k8s |
| [[immich]] | Photo management | k8s |
| [[jellyfin]] | Media server | indri |
| [[jobsync]] | Job application tracker | k8s (ringtail) |
| [[kiwix]] | Offline Wikipedia & ZIM archives | k8s |
| [[loki]] | Log aggregation | k8s |
| [[tempo]] | Distributed tracing | k8s |

View file

@ -0,0 +1,104 @@
---
title: JobSync
modified: 2026-03-08
tags:
- service
- job-search
---
# JobSync
Self-hosted job application tracker. Tracks job applications, automates job searching via the JSearch API, and provides AI-powered resume tailoring via [[ollama|Ollama]].
## Quick Reference
| Property | Value |
|----------|-------|
| **URL** | https://jobsync.ops.eblu.me |
| **Tailscale URL** | https://jobsync.tail8d86e.ts.net |
| **Namespace** | `jobsync` |
| **Cluster** | ringtail k3s |
| **Image** | `blumeops/jobsync` (Nix-built) |
| **Upstream** | https://github.com/Gsync/jobsync |
| **Manifests** | `argocd/manifests/jobsync/` |
| **Port** | 3000 |
## Architecture
```
Browser ──HTTPS──► Caddy (jobsync.ops.eblu.me)
Tailscale ProxyGroup
JobSync (Next.js)
┌───────┴───────┐
│ │
SQLite (/data) Ollama (in-cluster)
│ │
PVC 5Gi GPU-accelerated LLM
```
- **Framework:** Next.js 15 + Prisma ORM
- **Database:** SQLite on a 5Gi PVC at `/data`
- **Auth:** Local email/password accounts (NextAuth v5), no SSO
- **AI:** Ollama at `http://ollama.ollama.svc.cluster.local:11434` for resume tailoring
- **Job Search:** JSearch API via RapidAPI (requires `RAPIDAPI_KEY`)
## Job Search (JSearch / RapidAPI)
The automated job search feature uses the [JSearch API](https://rapidapi.com/letscrape-6bRBa3QguO5/api/jsearch) on RapidAPI. The API key can be configured two ways (checked in order):
1. **Per-user:** Added via Settings > API Keys in the web UI (encrypted with `ENCRYPTION_KEY`)
2. **Environment variable:** `RAPIDAPI_KEY` env var as a fallback for all users
Without either, job search automations fail with: `Search failed: network - RAPIDAPI_KEY is not configured`
The free tier allows 200 requests/month. The key is stored in 1Password ("JobSync" item, `rapidapi_key` field) and synced via ExternalSecret.
## Secrets
All secrets are in the **JobSync** 1Password item (blumeops vault), synced by ExternalSecret:
| Secret | 1Password Field | Purpose |
|--------|-----------------|---------|
| `auth_secret` | `auth_secret` | NextAuth session signing |
| `encryption_key` | `encryption_key` | AES-256-GCM for stored API keys |
| `rapidapi_key` | `rapidapi_key` | JSearch job search API |
## Observability
JobSync has no metrics endpoint or Grafana dashboard. Logs are collected by [[alloy|Alloy]] on ringtail and shipped to Loki on indri.
**Querying logs in Grafana:**
```logql
{namespace="jobsync", app="jobsync"}
```
To search for job search errors specifically:
```logql
{namespace="jobsync", app="jobsync"} |~ "(?i)(rapid|search failed|error)"
```
The app runs a scheduled job search daily at 4 AM. Failures appear in logs during those executions.
## Container
Built with Nix on ringtail (x86_64). See [[build-jobsync-container]] for details.
```fish
mise run container-release jobsync <version>
```
Update `newTag` in `argocd/manifests/jobsync/kustomization.yaml` after building, then `argocd app sync jobsync`.
## Related
- [[ollama]] — AI backend for resume tailoring
- [[ringtail]] — Host node
- [[deploy-jobsync]] — Deployment how-to
- [[build-jobsync-container]] — Container build guide
- [[apps]] — ArgoCD application registry