Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
How to setup next.js app on nginx with letsencrypt

How to setup Next.js app on Nginx with letsencrypt

Next.js, Nginx with Reverse proxy, SSL certificate

1. Install Nginx, Node and certbot

In your server console/terminal

cd ~ # go to the current user's home directory
curl -sL https://deb.nodesource.com/setup_14.x -o nodesource_setup.sh
sudo bash nodesource_setup.sh

sudo apt update
sudo apt install nginx nodejs certbot python3-certbot-nginx

Also enable Nginx in ufw

sudo ufw allow 'OpenSSH' # needed for SSH connections
sudo ufw allow 'Nginx Full' # after installing Nginx!
sudo ufw enable

2. Setup letsencrypt with certbot

  • You will need to point your domain to your server's IP with DNS Record (with A record, ...)

Edit our default Nginx site file

sudo vim /etc/nginx/sites-available/default
Content

You can keep everything other than server_name (domain) unchanged now

  • example.com should be changed to the domain you are setting up the app on
server {
  # ...

  server_name example.com www.example.com;

  # ...
}

Restart nginx

sudo nginx -t # check syntax errors
sudo systemctl restart nginx

Run certbot command

sudo certbot --nginx -d example.com -d www.example.com
# certbot will guide you through setting up the certificate and different options of redirecting, ...

4. Setup Reverse proxy

Edit our Nginx file again

# ...

server {
  # ...

  server_name example.com www.example.com;

  # ...

  location / {
    # Reverse proxy for Next server
    proxy_pass http://localhost:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "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;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Port $server_port;

    # we need to remove this 404 handling
    # because of Next's error handling and _next folder
    # try_files $uri $uri/ =404;
  }

  # ...
}

Restart Nginx again

sudo nginx -t # check syntax errors
sudo systemctl restart nginx

4. Setup Next.js app

# assuming you have a GitHub repository for the app
git pull https://github.com/user/repo.git
cd repo
npm install # install app dependencies (or yarn install)
npm run build # build our app for production (or yarn build)

npm install -g pm2 # install pm2 for running our app detached

# run start/stop
pm2 start npm --name "next" -- start # start next app
pm2 stop next # for stopping app

We are done

Congratulations!

Now you have the Next.js app up and running on Nginx Reverse proxy with SSL on your https://domain.

@tylerpope

This comment has been minimized.

Copy link

@tylerpope tylerpope commented Nov 26, 2018

Thanks for this.

@vlavellauruit

This comment has been minimized.

Copy link

@vlavellauruit vlavellauruit commented Dec 31, 2018

Thank you very much for this :)

@kidow

This comment has been minimized.

Copy link

@kidow kidow commented Jan 4, 2019

What means 'Edit our nginx file'? what file?

@cdolek

This comment has been minimized.

Copy link

@cdolek cdolek commented Jan 10, 2019

@kidow What means 'Edit our nginx file'? what file?

nginx web server configuration file.

On linux based systems usually found at:

/etc/nginx/sites-available/some_name.conf

and may have a symbolic link at (or you can place your config file here as well):

 /etc/nginx/sites-enabled/some_name.conf
@juanslinger

This comment has been minimized.

Copy link

@juanslinger juanslinger commented Feb 7, 2019

Great job, you save me hours of work!!!

Just to improve some details, example.com has to be updated for *q

ssl_certificate /etc/letsencrypt/live/*q/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/*q/privkey.pem;

@slavic18

This comment has been minimized.

Copy link

@slavic18 slavic18 commented Jan 10, 2020

thanks man!

@js5882

This comment has been minimized.

Copy link

@js5882 js5882 commented Jan 13, 2020

It also works for me thanks for the gist.. One thing more which should be the primary thing that we have to open port 443 (https).for the server

@kocisov

This comment has been minimized.

Copy link
Owner Author

@kocisov kocisov commented Jan 13, 2020

It also works for me thanks for the gist.. One thing more which should be the primary thing that we have to open port 443 (https).for the server

Well, the sudo ufw allow 'Nginx Full' does that.

@TrejoCode

This comment has been minimized.

Copy link

@TrejoCode TrejoCode commented Feb 17, 2020

Hi, thanks for the help, I can visualize my Web now, but, I can't get the images and styles to load, the 404 error in / img returns to my console. Any suggestions?

@bmisanthropy

This comment has been minimized.

Copy link

@bmisanthropy bmisanthropy commented Sep 15, 2020

Thank you!

@disaada

This comment has been minimized.

Copy link

@disaada disaada commented Jan 26, 2021

where i should put my next.js app?

@kocisov

This comment has been minimized.

Copy link
Owner Author

@kocisov kocisov commented Jan 26, 2021

where i should put my next.js app?

Hello, that does not matter.
You can put the app anywhere you like. Afterwards, if you start it with pm2, Nginx will proxy that app based on the port and local ip.

But maybe /usr/src/app, maybe /var/www/app or even in home folder like ~/app.

@disaada

This comment has been minimized.

Copy link

@disaada disaada commented Jan 27, 2021

Hello, i put my project in home ~/disaada.github.io (is it okk to use this folder name? because its cloned from github) but when pm2 already online and i access it using my domain, its just loading for long time and failed to load the page and said "This site can’t be reached". What sould i do?

@kocisov

This comment has been minimized.

Copy link
Owner Author

@kocisov kocisov commented Jan 27, 2021

Yes, the name of the folder is alright as I mentioned before.
If the site can't be reached I would try to change Nginx configuration to a default state with your domain in place and test if it is working correctly with static files (eg. index.html).

If that works then I would also check if Nginx can reach the port of the app that runs in pm2.

@disaada

This comment has been minimized.

Copy link

@disaada disaada commented Jan 28, 2021

My bad. I forgot to add https security group at my cloud server. And now it works! I'm sorry. Big much thank you!

@kocisov

This comment has been minimized.

Copy link
Owner Author

@kocisov kocisov commented Jan 28, 2021

No problem, glad you got it resolved.

@chas13

This comment has been minimized.

Copy link

@chas13 chas13 commented Feb 8, 2021

Hi there, could anyone help with renewing the let's encrypt certificate, please?

sudo letsencrypt certonly -a webroot --webroot-path=/var/www/html -d mydomain.com -d www.mydomain.com

IMPORTANT NOTES:
 - The following errors were reported by the server:

   Domain: mydomain.com 
   Type:   unauthorized
   Detail: Invalid response from
   https://mydomain.com/.well-known/acme-challenge/kJKsq-0rKw_v9nf3oVLlg7l4xOiRy7nZcBkQyouVxt0
   [51.89.192.19]: "<html>\r\n<head><title>404 Not
   Found</title></head>\r\n<body bgcolor=\"white\">\r\n<center><h1>404
   Not Found</h1></center>\r\n<hr><center>"
@gigapoc

This comment has been minimized.

Copy link

@gigapoc gigapoc commented May 19, 2021

Thank you for this ! Really helpful and clear, A+ grade SSL certs !

@SpaceComet

This comment has been minimized.

Copy link

@SpaceComet SpaceComet commented Jun 2, 2021

By doing this do you lose the performance optimizations of Next.js?
I got this from the official doc:

Before deciding to use a custom server please keep in mind that it should only be used when the integrated router of Next.js can't meet your app requirements. A custom server will remove important performance optimizations, like serverless functions and Automatic Static Optimization.

@kocisov

This comment has been minimized.

Copy link
Owner Author

@kocisov kocisov commented Jun 3, 2021

By doing this do you lose the performance optimizations of Next.js?
I got this from the official doc:

Before deciding to use a custom server please keep in mind that it should only be used when the integrated router of Next.js can't meet your app requirements. A custom server will remove important performance optimizations, like serverless functions and Automatic Static Optimization.

Hello, no that is not the case, we are not using custom server in this guide.

@dryleaf

This comment has been minimized.

Copy link

@dryleaf dryleaf commented Jun 18, 2021

@kocisov, Could you please explain why we need to do 2. Edit our default nginx site file step? Seems like a duplicate from step 3 nginx file, as same configuration is present there.

@kocisov

This comment has been minimized.

Copy link
Owner Author

@kocisov kocisov commented Jun 18, 2021

@kocisov, Could you please explain why we need to do 2. Edit our default nginx site file step? Seems like a duplicate from step 3 nginx file, as same configuration is present there.

Hello, we do the second step because we need to tell Nginx that we want to serve on our domain before running letsencrypt.
This configuration file is also quite different in 3rd step because it's after generating certificates and we also set up proxy pass there.

@brunodesde1987

This comment has been minimized.

Copy link

@brunodesde1987 brunodesde1987 commented Jul 14, 2021

Thank you! 🙏

@kazi-shahin

This comment has been minimized.

Copy link

@kazi-shahin kazi-shahin commented Jul 29, 2021

Really useful. Thank you

@truongnc1997

This comment has been minimized.

Copy link

@truongnc1997 truongnc1997 commented Sep 2, 2021

Thanks you man

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment