Skip to content

Self Host and Deploy Nextjs without Vercel platform

Posted on:December 4, 2022 at 11:11 AM

This article teaches you how to self host Nextjs websites and deploy them without using the Vecel platform to public clouds such as AWS, Azure, and Google Cloud Platform. You will learn different rendering approaches, infrastructure requirements, deployment steps, and things to consider when deploying websites.

Next.js is an open-source, production-ready, and opinionated React framework. React is only a UI library and does not provide tools to run React websites on servers. Nextjs makes it easy to build and run React applications on servers or statically.

If you are starting from scratch and do not have existing cloud infrastructure, then Vercel, CloudFlare, Netlify, and many other vendors offer SaaS services that might fit your needs.

The following section examines why you should consider self hosting a Nextjs website.

Why self host a Nextjs website?

It would be best to decide on the rendering strategy for your Nextjs website, as that will dictate the hosting infrastructure. The following section explains various rendering strategies for a Nextjs website.

Rendering Strategies

There are two main strategies for rendering a Nextjs website: static generation and server-side. Static rendering is appropriate when the content is not frequently updated, such as marketing pages, documentation, blogs, and catalogs. The server-side rendering is suitable for dynamic content.

Static Generation

Nextjs makes it easy to generate pages at build time and recommends it as the default and go-to approach. The statically generated websites can be hosted on a cloud storage and cached on a Content Delivery Network. This approach does not require a server and is low-cost, highly scalable, and easy to implement.

Infrastructure

To deploy a statically generated website, you need cloud storage such as AWS S3 and a Content Delivery Network such as AWS CloudFront.

Infrastructure for hosting a statically generated website

Figure: Infrastructure for hosting a statically generated website

Deployment Steps

Deploying a statically generated Nextjs website requires the following steps:

1. Update package.json for static generation

Nextjs CLI provides an export command for static generation. Edit the package.json file and update the build script to include the next export.

"scripts": {   "build": "next build && next export" }
2. Static Generation

Run the npm run build script to generate the static website.

npm run build

The static website is generated into a folder named out.

3. Copy files to Cloud Storage

Copy statically generated files in the out folder to cloud storage. The copied files should be publicly accessible and have caching age specified. Use the following command to copy files to AWS S3 storage.

aws s3 sync ./out s3://<bucket> --acl public-read --cache-control max-age=<seconds>
4. Invalidate CDN cache

The Content Delivery Network cache must be invalidated to serve the new files. Use the following command to invalidate a cache on AWS CloudFront.

aws cloudfront create-invalidation --distribution-id <distribution-id> --paths "/path-to-website"

Considerations

After working with large Nextjs websites with tens of thousands of pages and serving millions of visitors, I would recommend considering the following points when deciding the suitability of static generation:

The beauty of Nextjs is that it allows you to decide the rendering approach on a page level. Some pages are suitable for static generation, and some require server-side rendering. Nextjs makes it easy to switch between rendering methods with minimal code changes.

The following teaches you Server Side rendering and Incremental Static regeneration approaches for rendering a page on request.

Server-side rendering (SSR)

Server-side rendering is suitable for pages with dynamic or personalized content where caching is impossible. A Nodejs server is used to generate the page on each request. The Incremental Static Regeneration (ISR) is similar but with the addition of Nextjs caching the generated page for a configurable duration.

Infrastructure

To deploy a server-side rendered Nextjs website following infrastructure pieces are needed:

Infrastructure for hosting Nextjs Server-side Rendered or Incremental Static Regenerated website

Figure: Infrastructure for hosting Nextjs Server-side Rendered or Incremental Static Regenerated website

You have many options for running the Nodejs server, from running a compute instance to running a docker container in Kubernetes. My recommendation is to use Docker for flexibility and scalability.

Nextjs Docker Image

The Nextjs docker-compose example is a good starting point that showcases how to package Nextjs code into a docker image. Docker opens up many deployment options, such as AWS EC2 instances, Azure App, Kubernetes, and more. Here is the code of a sample Dockerfile for a Nextjs website:

# filename: Dockerfile
# Use an official Node.js runtime as a parent image
FROM node:18-bullseye-slim

# Set the working directory to /app
WORKDIR /app

# Copy package.json and package-lock.json to the container
COPY package*.json ./

# Install dependencies
RUN npm install --production

# Copy the rest of the application code to the container
COPY . .

# Build the Next.js app
RUN npm run build

# Expose port 3000
EXPOSE 3000

# Start the Next.js app
CMD ["npm", "start"]

Copy the above code into a file name Dockerfile in the root of your Nextjs project. Run the following commands to launch a docker instance on your machine:

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

Deployment Steps

To deploy a server-side rendered Nextjs website following steps are required:

1. Build a docker image

To make deployment easy, configure Nextjs to output a standalone folder that contains the server code bundle. Then run the docker build command to generate a docker image containing the Nextjs server (the standalone folder) and client (the .next/static folder) bundles.

docker build .
2. Copy static assets to cloud storage

The .next/static folder contains static assets that run in the browser. A Nodejs server can serve this folder, but do it from a CDN for the best performance.

There is no need to invalidate the CDN, as any code changes will result in new files with unique names.

3. Deploy the docker image

You can quickly deploy to most public cloud computing platforms by using Docker for packing the website. Follow the steps for your chosen computing platform. Check out the Nextjs GitHub repository that contains many implementation and integration examples.

For optimal performance on incremental static regeneration, refer to instructions on ISR self-hosting.

Server-side Rendering Considerations

Summary

Nextjs takes the pain out of running React websites in production. Nextjs is a zero-configuration meta-framework that supports static generation, incremental static regeneration, server-side rendering, file system-based routing, and a lot more features out of the box.

There are many options for deploying and hosting Nextjs websites. Spend time upfront deciding on a suitable rendering strategy as that will define the infrastructure and deployment approach.