Deploy Next.js on Temps

Deploy Next.js applications with server-side rendering, API routes, middleware, and image optimization — on your own VPS. No Vercel required.


Prerequisites

  • A running Temps instance (install guide or quickstart)
  • A Next.js project in a GitHub or GitLab repository
  • Node.js 18+ in your project (Temps auto-detects this)

Quickstart

From your Next.js project root, deploy with your preferred package manager:

npx @temps-sdk/cli up

Or via the Temps dashboard:

  1. Go to Projects → New Project
  2. Connect your repository
  3. Temps detects Next.js and configures the build automatically
  4. Click Deploy — your app is live with HTTPS in about 2 minutes

Required: Standalone Output

Temps runs Next.js as a persistent Node.js process. Your next.config.ts (or next.config.js) must include output: 'standalone':

// next.config.ts
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  output: "standalone",
};

export default nextConfig;

If this is missing, the deployment will succeed but your app will not start. Temps will show a health check failure in the deployment logs.


What Temps Handles Automatically

FeatureHow Temps handles it
Buildnext build with standalone output
HTTPSLet's Encrypt certificate, auto-renewed
PortBinds to port 3000 by default
ISRFully supported — cache persists across deploys
Image optimizationnext/image works with no config changes
MiddlewareRuns in Node.js runtime (not Edge)
Preview deploymentsEvery PR gets its own URL
RollbacksOne click in dashboard or temps rollback CLI command
Zero-downtime deploysNew container starts before old one stops

Environment Variables

Set variables in Project → Settings → Environment Variables or via CLI:

# Set a variable for production
bunx @temps-sdk/cli environments vars set DATABASE_URL "postgres://user:pass@host:5432/db" -e production

# Set a variable for all environments
bunx @temps-sdk/cli environments vars set NEXT_PUBLIC_API_URL "https://api.yourdomain.com"

Variables prefixed with NEXT_PUBLIC_ are embedded at build time. All other variables are available at runtime only — you do not need to rebuild when you change them.

# After changing a runtime variable, trigger a redeploy
bunx @temps-sdk/cli deploy --project my-app

API Routes and Route Handlers

API routes (/app/api/ or /pages/api/) work without any changes. Temps runs your app as a persistent Node.js process, so there are no cold starts — the first request is as fast as any subsequent one.

// app/api/hello/route.ts — works on Temps without changes
export async function GET() {
  return Response.json({ message: "Hello from Temps" });
}

Middleware

Next.js Middleware runs on Temps in the Node.js runtime (not the Edge runtime). This means:

  • All Node.js APIs are available
  • No export const runtime = 'edge' required
  • No limitations on package size

If your middleware currently uses Edge-only APIs, remove export const runtime = 'edge' and test locally with NODE_ENV=production.


ISR and Caching

Incremental Static Regeneration (ISR) works on Temps. The cache is stored on disk inside the container, so it persists between requests.

On redeploy, Temps starts the new container before stopping the old one (zero-downtime). The new container starts with a cold cache, so the first request to each ISR page after a deploy will regenerate it. This is the expected behavior — subsequent requests are served from cache.

If you need the ISR cache to persist across deploys, mount a persistent volume:

  1. Go to Project → Settings → Volumes
  2. Mount a volume at /app/.next/cache

Monorepos

If your Next.js app is inside a monorepo, set the App Directory in project settings to the subdirectory containing package.json:

my-monorepo/
├── apps/
│   └── web/          ← set App Directory to "apps/web"
│       ├── package.json
│       └── next.config.ts
└── packages/

See the Monorepos guide for workspace-aware builds.


Troubleshooting

Health check failing after deploy

The most common cause is missing output: 'standalone' in next.config.ts. Check the deployment logs — if you see ENOENT .next/standalone/server.js, that is the problem.

# View live deployment logs
bunx @temps-sdk/cli deployments logs --project my-app --follow

Build running out of memory

Next.js builds can be memory-intensive. If the build fails with an out-of-memory error:

FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory

Set a higher memory limit as an environment variable in your project settings:

NODE_OPTIONS=--max-old-space-size=4096

Environment variables not available at runtime

Check that the variable is set in the correct environment (production vs staging). Variables set in the Temps console are not available at build time unless they are prefixed with NEXT_PUBLIC_.

next/image returning 404 for external images

Add your image domains to next.config.ts:

const nextConfig: NextConfig = {
  output: "standalone",
  images: {
    remotePatterns: [
      { protocol: "https", hostname: "your-image-cdn.com" },
    ],
  },
};

Port mismatch

Temps expects your app to listen on port 3000 by default. If your next.config.ts or start script uses a different port, override it with an environment variable:

PORT=3000

Switching from Vercel

If you're migrating from Vercel, see the Migrate from Vercel guide. Most Next.js apps migrate in under 30 minutes — the main changes are replacing Vercel-specific storage (KV, Blob, Postgres) with standard alternatives.


Next Steps

Was this page helpful?