Skip to main content
Sandbox demo — data resets on the hour. Try the admin at /admin, own the whole thing viathe template →
Get Template — $89

Search AI Directory

Search tools, categories, stacks, and pages

Getting Started

Deployment

Three paths to production, plus scheduling the pipelines.

One Next.js app serves everything: the public site, the /admin console, the REST API, and the MCP server. One Postgres database holds all content. There are no required third-party services. Pick whichever path fits your infrastructure.

Any 2-core VPS works. You need a domain with an A record pointing at the server. The repo ships docker-compose.yml (app + Postgres) and a Caddyfile that provisions HTTPS automatically.

git clone <your-repo> && cd <your-repo>
cp .env.example .env
# edit .env: DOMAIN, POSTGRES_PASSWORD, BETTER_AUTH_SECRET (openssl rand -base64 32)
docker compose up -d

The first boot builds the app against the live database (a few minutes) and pushes the schema. Optionally load the starter content:

docker compose exec app pnpm --filter @repo/database seed

Then open https://your-domain/admin — the setup wizard creates the owner account and saves your site identity.

Path B — Vercel + Neon

  1. Create a Neon Postgres database; copy the connection string.
  2. Import the repo into Vercel with root directory apps/web.
  3. Set the environment variables from .env.example (at least DATABASE_URL, NEXT_PUBLIC_SITE_URL, BETTER_AUTH_SECRET, BETTER_AUTH_URL).
  4. Push the schema once from your machine:
DATABASE_URL=<neon-url> npx prisma db push --schema=packages/database/prisma/schema.prisma
DATABASE_URL=<neon-url> pnpm --filter @repo/database seed   # optional starter content
  1. Deploy, then visit /admin for the setup wizard.

Path C — bare VPS with PM2

For a plain Node server with no Docker. Install Node 20+ and pnpm, provision Postgres, then build and run under a process manager.

pnpm install
pnpm --filter @repo/database build          # prisma generate
npx prisma db push --schema=packages/database/prisma/schema.prisma
pnpm --filter @repo/database seed            # optional
pnpm --filter web build                      # content-collections + next build

Run the built app with PM2. The start script defaults to port 3000, so pass -p 3001 (or your chosen port) explicitly and put a reverse proxy in front for TLS:

// ecosystem.config.js
module.exports = {
  apps: [
    {
      name: "directory",
      cwd: "./apps/web",
      script: "node_modules/.bin/next",
      args: "start -p 3001",
      env: {
        NODE_ENV: "production",
        DATABASE_URL: process.env.DATABASE_URL,
        NEXT_PUBLIC_SITE_URL: process.env.NEXT_PUBLIC_SITE_URL,
        BETTER_AUTH_SECRET: process.env.BETTER_AUTH_SECRET,
        BETTER_AUTH_URL: process.env.BETTER_AUTH_URL,
      },
    },
  ],
};
pm2 start ecosystem.config.js

Reference env vars from the process environment rather than hardcoding them in the config file. See Environment variables for the full list.

Scheduling the pipelines

The pipelines are POST /api/cron/* endpoints. Nothing calls them for you — you schedule them with server crontab, GitHub Actions, or an agent. Each call needs an API key with the publish scope (create one in /admin/api-keys).

curl -X POST https://your-domain/api/cron/news \
  -H "Authorization: Bearer $API_KEY"

A sensible starting schedule:

PipelineEndpointSuggested cadence
News/api/cron/newsHourly
News enrich/api/cron/news-enrichEvery 2 hours
Tools crawl/api/cron/tools-crawlDaily
Tools enrich/api/cron/tools-enrichDaily
Data audit/api/cron/data-auditNightly
Tool discovery/api/cron/tool-discoveryDaily
Compare generate/api/cron/compare-generateWeekly
Stacks refresh/api/cron/stacks-refreshWeekly
Roles sync/api/cron/roles-syncWeekly
Tags sync/api/cron/tags-syncDaily

Example crontab lines:

0 * * * *   curl -sS -X POST https://your-domain/api/cron/news          -H "Authorization: Bearer $API_KEY"
0 */2 * * * curl -sS -X POST https://your-domain/api/cron/news-enrich    -H "Authorization: Bearer $API_KEY"
30 3 * * *  curl -sS -X POST https://your-domain/api/cron/tools-crawl    -H "Authorization: Bearer $API_KEY"

Every run is recorded at /admin/pipelines with status, duration, and item counts.