TutorialsNext.jsTutorial

Deploy a production Next.js app in 90 seconds

Connect a GitHub repo, attach a Postgres database, and go live - all in under two minutes.

TW

Tom Walsh

Developer Advocate

March 14, 20265 min read

Most "quick start" tutorials skip the parts that actually take time: wiring up a database, setting environment variables correctly, and understanding what the platform is doing under the hood. This one doesn't. By the end you'll have a production Next.js app running with a real Postgres database, deployed from a GitHub push.

Prerequisites

  • A StackBlaze account (free tier works fine)
  • A Next.js app pushed to a GitHub repository
  • Node.js 18+ used locally (we'll match this on the platform)

If you don't have an app ready, clone the official Next.js starter: npx create-next-app@latest my-app. Push it to a new GitHub repo and come back here.

Step 1: Connect your GitHub repo

From the StackBlaze dashboard, click New Service → Web Service. You'll be prompted to authorize GitHub. Grant access to either all repositories or just the specific repo you want to deploy, we request the minimum scopes needed (contents: read, webhooks: write).

Once authorized, search for your repository by name and select it. StackBlaze will scan the repo root for a package.json and detect that this is a Next.js project.

Step 2: Configure your service

The configuration screen will pre-fill sensible defaults. Review the following:

  • Branch: main (or whichever branch you want to deploy from)
  • Build command: npm run build
  • Start command: npm start
  • Node version: auto-detected from your .nvmrc or package.json engines field
  • Region: pick the one closest to your users

Build command auto-detection

StackBlaze reads your package.json scripts to detect the right build command. If you have a "build" script, it uses that. If you use Turborepo or a custom output directory, you can override the detected command here - just make sure it outputs to .next for the platform to find the build artifact.

Step 3: Attach a Postgres database

Click Add Resource → Postgres. Choose a plan, the Dev plan is free and gives you a fully isolated Postgres 16 instance with 1 GB storage. This creates the database in the same private network as your web service, so traffic between them never touches the public internet.

After creating the database, StackBlaze automatically injects a DATABASE_URL environment variable into your web service. You don't need to copy connection strings manually.

Step 4: Set environment variables

Go to the Environment tab of your web service. Add any app-specific variables your Next.js app needs. For variables you want exposed to the browser, prefix them with NEXT_PUBLIC_.

.env.local
# Local development only, do not commit this file
DATABASE_URL=postgresql://postgres:password@localhost:5432/myapp
NEXT_PUBLIC_APP_URL=http://localhost:3000
NEXTAUTH_SECRET=your-dev-secret-here
NEXTAUTH_URL=http://localhost:3000

In production, DATABASE_URL is already injected. Add the remaining variables through the dashboard. For secrets like NEXTAUTH_SECRET, use the "Secret" toggle so the value is encrypted at rest and never shown in the UI after saving.

lib/db.ts
import { Pool } from 'pg';

// DATABASE_URL is injected automatically by StackBlaze when a Postgres
// resource is attached. Falls back to the local URL during development.
const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
  ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : false,
  max: 10,
});

export default pool;

Step 5: Deploy

Click Deploy. StackBlaze queues a build, runs npm run build inside an isolated container, and starts your service when the build succeeds. The first build typically takes 60–90 seconds depending on your dependency tree. Subsequent deploys are faster because the npm cache layer is reused when your package-lock.json hasn't changed.

You'll see streaming build logs in the dashboard. Once the service is healthy, your app is live at a generated .stackblaze.app domain. You can attach a custom domain from the Settings tab, DNS verification and TLS provisioning happen automatically.

What just happened

  1. Cloned your repo and installed a webhook so every push to your branch triggers a new deploy
  2. Built your app inside an ephemeral container with the Node version matching your project
  3. Provisioned a Postgres 16 instance in the same private network zone as your web service
  4. Injected DATABASE_URL as a runtime environment variable, no secrets in your codebase
  5. Started your app behind a load balancer with automatic TLS termination
  6. Set up health checks that restart your service if it stops responding

From here, every push to your main branch will trigger a new deploy automatically. If a build fails, the previous version stays live, there's no downtime during broken builds.

TW

Tom Walsh

Developer Advocate at StackBlaze

Member of the founding team at StackBlaze. Writes about infrastructure, engineering culture, and the systems that keep production running.

More from the blog