In this post I’ll explain a setup for one of my NextJS websites on elasticbeanstalk. You probably already know about what are NextJS, Nginx and elasticbeanstalk, so I’ll skip the introductory definitions.

I have a hybrid NextJS website. Some content is

  • SSG which stands for Static-Site Generated
  • SSR which stands for Server-Side Rendered

Hint: If you just have a static nextjs app, maybe this post will work better.

My hybrid NextJS website is running on an elasticbeanstalk service, single instance, on the ec2 t2.micro with 1G RAM.

At the time of the writing, I couldn’t chose running elb environments without a proxy. Only available options were Apache or Nginx. Since I’m more familiar with Nginx, I configured elb running on NodeJS 16 behind Nginx.

When I think about it, maybe running a NextJS app behind a proxy isn’t such a bad idea. When you build a NextJS app, you get plenty of static files in the next directory. Proxy servers like Apache and Nginx are better suited for serving statics.

First steps

You can run your Nextjs app on elastic beanstalk by simply uploading a package to your eb environment.

You don’t need to configure anything, default port will be whatever is defined in the PORT environment variable and will run on 8080 by default.

This simple script will prepare the app for uploading to eb environment.

#!/bin/bash

declare -r app_name="package-demo"
declare -r version="1.0"
# Stops execution of the script if error
set -e

export NODE_ENV=production
npm run build

zip -r app.zip .next pages public styles *.json *.js

Npm packages that require native libraries

You might have stumbled upon sharp issues when you installed it as a recommendation for NextJs image optimization. You might see something like this:

failed npm install sharp log

Sharp requires libvips, and it has something to do with permissions when deploying your app, better said in this github issue. But really this isn’t just a problem with sharp, it will affect any kind of npm library that uses native system libs. So, my solution is just add a pre build hook that installs all dependencies, except dev ones.

elastic beanstalk hooks for sharp spawn ENOEM issue

And the script – don’t forget to chmod +x it:

00_npm_install.sh

#!/bin/bash
set -e
EXIT_CODE=0

cd /var/app/staging
runuser -u webapp -- npm i --omit=dev || EXIT_CODE=$?
echo $EXIT_CODE

Serve static behind Nginx

Although Node app would probably do fine at serving a file, I think Nginx is faster. No need to burden the app with static request calls, when nginx can just call a sendfile.

elastic beanstalk nginx

What can be served only behind nginx is everything located in _next/static and favicon.ico.

00_application.conf

location ^~ /_next/static/ {
  alias /var/app/current/.next/static/;
  sendfile           on;
  sendfile_max_chunk 2m;
  access_log off;
  expires 30d;
  add_header Cache-Control public;
  tcp_nodelay off;
}

location = /favicon.ico {
  alias /var/app/current/public/favicon.ico;
  sendfile           on;
  sendfile_max_chunk 2m;
  access_log off;
  expires 30d;
  add_header Cache-Control public;
  tcp_nodelay off;
}

location / {
  proxy_pass          http://127.0.0.1:8080;
  proxy_http_version  1.1;

  proxy_set_header    Connection          $connection_upgrade;
  proxy_set_header    Upgrade             $http_upgrade;
  proxy_set_header    Host                $host;
  proxy_set_header    X-Real-IP           $remote_addr;
  proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
}

Add swap space

If you experience app crashes, probably your ec2 instance is too weak. If you don’t want to invest into stronger instance, a cheap workaround is adding swap space. Keep in mind that this solution will slow down your app deployments.

Add another hook, like in the picture above. Don’t forget to chmod +x it.

01_add_swap.sh

#!/bin/bash
set -e
EXIT_CODE=0

if [[ ! -f /swapfile ]]
then
  dd if=/dev/zero of=/swapfile bs=128M count=8
  chmod 600 /swapfile
  mkswap /swapfile
  swapon /swapfile
  swapon -s
else
  echo "Skipping add swap. Already defined!"
fi
echo $EXIT_CODE

The End

Read this If you’d like to ssh to elastic beanstalk ec2 instance and don’t know how.

I wrote several articles on configuring nextjs, maybe you’re interested.

All code is available in the Github repo https://github.com/amarjanica/demo-nextjs-elasticbeanstalk.


0 Comments

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *