How to deploy NextJS app using Docker with Bun

This article will guide experienced engineers through the process of deploying a NextJS application using Docker with Bun (than npm), a fast all-in-one JavaScript runtime. We'll explore how to leverage Bun's speed and Docker's containerization to create a streamlined deployment process.

Understanding the Dockerfile

Let's break down the Dockerfile that will be used to containerize our NextJS application:

FROM oven/bun:alpine AS base

# Step 1 - install dependencies
FROM base AS deps
WORKDIR /app
COPY package.json bun.lockb ./
RUN bun install --frozen-lockfile

# Step 2 - rebuild the app
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN bun run build

# Step 3 - copy all the files and run server
FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production
COPY --from=builder /app/public ./public
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static

EXPOSE 3000
CMD ["bun", "run", "server.js"]

This Dockerfile uses a multi-stage build process to optimize the final image size and improve security. Let's examine each stage:

Stage 1: Dependencies

In this stage, we copy the package.json and bun.lockb files and install the dependencies using Bun. The --frozen-lockfile flag ensures we use the exact versions specified in the lockfile.

Stage 2: Building the App

Here, we copy the installed node_modules from the previous stage and the rest of our application code. We then run the build process using bun run build.

Stage 3: Final Image

The final stage copies only the necessary files from the build stage, including the standalone NextJS server, static files, and public assets. This results in a smaller, production-ready image.

Optimizing for Production

Notice the ENV NODE_ENV=production line in the final stage. This sets the environment to production, which can trigger optimizations in NextJS and its dependencies.

Running the Application

The EXPOSE 3000 instruction documents that the container will listen on port 3000. The final CMD instruction specifies how to run the application using Bun.

Deploying Your NextJS App

To deploy your NextJS app using this Dockerfile:

docker build -t my-nextjs-app .
docker run -p 3000:3000 my-nextjs-app

Your NextJS application should now be accessible at http://localhost:3000.

Summary

Deploying a NextJS application using Docker with Bun offers a powerful, efficient, and streamlined approach to containerization. By leveraging Bun's speed and Docker's isolation, developers can create lightweight, performant containers for their NextJS applications.

Happy bunning!