Creating dockerized NextJS Application
Tags: nextjs, docker
Published: 2021-08-16 12:41:55

##### Resources:
- [Create NextJS docker container](https://blog.zack.computer/docker-containers-nodejs-nextjs)

##### Table of content:
- [Create NextJS app](#create-next-app)
- [Dockerize NextJS app](#dockerize-next-app)
- [Deploy dockerized app to AWS EB](https://dev.to/bnn1/deploying-dockerized-nextjs-app-to-aws-eb-part-2-deployment-to-beanstalk-47pj) - next part
- [Add custom domain](https://dev.to/bnn1/deploying-dockerized-nextjs-app-to-aws-eb-part-3-setting-custom-domain-45bm) - part 3
- [Set up redirects](https://dev.to/bnn1/deploying-dockerized-nextjs-app-to-aws-elastic-beanstalk-part-4-setting-redirects-48h9) - part 4

Hello everyone.

I assume that you already have Docker, NodeJS and YARN installed.  

<a name="create-next-app"></a>
## Create NextJS app    
To create a new Nextjs app execute `yarn create next-app app-name` or you can pick an example app from [there](https://github.com/vercel/next.js/tree/canary/examples) and create a new app with supplied command.  
I'm going to pick [blog starter example](https://github.com/vercel/next.js/tree/canary/examples/blog-starter-typescript).
In the `How to use` section copy command 
```
yarn create next-app --example blog-starter-typescript blog-starter-typescript-app
```
paste it in your terminal and hit `enter`. 

<a name="dockerize-next-app"></a>
## Dockerize NextJS app    
Open [this awesome post](https://blog.zack.computer/docker-containers-nodejs-nextjs#final-dockerfile) and copy the final version of docker configuration.  
Inside the root folder of your project (where `package.json` file is) create a new file named `Dockerfile`, paste copied configuration into it.   
We need to tweak it a little (otherwise AWS will complain - try out yourself without deleting if you're curious): 
1. delete image aliases (`AS %alias_name%` part of `FROM` statement)
1. replace used aliases with image indices (`--from=deps` becomes `--from=0` and `--from=BUILD_IMAGE` becomes `--from=1`)  

Our final Dockerfile:    
```
# dependencies image
FROM node:14-alpine
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile

# build image
FROM node:14-alpine
WORKDIR /app
COPY --from=0 /app/node_modules ./node_modules
COPY . .
RUN yarn build
RUN rm -rf node_modules
RUN yarn install --production --frozen-lockfile --ignore-scripts --prefer-offline

# build output image
FROM node:14-alpine

ENV NODE_ENV production

RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
WORKDIR /app
COPY --from=1 --chown=nextjs:nodejs /app/package.json /app/yarn.lock ./
COPY --from=1 --chown=nextjs:nodejs /app/node_modules ./node_modules
COPY --from=1 --chown=nextjs:nodejs /app/public ./public
COPY --from=1 --chown=nextjs:nodejs /app/.next ./.next

USER nextjs

EXPOSE 3000

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

Also create `.dockerignore` file near `Dockerfile` and insert two directory names into it: 
```
node_modules
.next
```  
To make sure it works run the following commands:
- `docker build -t example-nextjs-app .` - builds our image
- `docker run -p 3000:3000 example-nextjs-app` - runs our image  

Now open `localhost:3000` in your browser - you should see your app up and running. Yay =)  
To stop docker image either kill (close) the terminal or stop the image:
1. execute command `docker ps`
1. copy container id
1. execute command `docker stop container id`

In the [next part](https://dev.to/bnn1/deploying-dockerized-nextjs-app-to-aws-eb-part-2-deployment-to-beanstalk-47pj) we are going to deploy our application to AWS Elastic Beanstalk. Hope to see you in the  =)

Thanks for reading.