How to Dockerize and Deploy a Next.js Application on Koyeb
Tags: nextjs, react, docker, tutorial
Published: 2021-05-12 10:20:20


## Introduction

Next.js is a popular React framework offering a wide range of features such as hybrid and server rendering, file-system routing, route pre-fetching, smart bundling, and more with near-zero configuration.

In this guide, we will showcase how to Dockerize a Next.js application and deploy it to Koyeb.

## Requirements

 To successfully follow and complete this tutorial, you need:
 - [Docker](https://docs.docker.com/get-docker/) installed on your machine
 - A [GitHub account](https://github.com/) to store our Docker image on the GitHub container registry
 - Have [configured Docker for use with GitHub Packages](https://docs.github.com/en/packages/guides/configuring-docker-for-use-with-github-packages)
 - A [Koyeb account](https://www.koyeb.com) to deploy and run our dockerized Next.js application

## Steps

To dockerize and deploy a Next.js application on Koyeb, you need to follow these steps:

1. [**Create a Hello World Next.js app or use an existing one**](#create-a-hello-world-next-js-app-or-use-an-existing-one)
2. [**Write the Dockerfile and build the Docker image**](#write-the-dockerfile-and-build-the-docker-image)
3. [**Push the Docker image to the GitHub container registry**](#push-the-docker-image-to-the-git-hub-container-registry)
4. [**Deploy the dockerized Next.js app on Koyeb**](#deploy-the-dockerized-next-js-app-on-koyeb)

## Create a Hello World Next.js app or use an existing one

If you already have an existing Next.js application you want to dockerize, you can jump to the next step.

Let's get started by creating a new Next.js application. In your terminal run the following command:

```bash
yarn create next-app
```

This command initializes all the files and configurations required to run a new Next.js application. During the installation process, you are asked to give your project a name.
This name is used to create the folder your project will be located and to seed the `package.json` name key.

Once the initialization complete, you can launch the Next.js application by running `yarn dev` on your project folder and opening your browser to `http://localhost:3000`.

You should land on the `Welcome to Next.js` page.

## Write the Dockerfile and build the Docker image

To Dockerize a Next.js app, you need to create a `Dockerfile` in your project folder containing the content below. In this guide, we use [Docker multi-stage build](https://docs.docker.com/develop/develop-images/multistage-build/) to keep the image layers size as small as possible and to ensure our image contains only what is needed to run.

The Dockerfile is composed of three different stages:

- The first one is used to install dependencies
- The second is used to build the Next.js app
- The last one is used to configure the runtime environment of the Next.js app

In this guide, we use the Node.js LTS version as the base image, if you need to use a specific version of Node, you can refer to the available tags [on the Docker Hub](https://hub.docker.com/_/node).

```dockerfile
FROM node:lts as dependencies
WORKDIR /my-project
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile

FROM node:lts as builder
WORKDIR /my-project
COPY . .
COPY --from=dependencies /my-project/node_modules ./node_modules
RUN yarn build

FROM node:lts as runner
WORKDIR /my-project
ENV NODE_ENV production
# If you are using a custom next.config.js file, uncomment this line.
# COPY --from=builder /my-project/next.config.js ./
COPY --from=builder /my-project/public ./public
COPY --from=builder /my-project/.next ./.next
COPY --from=builder /my-project/node_modules ./node_modules
COPY --from=builder /my-project/package.json ./package.json

EXPOSE 3000
CMD ["yarn", "start"]
```

To build the Docker image execute the following command:

```bash
docker build . -t ghcr.io/<YOUR_GITHUB_USERNAME>/my-project
```

This command will build the Docker image with the name `ghcr.io/<YOUR_GITHUB_USERNAME>/my-project`. Once the build is over, you can run a container using the image locally to validate everything is working as expected running:

```bash
docker run -p 3000:3000 ghcr.io/<YOUR_GITHUB_USERNAME>/my-project
```

Open your browser and navigate to `http://localhost:3000` to view your project landing page.

## Push the Docker image to the GitHub container registry

Since our Docker image is built and functional in our test, we can now upload it to the GitHub container registry. In your terminal run the command below to push the image.

```bash
docker push ghcr.io/<YOUR_GITHUB_USERNAME>/my-project
```

Within a few minutes, you will see your Docker image available on the GitHub container registry: `https://github.com/<YOUR_GITHUB_USERNAME>?tab=packages`.

## Deploy the dockerized Next.js app on Koyeb

It's now time to deploy our freshly dockerized Next.js application on Koyeb. On the Koyeb Control Panel, click the **Create App** button.

In the form, fill the `Docker image` field with the name of the image we previously created which should look like `ghcr.io/<YOUR_GITHUB_USERNAME>/my-project`.

Check the box `Use a private registry` and, in the select field, click **Create Registry Secret**.

A modal opens asking for:

* a name for the Secret which will be created, we can use for instance `gh-registry-secret`
* the registry provider to generate the secret containing your private registry credentials, in our case GitHub
* your GitHub username and password
Once you've filled all the fields, click the **Create** button.

In the *Ports* section, change the export port from `80` to `3000`, which is the port our Next.js app is listening on. This setting is required to let Koyeb know which port your application is listening to and properly route incoming HTTP requests. We don't need to change the *Path*, our app will be available at the root of our domain: `/`.

Give your App a name, i.e `my-next-js-project`, and click **Create App**

*You can add more regions to deploy your applications, set environment variables, and define the horizontal scaling according to your needs.*

You will automatically be redirected to the Koyeb App page where you can follow the progress of your Next.js application deployment. In a few seconds, once your app is deployed, click on the *Public URL* ending with `koyeb.app`.

Et voilà, your Next.js project is running on Koyeb!

Your Next.js app is now secured with native TLS encryption and benefits from all the Koyeb Serverless features including autoscaling, auto-healing, and a High-Performance Edge Network.