# Local setup

Run Docup on your machine with Docker for Postgres and Redis, a .dev.vars file, migrations and the Trigger.dev dev server.

This guide runs the dashboard, a docs site and the background tasks on your own machine.

## Prerequisites

- Node.js and **pnpm 12**
- Docker, for Postgres and Redis
- A GitHub account, to create an OAuth app and a GitHub App
- A Trigger.dev cloud project, for the background tasks
- A Google Cloud project with Vertex AI and a service account, for the models
- A Qdrant Cloud cluster, for Ask AI
- Optional: Google OAuth credentials, a Cloudflare Turnstile key and an ngrok tunnel

## 1. Install

```bash
pnpm install
```

## 2. Start Postgres and Redis

```bash
pnpm db:up
```

This starts Postgres 17 on port 5432 (user, password and database all `docup`), Redis 7 and an HTTP proxy on port 8079 so the same `@upstash/redis` client works locally. The proxy token is `docup-local-redis-token`.

## 3. Create `.dev.vars`

```bash
cp .dev.vars.example .dev.vars
```

Fill in the values. The most important ones are described in [Environment variables](/development/environment-variables). For local work, set:

```text
BETTER_AUTH_URL=http://localhost:3000
DATABASE_URL=postgres://docup:docup@localhost:5432/docup
UPSTASH_REDIS_REST_URL=http://localhost:8079
UPSTASH_REDIS_REST_TOKEN=docup-local-redis-token
```

Generate `BETTER_AUTH_SECRET` with `openssl rand -base64 32`.

> **Warning:** Point `DATABASE_URL` at your local database unless you mean to use a remote one. The `db:*` scripts read `.dev.vars`, and a `DATABASE_URL` exported in your shell can take precedence over it.

## 4. Run migrations

```bash
pnpm db:migrate
```

## 5. Start the app

```bash
pnpm dev
```

The app runs on `http://localhost:3000`, and the port is strict: the command fails if it is taken. The Worker runtime is emulated, with R2 and Hyperdrive stored locally. In development Hyperdrive points at the local Postgres.

Docs sites are served on `<address>.localhost:3000`. Browsers resolve `*.localhost` to your machine, so a site with the address `acme` is at `http://acme.localhost:3000`.

## 6. Start the background tasks

In a second terminal:

```bash
pnpm trigger:dev
```

This connects to your Trigger.dev project. The tasks read their own environment variables from the Trigger.dev dashboard, not from `.dev.vars`. Add `DATABASE_URL`, `GITHUB_SERVER_TOKEN`, `GITHUB_APP_ID`, `GITHUB_APP_PRIVATE_KEY`, `GOOGLE_VERTEX_CREDENTIALS`, `QDRANT_*` and `UPSTASH_*` there.

## 7. Receive GitHub webhooks (optional)

Updates on push need GitHub to reach your machine. Run an ngrok tunnel to port 3000, set the GitHub App's webhook URL to `<tunnel>/api/webhooks/github`, and use the same secret as `GITHUB_WEBHOOK_SECRET`. The dev server allows hosts under `.ngrok-free.dev`.

## Everyday commands


| Command               | What it does                             |
| --------------------- | ---------------------------------------- |
| `pnpm dev`            | Dev server on port 3000                  |
| `pnpm build`          | Build the Worker                         |
| `pnpm start`          | Preview the build locally                |
| `pnpm preview`        | Build, then preview                      |
| `pnpm deploy`         | Deploy with vinext's Cloudflare helper   |
| `pnpm cf-typegen`     | Generate Worker binding types            |
| `pnpm trigger:dev`    | Trigger.dev dev server                   |
| `pnpm trigger:deploy` | Deploy tasks to Trigger.dev              |
| `pnpm db:up`          | Start Postgres and Redis containers      |
| `pnpm db:generate`    | Generate a migration from schema changes |
| `pnpm db:migrate`     | Apply migrations                         |
| `pnpm db:studio`      | Open Drizzle Studio                      |
| `pnpm db:auth-schema` | Regenerate the Better Auth tables        |


## Troubleshooting

- **"Port 3000 is in use."** Free the port; the server does not pick another.
- **Sign-in redirects fail.** The OAuth callback must be `http://localhost:3000/api/auth/callback/github` or `.../google`.
- **A run never starts.** Check that `pnpm trigger:dev` is running and that `TRIGGER_SECRET_KEY` is the dev key of the same project.
- **Docs sites 404.** Use `<address>.localhost:3000`, and publish the site first.
