Update AGENTS.md. Start fixing old weird errors
This commit is contained in:
287
README.md
287
README.md
@@ -32,15 +32,21 @@ A production-ready Turborepo starter with Next.js, Expo, and self-hosted Convex
|
||||
|
||||
## Getting Started
|
||||
|
||||
This is a self-hosted template. The full setup requires a server (home server or VPS)
|
||||
to host the Convex backend and dashboard, and a reverse proxy (nginx-proxy-manager is
|
||||
recommended) to expose them over HTTPS. The Next.js app can run locally in dev mode
|
||||
once the Convex containers are reachable.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- [Bun](https://bun.sh) (v1.2.19+)
|
||||
- [Bun](https://bun.sh) (v1.2+)
|
||||
- [Docker](https://www.docker.com/) & Docker Compose (for self-hosted Convex)
|
||||
- Node.js 22.20.0+ (for compatibility)
|
||||
- Node.js 22+ (for compatibility)
|
||||
- A running nginx-proxy-manager instance (or similar reverse proxy) to expose Convex over HTTPS
|
||||
|
||||
### Development Setup
|
||||
---
|
||||
|
||||
#### 1. Clone & Install
|
||||
### Step 1 — Clone & Install
|
||||
|
||||
```bash
|
||||
git clone https://git.gbrown.org/gib/convex-monorepo
|
||||
@@ -48,88 +54,152 @@ cd convex-monorepo
|
||||
bun install
|
||||
```
|
||||
|
||||
#### 2. Configure Environment Variables
|
||||
|
||||
Create a `.env` file in the project root with the following variables:
|
||||
If you're using this as a template for a new project, remove the existing remote and
|
||||
add your own:
|
||||
|
||||
```bash
|
||||
# Convex Backend (Self-Hosted)
|
||||
CONVEX_SELF_HOSTED_URL=https://api.convex.example.com
|
||||
CONVEX_SELF_HOSTED_ADMIN_KEY=<generated>
|
||||
CONVEX_SITE_URL=https://convex.example.com
|
||||
|
||||
# Next.js Public
|
||||
NEXT_PUBLIC_CONVEX_URL=https://api.convex.example.com
|
||||
NEXT_PUBLIC_SITE_URL=https://example.com
|
||||
NEXT_PUBLIC_PLAUSIBLE_URL=https://plausible.example.com
|
||||
NEXT_PUBLIC_SENTRY_DSN=
|
||||
NEXT_PUBLIC_SENTRY_URL=
|
||||
NEXT_PUBLIC_SENTRY_ORG=
|
||||
NEXT_PUBLIC_SENTRY_PROJECT_NAME=
|
||||
|
||||
# Server-side
|
||||
SENTRY_AUTH_TOKEN=
|
||||
|
||||
# Auth (will be synced to Convex)
|
||||
AUTH_AUTHENTIK_ID=
|
||||
AUTH_AUTHENTIK_SECRET=
|
||||
AUTH_AUTHENTIK_ISSUER=
|
||||
USESEND_API_KEY=
|
||||
git remote remove origin
|
||||
git remote add origin https://your-git-host.com/your/new-repo.git
|
||||
```
|
||||
|
||||
**For local development:** Use `http://localhost:3210` for Convex URLs.
|
||||
---
|
||||
|
||||
#### 3. Configure Docker Environment
|
||||
### Step 2 — Configure the Docker Environment
|
||||
|
||||
Check and update environment variables in `docker/.env` for your deployment:
|
||||
The `docker/` directory contains everything needed to run the Convex backend and the
|
||||
Next.js app in production.
|
||||
|
||||
```bash
|
||||
cd docker/
|
||||
cp .env.example .env
|
||||
# Edit .env with your configuration
|
||||
```
|
||||
|
||||
#### 4. Start Self-Hosted Convex
|
||||
Edit `docker/.env` and fill in your values. The variables below the Next.js app section
|
||||
control the Convex containers — you'll need to choose:
|
||||
|
||||
Spin up the Convex backend and dashboard:
|
||||
- `INSTANCE_NAME` — a unique name for your Convex instance
|
||||
- `INSTANCE_SECRET` — a secret string (generate something random)
|
||||
- `CONVEX_CLOUD_ORIGIN` — the public HTTPS URL for your Convex backend API (e.g. `https://api.convex.example.com`)
|
||||
- `CONVEX_SITE_ORIGIN` — the public HTTPS URL for Convex Auth HTTP routes (e.g. `https://api.convex.example.com`)
|
||||
- `NEXT_PUBLIC_DEPLOYMENT_URL` — the URL for the Convex dashboard (e.g. `https://dashboard.convex.example.com`)
|
||||
|
||||
---
|
||||
|
||||
### Step 3 — Start the Convex Containers
|
||||
|
||||
```bash
|
||||
cd docker/
|
||||
docker compose up -d convex-backend convex-dashboard
|
||||
sudo docker compose up -d convex-backend convex-dashboard
|
||||
```
|
||||
|
||||
**Services:**
|
||||
Wait a moment for `convex-backend` to pass its health check, then verify both
|
||||
containers are running:
|
||||
|
||||
- **Backend:** http://localhost:3210
|
||||
- **Dashboard:** http://localhost:6791
|
||||
```bash
|
||||
sudo docker compose ps
|
||||
```
|
||||
|
||||
#### 5. Generate Auth Keys & Sync Environment Variables
|
||||
Reverse-proxy the two Convex services through nginx-proxy-manager (or your preferred
|
||||
proxy) to the URLs you chose in Step 2. Both must be reachable over HTTPS before you
|
||||
can proceed.
|
||||
|
||||
Generate JWT keys for Convex Auth:
|
||||
---
|
||||
|
||||
### Step 4 — Generate the Convex Admin Key
|
||||
|
||||
With the backend container running, generate the admin key:
|
||||
|
||||
```bash
|
||||
cd docker/
|
||||
./generate_convex_admin_key
|
||||
```
|
||||
|
||||
Copy the printed key — you'll need it as `CONVEX_SELF_HOSTED_ADMIN_KEY` in the root
|
||||
`.env` file.
|
||||
|
||||
---
|
||||
|
||||
### Step 5 — Configure Root Environment Variables
|
||||
|
||||
Create the root `.env` file:
|
||||
|
||||
```bash
|
||||
# From the repo root
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
Fill out all values in `/.env`:
|
||||
|
||||
```bash
|
||||
# Next.js
|
||||
NODE_ENV=development
|
||||
SENTRY_AUTH_TOKEN= # From your self-hosted Sentry
|
||||
NEXT_PUBLIC_SITE_URL=https://example.com
|
||||
NEXT_PUBLIC_CONVEX_URL=https://api.convex.example.com
|
||||
NEXT_PUBLIC_PLAUSIBLE_URL=https://plausible.example.com
|
||||
NEXT_PUBLIC_SENTRY_DSN=
|
||||
NEXT_PUBLIC_SENTRY_URL=https://sentry.example.com
|
||||
NEXT_PUBLIC_SENTRY_ORG=sentry
|
||||
NEXT_PUBLIC_SENTRY_PROJECT_NAME=my-project
|
||||
|
||||
# Convex
|
||||
CONVEX_SELF_HOSTED_URL=https://api.convex.example.com
|
||||
CONVEX_SELF_HOSTED_ADMIN_KEY= # From Step 4
|
||||
CONVEX_SITE_URL=http://localhost:3000 # Always localhost:3000 for local dev
|
||||
|
||||
# Auth (synced to Convex in Step 6)
|
||||
USESEND_API_KEY=
|
||||
USESEND_URL=https://usesend.example.com
|
||||
USESEND_FROM_EMAIL=My App <noreply@example.com>
|
||||
AUTH_AUTHENTIK_ID=
|
||||
AUTH_AUTHENTIK_SECRET=
|
||||
AUTH_AUTHENTIK_ISSUER=https://auth.example.com/application/o/my-app/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Step 6 — Generate JWT Keys & Sync Environment Variables to Convex
|
||||
|
||||
Generate the RS256 JWT keypair needed for Convex Auth:
|
||||
|
||||
```bash
|
||||
cd packages/backend
|
||||
bun run scripts/generateKeys.mjs
|
||||
```
|
||||
|
||||
Sync environment variables to Convex deployment (via CLI or Dashboard):
|
||||
This prints `JWT_PRIVATE_KEY` and `JWKS` values. Sync them to your Convex deployment
|
||||
along with all other backend environment variables:
|
||||
|
||||
```bash
|
||||
cd packages/backend
|
||||
bun with-env npx convex env set AUTH_AUTHENTIK_ID "your-value"
|
||||
bun with-env npx convex env set AUTH_AUTHENTIK_SECRET "your-value"
|
||||
# From packages/backend/
|
||||
bun with-env npx convex env set JWT_PRIVATE_KEY "your-private-key"
|
||||
bun with-env npx convex env set JWKS "your-jwks"
|
||||
bun with-env npx convex env set AUTH_AUTHENTIK_ID "your-client-id"
|
||||
bun with-env npx convex env set AUTH_AUTHENTIK_SECRET "your-client-secret"
|
||||
bun with-env npx convex env set AUTH_AUTHENTIK_ISSUER "your-issuer-url"
|
||||
bun with-env npx convex env set USESEND_API_KEY "your-api-key"
|
||||
bun with-env npx convex env set CONVEX_SITE_URL "http://localhost:3000"
|
||||
bun with-env npx convex env set USESEND_URL "https://usesend.example.com"
|
||||
bun with-env npx convex env set USESEND_FROM_EMAIL "My App <noreply@example.com>"
|
||||
```
|
||||
|
||||
**Important:** For local development, set `CONVEX_SITE_URL` to `http://localhost:3000`.
|
||||
**For production auth to work**, you must also update `CONVEX_SITE_URL` in the Convex
|
||||
Dashboard to your production Next.js URL. Go to
|
||||
`https://dashboard.convex.example.com` → Settings → Environment Variables and set:
|
||||
|
||||
#### 6. Start Development Server
|
||||
```
|
||||
CONVEX_SITE_URL = https://example.com
|
||||
```
|
||||
|
||||
The root `.env` value of `http://localhost:3000` is correct for local dev and should
|
||||
not be changed — only update it in the Dashboard for production.
|
||||
|
||||
---
|
||||
|
||||
### Step 7 — Start the Development Server
|
||||
|
||||
```bash
|
||||
# From project root
|
||||
bun dev:next # Next.js app + Convex backend
|
||||
bun dev:next # Next.js app + Convex backend (most common)
|
||||
# or
|
||||
bun dev # All apps (Next.js + Expo + Backend)
|
||||
```
|
||||
@@ -137,7 +207,7 @@ bun dev # All apps (Next.js + Expo + Backend)
|
||||
**App URLs:**
|
||||
|
||||
- **Next.js:** http://localhost:3000
|
||||
- **Convex Dashboard:** http://localhost:6791
|
||||
- **Convex Dashboard:** https://dashboard.convex.example.com
|
||||
|
||||
---
|
||||
|
||||
@@ -193,7 +263,7 @@ convex-monorepo/
|
||||
│
|
||||
├── packages/
|
||||
│ ├── backend/ # Convex backend
|
||||
│ │ ├── convex/ # Convex functions (synced to cloud)
|
||||
│ │ ├── convex/ # Convex functions (synced to deployment)
|
||||
│ │ ├── scripts/ # Utilities (generateKeys.mjs)
|
||||
│ │ └── types/ # Shared types
|
||||
│ └── ui/ # shadcn/ui components
|
||||
@@ -223,16 +293,16 @@ convex-monorepo/
|
||||
- **OAuth:** Authentik SSO integration
|
||||
- **Password:** Custom password auth with email verification
|
||||
- **OTP:** Email verification via self-hosted UseSend
|
||||
- **Session Management:** Secure cookie-based sessions
|
||||
- **Session Management:** Secure cookie-based sessions (30-day max age)
|
||||
|
||||
### Next.js App
|
||||
|
||||
- **App Router:** Next.js 16 with React Server Components
|
||||
- **Data Preloading:** Server-side data fetching with Convex
|
||||
- **Middleware:** Route protection & authentication
|
||||
- **Styling:** Tailwind CSS v4 with dark mode
|
||||
- **Analytics:** Plausible (privacy-focused)
|
||||
- **Monitoring:** Sentry error tracking
|
||||
- **Data Preloading:** SSR data fetching with `preloadQuery` + `usePreloadedQuery`
|
||||
- **Middleware:** Route protection & IP-based security (`src/proxy.ts`)
|
||||
- **Styling:** Tailwind CSS v4 with dark mode (OKLCH-based theme)
|
||||
- **Analytics:** Plausible (privacy-focused, proxied through Next.js)
|
||||
- **Monitoring:** Sentry error tracking & performance
|
||||
|
||||
### Backend
|
||||
|
||||
@@ -244,87 +314,113 @@ convex-monorepo/
|
||||
|
||||
### Developer Experience
|
||||
|
||||
- **Monorepo:** Turborepo for efficient builds
|
||||
- **Monorepo:** Turborepo for efficient builds and caching
|
||||
- **Type Safety:** Strict TypeScript throughout
|
||||
- **Code Quality:** ESLint + Prettier with auto-fix
|
||||
- **Hot Reload:** Fast refresh for all packages
|
||||
- **Catalog Deps:** Centralized version management
|
||||
- **Catalog Deps:** Centralized dependency version management
|
||||
|
||||
---
|
||||
|
||||
## Deployment
|
||||
|
||||
### Docker (Recommended)
|
||||
### Production Deployment (Docker)
|
||||
|
||||
Build and deploy with Docker Compose:
|
||||
Once the Convex containers are running (they only need to be started once), deploying
|
||||
a new version of the Next.js app is a two-command workflow:
|
||||
|
||||
```bash
|
||||
# SSH onto your server, then:
|
||||
cd docker/
|
||||
|
||||
# Build the new image
|
||||
sudo docker compose build next-app
|
||||
|
||||
# Deploy it
|
||||
sudo docker compose up -d next-app
|
||||
```
|
||||
|
||||
To start all services from scratch:
|
||||
|
||||
```bash
|
||||
cd docker/
|
||||
|
||||
# Start all services
|
||||
docker compose up -d
|
||||
|
||||
# View logs
|
||||
docker compose logs -f
|
||||
|
||||
# Stop services
|
||||
docker compose down
|
||||
sudo docker compose up -d convex-backend convex-dashboard
|
||||
# Wait for backend health check to pass, then:
|
||||
sudo docker compose up -d next-app
|
||||
```
|
||||
|
||||
**Services:**
|
||||
|
||||
- `next-app` - Next.js standalone build
|
||||
- `convex-backend` - Convex backend (port 3210)
|
||||
- `convex-dashboard` - Admin dashboard (port 6791)
|
||||
- `next-app` — Next.js standalone build
|
||||
- `convex-backend` — Convex backend (port 3210)
|
||||
- `convex-dashboard` — Admin dashboard (port 6791)
|
||||
|
||||
**Network:** Uses `nginx-bridge` network (configurable in `compose.yml`).
|
||||
**Network:** Uses `nginx-bridge` Docker network (reverse proxy via nginx-proxy-manager).
|
||||
|
||||
### Production Checklist
|
||||
|
||||
- [ ] Update environment variables in `docker/.env`
|
||||
- [ ] Generate `CONVEX_SELF_HOSTED_ADMIN_KEY`
|
||||
- [ ] Configure reverse proxy (Nginx/Traefik)
|
||||
- [ ] Set up SSL certificates
|
||||
- [ ] Sync auth environment variables to Convex
|
||||
- [ ] Configure backup strategy for `docker/data/`
|
||||
- [ ] Test authentication flow
|
||||
- [ ] Enable Sentry error tracking
|
||||
- [ ] Fill out `docker/.env` with your domain names and secrets
|
||||
- [ ] Start `convex-backend` and `convex-dashboard` containers
|
||||
- [ ] Generate and set `CONVEX_SELF_HOSTED_ADMIN_KEY` via `./generate_convex_admin_key`
|
||||
- [ ] Reverse-proxy both Convex services via nginx-proxy-manager with SSL
|
||||
- [ ] Fill out root `/.env` with all environment variables
|
||||
- [ ] Generate JWT keys and sync all env vars to Convex (`bun with-env npx convex env set ...`)
|
||||
- [ ] Update `CONVEX_SITE_URL` in the Convex Dashboard to your production Next.js URL
|
||||
- [ ] Build and start the `next-app` container
|
||||
- [ ] Back up `docker/data/` regularly (contains all Convex database data)
|
||||
|
||||
---
|
||||
|
||||
## Documentation
|
||||
|
||||
- **[AGENTS.md](./AGENTS.md)** - Comprehensive guide for AI agents & developers
|
||||
- **[Convex Docs](https://docs.convex.dev)** - Official Convex documentation
|
||||
- **[Turborepo Docs](https://turbo.build/repo/docs)** - Turborepo documentation
|
||||
- **[Next.js Docs](https://nextjs.org/docs)** - Next.js documentation
|
||||
- **[AGENTS.md](./AGENTS.md)** — Comprehensive guide for AI agents & developers
|
||||
- **[Convex Docs](https://docs.convex.dev)** — Official Convex documentation
|
||||
- **[Turborepo Docs](https://turbo.build/repo/docs)** — Turborepo documentation
|
||||
- **[Next.js Docs](https://nextjs.org/docs)** — Next.js documentation
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Backend typecheck shows help message
|
||||
### Backend typecheck shows TypeScript help message
|
||||
|
||||
This is expected behavior. The backend package follows Convex's structure with only `convex/tsconfig.json` (no root tsconfig). See [AGENTS.md](./AGENTS.md) for details.
|
||||
This is expected behavior. The backend package follows Convex's structure with only
|
||||
`convex/tsconfig.json` (no root tsconfig). Running `bun typecheck` from the repo root
|
||||
will show TypeScript's help text for `@gib/backend` — this is not an error.
|
||||
|
||||
### Imports from Convex require .js extension
|
||||
### Imports from Convex require `.js` extension
|
||||
|
||||
The project uses ESM (`"type": "module"`), requiring explicit file extensions:
|
||||
The project uses ESM (`"type": "module"`), which requires explicit file extensions:
|
||||
|
||||
```typescript
|
||||
// ✅ Correct
|
||||
|
||||
// ❌ Wrong
|
||||
import type { Id } from '@gib/backend/convex/_generated/dataModel.js';
|
||||
// ❌ Wrong — will fail at runtime
|
||||
import { api } from '@gib/backend/convex/_generated/api';
|
||||
import { api } from '@gib/backend/convex/_generated/api.js';
|
||||
```
|
||||
|
||||
### Docker containers won't start
|
||||
|
||||
1. Check Docker logs: `docker compose logs`
|
||||
1. Check Docker logs: `sudo docker compose logs`
|
||||
2. Verify environment variables in `docker/.env`
|
||||
3. Ensure ports 3210 and 6791 are available
|
||||
4. Check network configuration (`nginx-bridge`)
|
||||
3. Ensure the `nginx-bridge` network exists: `sudo docker network create nginx-bridge`
|
||||
4. Check that the required ports (3210, 6791) are not already in use
|
||||
|
||||
### Auth doesn't work in production
|
||||
|
||||
Make sure `CONVEX_SITE_URL` is set to your production Next.js URL in the **Convex
|
||||
Dashboard** (not just in the root `.env` file). The root `.env` should always contain
|
||||
`http://localhost:3000`; the Dashboard must have your production URL.
|
||||
|
||||
### Catalog updates break workspace
|
||||
|
||||
After updating dependencies, if you see `sherif` errors on `bun install`:
|
||||
|
||||
1. Never use `bun update` inside individual package directories
|
||||
2. Edit the version in root `package.json` catalog section instead
|
||||
3. Run `bun install` from the root
|
||||
4. Verify with `bun lint:ws`
|
||||
|
||||
---
|
||||
|
||||
@@ -337,6 +433,7 @@ This is a personal monorepo template. Feel free to fork and adapt for your needs
|
||||
- Single quotes, trailing commas
|
||||
- 80 character line width
|
||||
- ESLint + Prettier enforced
|
||||
- `const fn = () => {}` over `function fn()` (strong preference)
|
||||
- Import order: Types → React → Next → Third-party → @gib → Local
|
||||
|
||||
Run `bun lint:fix` and `bun format:fix` before committing.
|
||||
|
||||
Reference in New Issue
Block a user