A complete SaaS boilerplate with Next.js, Drizzle ORM, Stripe, and Better Auth.
Follow these steps to set up your project.
- Go to Cloudflare or your preferred registrar.
- Buy a domain name.
- If you use a different registrar, point your nameservers to Cloudflare for better DNS management (optional but recommended).
- Go to Resend and sign up.
- Add your domain to Resend and verify the DNS records in Cloudflare.
- Create an API Key.
- Add the following to your
.envfile:RESEND_API_KEY=re_123... RESEND_FROM=onboarding@yourdomain.com
- Go to Upstash and create a Redis database.
- Copy the
UPSTASH_REDIS_REST_URLandUPSTASH_REDIS_REST_TOKEN. - Add them to your
.envfile:UPSTASH_REDIS_REST_URL=https://... UPSTASH_REDIS_REST_TOKEN=...
You need a PostgreSQL database. You can host this on a Hetzner VPS (using Docker or manual install) or use a managed provider.
- Set up a PostgreSQL database.
- Get the connection string (
postgres://...). - Add it to your
.envfile:DATABASE_URL=postgres://user:password@host:port/db
- Go to the Google Cloud Console.
- Create a new project.
- Go to "APIs & Services" > "Credentials".
- Create "OAuth client ID".
- Set "Authorized JavaScript origins" to
http://localhost:3000(and your production URL). - Set "Authorized redirect URIs" to
http://localhost:3000/api/auth/callback/google(and production equivalent). - Copy the Client ID and Client Secret.
- Add them to your
.envfile:GOOGLE_CLIENT_ID=... GOOGLE_CLIENT_SECRET=...
- Go to Stripe and create an account.
- Get your API keys (Secret Key and Publishable Key) from the Developer Dashboard.
- Create a Product and Price in Stripe. Copy the Price ID (e.g.,
price_...). - Set up a Webhook pointing to
http://localhost:3000/api/webhooks/stripe(use Stripe CLI for local testing:stripe listen --forward-to localhost:3000/api/webhooks/stripe). - Get the Webhook Signing Secret (
whsec_...). - Add them to your
.envfile:STRIPE_SECRET_KEY=sk_test_... NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_... STRIPE_WEBHOOK_SECRET=whsec_... NEXT_PUBLIC_STRIPE_PRICE_ID=price_...
Create a .env file in the root directory and fill in all the values:
NODE_ENV=development
NEXT_PUBLIC_APP_URL=http://localhost:3000
# Database
DATABASE_URL=
# Auth (Google)
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
# Payments (Stripe)
STRIPE_SECRET_KEY=
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=
STRIPE_WEBHOOK_SECRET=
NEXT_PUBLIC_STRIPE_PRICE_ID=
# Email (Resend)
RESEND_API_KEY=
RESEND_FROM=
# Redis (Upstash)
UPSTASH_REDIS_REST_URL=
UPSTASH_REDIS_REST_TOKEN=
# Analytics (PostHog - Optional)
NEXT_PUBLIC_POSTHOG_KEY=
NEXT_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com- Install dependencies:
pnpm install
- Push the database schema:
pnpm db:push
- Run the development server:
pnpm dev
To deploy on a Hetzner VPS using Docker:
- Provision a VPS (e.g., Ubuntu).
- Install Docker and Docker Compose.
- Clone this repository to the server.
- Create your
.envfile with production values. - Build and run the container:
Note: For a production setup, consider using Coolify or a reverse proxy (Nginx/Traefik) with SSL.
docker build -t saas-app . docker run -p 3000:3000 --env-file .env saas-app