DEV Community

Imamuzzaki Abu Salam
Imamuzzaki Abu Salam

Posted on • Originally published at blog.imam.dev

Complete Guide to Deploying Next.js Standalone with Bun and Docker

Learn to deploy a Next.js standalone application using Bun and Docker as if you were deploying with Vercel. This guide includes a step-by-step walkthrough, tackling common errors, and more.

Why Deploy Next.js with Bun and Docker?

When Bun hit its stable version 1 and Vercel started supporting it as a package manager (though still relying on Node for runtime), I was intrigued. How could you simulate the Vercel deployment process locally? Specifically, how can you deploy a Next.js standalone app with Bun and Docker? This guide aims to answer these questions.

Prerequisites

  • Basic understanding of Docker, Next.js, and Bun
  • Node.js installed
  • Bun package manager installed

Step-by-Step Guide

Step 1: Setting Up Dockerfile

Here's the full dockerfile you'll need.

FROM imbios/bun-node:18-slim AS deps
ARG DEBIAN_FRONTEND=noninteractive

# I use Asia/Jakarta as my timezone, you can change it to your timezone
RUN apt-get -y update && \
  apt-get install -yq openssl git ca-certificates tzdata && \
  ln -fs /usr/share/zoneinfo/Asia/Jakarta /etc/localtime && \
  dpkg-reconfigure -f noninteractive tzdata
WORKDIR /app

# Install dependencies based on the preferred package manager
COPY package.json bun.lockb ./
RUN bun install --frozen-lockfile

# Build the app
FROM deps AS builder
WORKDIR /app
COPY . .

RUN bun run build


# Production image, copy all the files and run next
FROM node:18-slim AS runner
WORKDIR /app

ARG CONFIG_FILE
COPY $CONFIG_FILE /app/.env
ENV NODE_ENV production
# Uncomment the following line in case you want to disable telemetry during runtime.
# ENV NEXT_TELEMETRY_DISABLED 1

COPY --from=builder  /app/.next/standalone ./

EXPOSE 3001

ENV PORT 3001

CMD ["node", "server.js"]
Enter fullscreen mode Exit fullscreen mode

Step 2: Custom Shell Script

Create a custom shell script ./build.sh.

#!/bin/bash
set -e

# Run Next.js build with passed arguments
next build "$@"

# Copy files only if not in a CI environment
if [ -z "$CI" ]; then
  cp -r ./public ./.next/standalone/public
  cp -r ./.next/static ./.next/standalone/.next/static
fi
Enter fullscreen mode Exit fullscreen mode

Common Errors and Troubleshooting

I ran into some issues during my first attempt, especially errors prefixed with node:. I fixed them by using imbios/bun-node instad of oven/bun as the base image. Becase we need Node.js fallback for Bun's not yet implemented features.

Conclusion

By following this guide, you should have a Next.js app deployed, mimicking the Vercel deployment process, with Bun and Docker. Feel free to tweak and optimize the setup according to your project's needs.

What's Next?

Share this guide if you found it useful and leave a comment if you have any questions or improvements. Stay tuned for more!

Top comments (3)

Collapse
 
lieranderl profile image
Evgenii Fedotov

Why is the application running on Node.js instead of a Bun server? This is confusing and not related to the title of the article.
FROM node:18-slim AS runner
You just building with bun, but not deploying with bun server.

Collapse
 
deyvisonborges profile image
Deyvison Borges

Help me understand one thing:
Are you separating the server generated by next and the statistical files?

I've been having this dilemma for some time.

With the serverless framework, about 2 years ago, it was possible to have static in S3 and AWS Lambda had specific code (similar to the current autonomous one), which, when receiving an ISR or SSR event, generated an updated structure and updated the S3 .

Is this what you are proposing?

Collapse
 
bolanosdev profile image
Carlos Bolanos

been trying to deploy a next/remix app for hours your dockerfile worked like a charm

thanks for creating it