Getting started w/ Next.JS + Docker
by Adam Colpitts May 09, 2019
Getting started w/ Next.JS + Docker

Docker is an incredibly useful tool for running virtual machines inside of Containers on your local machine, and inside the cloud alike.  This greatly simplifies several aspects of deploying a complex web application, including things like horizontal scaling (if your architecture plans for this).  This, coupled with a service like AWS Fargate, means the sky 's the limit for your application.

Next.js is a solid framework for building Server Rendered React applications, and greatly simplifies several complexities that come along with rendering React applications on the server.  One of my favorite features of Next.js is that it builds the Single Page Application on the client through caching the page loads. This makes the app much snappier than trying to push the whole client code in several chunks all at once. They have great documentation, and if you are interested in learning more about Next.js head over to https://nextjs.org/#features

In this article, we will look at setting up Docker to build a production version of our Next.js application as a Docker image. We will also configure Docker to run this image inside of a container locally.  The idea here is to do development on your local machine so that we get Hot Module Reloading (HMR), and all the other handy development tools we prefer and then run a production version of the application inside a Docker container.  Once you are happy with the way your application works / performs - you can then deploy the container into the cloud to make your application accessible to its audience.

Step One: Building a bare bones Next.js app

1. From the folder on your computer where you would like to begin working, create a new directory and initialize our project.

mkdir docker-nextjs
cd docker-nextjs
npm init -y
1. Install Next.js, React, and ReactDOM modules

npm i next react react-dom

1. Add Next.js scripts to our script block in

package.json
“scripts”: {
  “dev”: “next”,
  “build”: “next build”,
  “start”: “next start”
}

1. The only thing left to do in order to have a bare-bones Next.js application that is able to fire up is to add a `/pages` directory along with an `index.jsx` for Next.js to serve.  This is a really powerful feature of Next.js as any valid react component that we place in the folder will be available via page level routing. Meaning if we place a valid `about.jsx` component inside of the `/pages` folder, when Next.js is running we can hit `http://localhost:3000/about` (swap the host and port with your dev env). Ok, with that out of the way, lets create a simple `index.jsx` file to serve as our landing / home page.

mkdir pages 
touch pages/index.jsx

1. Now inside of

pages/index.jsx
pate the following
import React, { Component } from ‘react’;


class Index extends Component {
 render() {
   return (
     <div>Welcome to the public landing page.  A.k.a The Home Page!!</div>
    )
 }
} export default Index;
1. You can start the application by running `npm run dev` from the project root and visiting
http://localhost:3000
in a Browser. Congratulations, you now have a basic Next.js application up and running, and you are now ready to build the NEXT best thing on the web!

Screen Shot 2019-05-09 at 9.28.24 AM

Step Two: Commit your changes

1. Ok before we go any further, this is a great time to commit our changes.  With git installed lets create a

.gitignore
file and make our first commit.

touch .gitignore
2. Add the following folders to the ignore file `.next` and `node_modules`

node_modules.next
3. Add and commit this intial project files
git init
git add .
git commit -m “feat: add index page”

Step Three: Containerization - creating a Dockerfile

Prerequisites:

Docker builds images by reading the instructions from a special `Dockerfile`.  This is a text file that contains all the commands needed to build an image of your project.  Don’t worry too much about the specifics; if your not familiar as you can always read more in the docs: https://docs.docker.com/develop/develop-images/dockerfile_best-practices/

Ok, with that out of the way, we now have a Next.js application that runs fine locally in `development` mode, there is HMR and all that fun stuff, but what about when it comes time to deploy the production grade application?  Docker simplifies this in several ways, but instead of going heavy on the copy - lets get into some code!

1. Ensure you have Docker and Docker CLI installed on your machine.  Please see `Prerequisites` above for more info.

2. Create a new file called `Dockerfile` in the root of your project and add the following:

FROM node:10

# Setting working directory. All the path will be relative to WORKDIR

WORKDIR /usr/src/app

# Installing dependencies

COPY package*.json ./

RUN npm install

# Copying source files

COPY . .

# Building app

RUN npm run build

# Running the app

CMD [ "npm", "start" ]

3. To build the docker image, run the following command from the root of your project.  Please note the period on the end of the cmd. This specified the current working directory.

docker build -t <your_username>/docker-nextjs

Step 4: Running our new docker image in a container

1. All that is left to do now is fire up our new container in Docker, and test it out.

docker run -d -p 3333:3000 <your_username>/docker-nextjs:latest
The command above runs our new image, `-p` flag binds port `3000` (the app is running on this port inside the container) to the local port `3333` on our dev machine, which means we should now be able to hit our application in a Browser at `http://localhost:3333`

Nice work, you now have a Server Side Rendered React application you are ready to extend, and when it comes time you are ready to deploy your app as a Docker image.

Ready to transform your business?