freehire

应用程序

strelov1/freehire

开源职位搜索引擎,直接聚合企业官网招聘页面。

项目简介

freehire 直接从 Workday、Greenhouse、Lever 等企业 ATS 职业页面抓取数百万在招职位,统一规范化并去重。提供多维度全文搜索、订阅推送、简历生成、投递追踪及 LLM 匹配分析。采用 Go 后端、SvelteKit 前端、PostgreSQL 与 Meilisearch,可完全自托管。

README 预览

\n\n\n  \n  \n\n\n# freehire\n\n### Every IT job, straight from the source.\n\n**3.3M+ live postings pulled directly from company career pages — no recruiters, no reposts, no dead links. Fully open source.**\n\n[**Try it live →**](https://freehire.me) · [Features](docs/features.md) · [Architecture](docs/architecture.md) · [Sources](#sources) · [API](#api) · [Add a source](#adding-a-source) · [Contributing](CONTRIBUTING.md)\n\n[](https://freehire.me)\n[](LICENSE)\n\n\n[](https://github.com/strelov1/freehire/stargazers)\n[](https://github.com/strelov1/freehire/graphs/contributors)\n[](https://discord.gg/79cgB9RRfx)\n\n\n\n\n\n  \n    \n    \n  \n\n\n\n\n\n\n\n\n\n## Why freehire?\n\n- **Straight from the source.** Every listing is crawled directly from a company's\n  own ATS — Workday, Greenhouse, Lever, Ashby, iCIMS and a long tail of others — and\n  links to the original posting. No recruiter reposts, no aggregator middlemen, no\n  dead links.\n- **One schema, deduplicated.** The same role posted to three boards collapses into\n  one entry: every posting is normalized into a single shape and deduplicated on a\n  stable key.\n- **Search that understands jobs.** Faceted full-text search over region, work mode,\n  seniority, skills and salary — derived from curated dictionaries, never guessed.\n- **Actually open.** MIT-licensed and self-hostable, pipeline and data both in the\n  open. Adding a company is one row in the board catalog\n  ([how](#adding-a-source)).\n- **Yours to build on.** A clean HTTP API, a CLI, Telegram digests, and a whole\n  workspace on top of the catalogue — see [Beyond the catalogue](#beyond-the-catalogue).\n  Use the hosted site, run your own, or build on top.\n\nAggregating **3.3M+ unique live postings** from **470,000+ companies** across\n**124 ATS platforms**, a long tail of aggregators and direct feeds, and **97\nTelegram channels** — **320 sources** in all, see [Sources](#sources) for the full\nbreakdown. Reposts of one job across boards ar

常见问题 (3)

故障排除
为什么 `docker compose up` 在重启 stack 后会一直卡在 s3-init 容器上?

第二次执行 make up 时,s3-init 会卡住,因为其重试循环只发送创建存储桶的 PUT 请求。当存储桶已经存在时,s3mock 会返回 409 BucketAlreadyOwnedByYou,curl -f 会以退出码 22 退出,until 循环便会无限重试,导致容器一直停留在 Waiting 状态。

修复:该问题已在 PR #3265 中修复(于 2026-10-19 合并)。init 脚本现在会先检查存储桶是否存在,仅在不存在时才创建,因此在首次及后续运行时都会以 0 正常退出(已针对 adobe/s3mock:5.2.3 验证)。

解决方法:更新本地代码并重启:

git pull origin main
make down
make up

来源 Issue #3264
故障排除
如何修复导致无法滑动职位卡片的"job not found"错误?

该职位通常并未被删除——而是数据源对它进行了重命名,一次 backfill 重新生成了它的 URL slug,因此滑动卡组中仍保留着旧的 slug,导致 POST /api/v1/jobs/<old-slug>/dismiss 返回 404。修复方法:升级到包含 PR #3289 的版本,该版本会阻止 backfill 更改已发布职位的 slug,并使旧的 slug 以 301 重定向到当前 URL。如果卡片仍然卡住,请修补 web/src/lib/components/SwipeDeck.svelte:在 judge() 中,send.catch(...) 处理程序会在任何失败时都把卡片恢复到顶部——请将其改为仅在网络错误时恢复卡片,并在服务器响应 404 时丢弃该卡片,因为 404 意味着该职位已不存在。

来源 Issue #3284
故障排除
为什么带有 'Locations:' 前缀的 Greenhouse 职位发布中国家和地区为空,以及如何修复?

部分 Greenhouse 职位发布在存储地点时带有 Locations: 标签前缀(例如 Locations: San Francisco),location.Parse 无法解析这种格式,导致 jobs.countries 和 jobs.regions 为空,并使 country=us 过滤器遗漏该职位。修复方法:在 Greenhouse 适配器或 normalize.CleanLocation 中,于解析前剥离 Locations: 标签。请注意,仅在采集端修复并不能修复已存储的行——需要先统计有多少行携带该前缀,然后使用 AGENTS.md 中描述的 INGEST_REFETCH_ALL / backfill-derive 作业重新派生这些行。

来源 Issue #3281