How to Deploy Next.js Standalone with Prisma Using Docker in your VPS
80 day ago by
Introduction
Deploying a Next.js application in standalone mode with Prisma using Docker can enhance performance and simplify management. This guide will walk you through creating an optimized Dockerfile
for building and deploying your Next.js application.
Prerequisites
Before starting, make sure you have installed:
Configuring Next.js for Standalone Mode
Before building the Docker image, configure Next.js to run in standalone mode by adding the following settings in next.config.js
:
/** @type {import('next').NextConfig} */ const nextConfig = { output: 'standalone', }; module.exports = nextConfig;
This configuration ensures that Next.js generates a standalone output, making it run more efficiently inside a container.
Dockerfile for Next.js Standalone with Prisma
Here is the Dockerfile
using a multi-stage build for a lightweight and efficient deployment:
FROM node:18-alpine3.20 AS base # Install dependencies only when needed FROM base AS deps RUN apk add --no-cache libc6-compat WORKDIR /app COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./ COPY prisma ./prisma/ RUN \ if [ -f yarn.lock ]; then yarn --frozen-lockfile; \ elif [ -f package-lock.json ]; then npm ci; \ elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \ else echo "Lockfile not found." && exit 1; \ fi # Rebuild the source code only when needed FROM base AS builder WORKDIR /app COPY --from=deps /app/node_modules ./node_modules COPY . . RUN \ if [ -f yarn.lock ]; then yarn run build; \ elif [ -f package-lock.json ]; then npm run build; \ elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \ else echo "Lockfile not found." && exit 1; \ fi # Production image, copy all the files and run standalone 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 standalone build output COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static COPY --chown=nextjs:nodejs prisma ./prisma/ COPY --chown=nextjs:nodejs .env .env USER nextjs EXPOSE 3000 # Run the standalone application CMD ["node", "server.js"]
Dockerfile Explanation
1. Base Stage (base
)
- Uses
node:18-alpine3.20
as the lightweight base image. - Installs
libc6-compat
for additional compatibility.
2. Dependencies Stage (deps
)
- Copies
package.json
and lock files (yarn.lock
,package-lock.json
,pnpm-lock.yaml
). - Installs dependencies based on the available lock file.
- Copies the
prisma/
directory to ensure Prisma is included.
3. Build Stage (builder
)
- Copies dependencies from the
deps
stage to avoid reinstalling them. - Copies the entire project code and builds the Next.js application.
4. Production Stage (runner
)
- Runs the application as a non-root user (
nextjs
) for security. - Copies the build output (
.next/standalone
and.next/static
). - Copies Prisma files and
.env
to ensure database connectivity. - Exposes port
3000
and runs the application usingnode server.js
.
Running the Application in Docker
Once the Dockerfile
is ready, build and run the container using the following commands:
# Build Docker image docker build -t nextjs-prisma-app . # Run the container docker run -p 3000:3000 --env-file .env nextjs-prisma-app
Conclusion
Using a multi-stage build approach optimizes Docker image size and efficiency for Next.js with Prisma. By following these steps, your application will be ready for deployment with improved performance in a production environment.