Deploy a Next.js App

This tutorial walks you through deploying a Next.js application on Temps. By the end, you will have a live Next.js app with server-side rendering, API routes, and automatic HTTPS running on your own server.


What you will build

  • A Next.js app deployed from a Git repository
  • Server-side rendering and API routes working out of the box
  • Environment variables configured for both server and client
  • Automatic deployments on every push

Time required: 10 minutes.

Prerequisites:

  • A running Temps instance (install guide)
  • A Next.js app in a GitHub, GitLab, Bitbucket, or Gitea repository
  • (Optional) A custom domain

Step 1: Prepare your app

Temps auto-detects Next.js from next in your package.json dependencies. No special configuration is needed for a standard Next.js app.

Verify your package.json

Make sure you have build and start scripts:

package.json

{
  "name": "my-next-app",
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  },
  "dependencies": {
    "next": "^16.0.0",
    "react": "^19.0.0",
    "react-dom": "^19.0.0"
  }
}

Enable standalone output (recommended)

Standalone output produces a self-contained server that does not need node_modules at runtime. This reduces your container image size significantly.

next.config.ts

import type { NextConfig } from 'next';

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

export default nextConfig;

Temps detects output: 'standalone' and adjusts the Dockerfile accordingly — copying from .next/standalone and using node server.js instead of next start.


Step 2: Create a project

  1. Open the Temps dashboard
  2. Click New Project
  3. Select your Git provider and authenticate if needed
  4. Choose the repository containing your Next.js app
  5. Select the branch to deploy (usually main)
  6. If your Next.js app is in a subdirectory (monorepo), set the Root Directory — for example, apps/web

Temps detects Next.js automatically. You will see the framework listed as Next.js in the project configuration.


Step 3: Configure environment variables

Add any environment variables your app needs in the project settings. Next.js has two types:

PrefixAvailable on serverAvailable in browserWhen embedded
No prefixYesNoRuntime
NEXT_PUBLIC_YesYesBuild time

Common variables:

# Server-only (never sent to browser)
DATABASE_URL=postgres://user:pass@host:5432/db
API_SECRET=your-secret-key

# Public (embedded in JavaScript bundle at build time)
NEXT_PUBLIC_API_URL=https://api.example.com
NEXT_PUBLIC_GA_ID=G-XXXXXXXXXX

Auto-injected variables

Temps automatically sets these — you do not need to add them:

  • PORT — The port Next.js listens on
  • HOST — Always 0.0.0.0
  • SENTRY_DSN / NEXT_PUBLIC_SENTRY_DSN — If Sentry is configured on your project
  • OTEL_EXPORTER_OTLP_ENDPOINT — OpenTelemetry collector for traces
  • OTEL_SERVICE_NAME — Your project name

Step 4: Deploy

Click Deploy or push a commit to your branch. Temps runs the following steps:

  1. Clones your repository
  2. Detects Next.js and generates a Dockerfile
  3. Installs dependencies (npm ci, yarn install --frozen-lockfile, pnpm install --frozen-lockfile, or bun install — based on your lockfile)
  4. Runs npm run build (or equivalent)
  5. Creates a container image
  6. Starts the container and runs health checks
  7. Routes traffic to the new container

Watch the build logs in the dashboard. A typical Next.js build takes 1-3 minutes depending on your project size.

What Temps generates

For a standard Next.js app, Temps generates a multi-stage Dockerfile:

  • Build stage: node:22-alpine, installs dependencies, runs next build
  • Production stage: node:22-alpine, copies build output, runs with minimal dependencies
  • Security: Non-root user, capabilities dropped, PID limits

For standalone builds, the production stage copies .next/standalone and runs node server.js. For non-standalone builds, it runs next start.


Step 5: Verify

Once the deployment completes, click the generated URL to open your app. Verify that:

  • Pages render correctly (SSR is working)
  • Client-side navigation works
  • API routes respond (test with curl or your browser)
# Test your deployment
curl https://your-app.your-domain.com
curl https://your-app.your-domain.com/api/health

Next.js features on Temps

API routes

Both App Router route handlers (app/api/*/route.ts) and Pages Router API routes (pages/api/*.ts) work without changes. They run inside the same Next.js server container.

Middleware

Next.js middleware (middleware.ts at the project root) runs on every request. It works on Temps because the Next.js server handles middleware execution — it is not a separate edge function.

Image optimization

Next.js image optimization (next/image) works out of the box. Images are optimized on-demand by the Next.js server. For production, consider setting a remotePatterns configuration if you load images from external domains:

next.config.ts

const nextConfig = {
  output: 'standalone',
  images: {
    remotePatterns: [
      { protocol: 'https', hostname: 'images.example.com' },
    ],
  },
};

Server Actions

Server Actions work without changes. They execute on the server inside the container, same as local development.

ISR (Incremental Static Regeneration)

ISR works with the default cache. Pages are regenerated on-demand by the Next.js server. The file-system cache is stored inside the container — it resets on each deployment.


Migrating from Vercel

If you are moving from Vercel to Temps:

Vercel featureTemps equivalent
Automatic deploymentsPush to branch triggers deployment
Preview deploymentsBranch-based preview environments
Environment variablesDashboard settings (same concept)
Serverless functionsAPI routes run in the container (no cold starts)
Edge functionsRun as middleware in the Next.js server
Vercel AnalyticsTemps Analytics (built-in)
Vercel BlobTemps Blob Storage
Vercel KVTemps KV Storage
@vercel/ogUse sharp or a custom image generation library
Cron jobs.temps.yaml cron configuration

Things to check

  1. Remove Vercel-specific packages: @vercel/analytics, @vercel/speed-insights, @vercel/og — replace with Temps equivalents or alternatives
  2. Update next.config.ts: Remove any vercel-specific configuration
  3. Environment variables: Re-add them in the Temps dashboard
  4. Edge runtime: If you use export const runtime = 'edge' on routes, switch to the default Node.js runtime — Temps does not have an edge runtime

Custom Dockerfile

If you need full control over the build, add a Dockerfile to your repository:

Dockerfile

FROM node:22-alpine AS base

FROM base AS deps
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN corepack enable && pnpm install --frozen-lockfile

FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN corepack enable && pnpm build

FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs
EXPOSE 3000
CMD ["node", "server.js"]

When a Dockerfile exists, Temps uses it instead of generating one.


Troubleshooting

Build fails with "next: not found"

The next package is in devDependencies and your install command skips dev dependencies. Either move next to dependencies or ensure your build runs before pruning dev dependencies.

Page renders but styles are missing

If you use CSS Modules or Tailwind, verify the build output includes CSS files. Check the build logs for CSS-related warnings. With standalone output, ensure .next/static is copied to the production stage.

API route returns 404

Verify the file is in the correct location: app/api/your-route/route.ts (App Router) or pages/api/your-route.ts (Pages Router). Check that the file exports the expected HTTP method handlers.

Memory issues during build

Large Next.js projects may need more memory during the build. Temps allocates half of the server's available memory for builds (minimum 2 GB). If your build is running out of memory, try adding standalone output to reduce the build footprint, or use a server with more RAM.


What to explore next

Manage environment variables Add a custom domain Add analytics and monitoring Deploy from a monorepo

Was this page helpful?