Skip to content

Instantly share code, notes, and snippets.

@vhamed
Forked from kocisov/next_nginx.md
Created September 24, 2021 21:40
Show Gist options
  • Select an option

  • Save vhamed/1afba5a341448acf29ad0ffccfcd7af4 to your computer and use it in GitHub Desktop.

Select an option

Save vhamed/1afba5a341448acf29ad0ffccfcd7af4 to your computer and use it in GitHub Desktop.

Revisions

  1. @kocisov kocisov revised this gist Jul 20, 2021. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions next_nginx.md
    Original file line number Diff line number Diff line change
    @@ -61,6 +61,8 @@ sudo nginx -t # check syntax errors
    sudo systemctl restart nginx
    ```

    #### Run `certbot` command

    ```bash
    sudo certbot --nginx -d example.com -d www.example.com
    # certbot will guide you through setting up the certificate and different options of redirecting, ...
  2. @kocisov kocisov revised this gist Jul 20, 2021. 1 changed file with 84 additions and 94 deletions.
    178 changes: 84 additions & 94 deletions next_nginx.md
    Original file line number Diff line number Diff line change
    @@ -1,142 +1,132 @@
    # How to setup next.js app on nginx with letsencrypt
    > next.js, nginx, reverse-proxy, ssl
    # How to setup Next.js app on Nginx with letsencrypt

    > Next.js, Nginx with Reverse proxy, SSL certificate
    - UPDATE (07/20/2021):
    - This process got simplified over the years of this gist being out
    - Older version of this gist (without certbot): https://gist.github.com/kocisov/2a9567eb51b83dfef48efce02ef3ab06/33fdd88872a0801bdde58fccce430fa48737ae10
    - I would also now recommend deploying to [Vercel](https://vercel.com) if you don't need custom server support

    ## 1. Install Nginx, Node and certbot

    In your server console/terminal

    ### 1. Install nginx and letsencrypt
    ```bash
    $ sudo apt-get update
    $ sudo apt-get install nginx letsencrypt
    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

    #### Also enable Nginx in ufw

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

    ### 2. Edit our default nginx site file
    ## 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

    ```bash
    $ sudo vim /etc/nginx/sites-available/default
    sudo vim /etc/nginx/sites-available/default
    ```

    ##### Content
    ```
    # *q is our domain
    server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root /var/www/html;
    index index.html index.htm index.nginx-debian.html;
    > You can keep everything other than server_name (domain) unchanged now
    server_name q*;
    - `example.com` should be changed to the domain you are setting up the app on

    location / {
    try_files $uri $uri/ =404;
    }
    # for letsencrypt
    location ~ /.well-known {
    allow all;
    }
    ```nginx
    server {
    # ...
    server_name example.com www.example.com;
    # ...
    }
    ```

    #### Restart nginx
    ```bash
    $ sudo nginx -t # check syntax errors
    $ sudo systemctl restart nginx
    ```

    ### 3. Setup letsencrypt
    ```bash
    # *q is our domain
    $ sudo letsencrypt certonly -a webroot --webroot-path=/var/www/html -d *q -d www.q*
    sudo nginx -t # check syntax errors
    sudo systemctl restart nginx
    ```

    #### Generate Strong DH Group
    ```bash
    $ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
    sudo certbot --nginx -d example.com -d www.example.com
    # certbot will guide you through setting up the certificate and different options of redirecting, ...
    ```

    #### Create nginx config file with Strong Encryption Settings
    ```bash
    $ sudo vim /etc/nginx/snippets/ssl-params.conf
    ```
    ##### Content
    ```
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
    ssl_ecdh_curve secp384r1;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;
    add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    ssl_dhparam /etc/ssl/certs/dhparam.pem;
    ```
    ## 4. Setup Reverse proxy

    #### Edit our nginx file
    ```
    # *q is our domain
    #### Edit our Nginx file again

    # redirect http to https
    server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name *q www.*q;
    return 301 https://$server_name$request_uri;
    }
    ```nginx
    # ...
    server {
    # listen on *:443 -> ssl; instead of *:80
    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;
    # ...
    server_name q*;
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    include snippets/ssl-params.conf;
    server_name example.com www.example.com;
    # ...
    location / {
    # reverse proxy for next server
    # 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 Connection "upgrade";
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
    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 next's _next folder and own handling
    # because of Next's error handling and _next folder
    # try_files $uri $uri/ =404;
    }
    location ~ /.well-known {
    allow all;
    }
    # ...
    }
    ```

    #### Restart nginx again
    #### Restart Nginx again

    ```bash
    $ sudo service nginx restart
    sudo nginx -t # check syntax errors
    sudo systemctl restart nginx
    ```

    ### 4. Setup next.js app
    ## 4. Setup Next.js app

    ```bash
    $ yarn build # build our app for production (npm build script: next build)
    $ yarn global add pm2 # install pm2 to keep next app alive forever*
    # 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 (npm start script: next start)
    $ pm2 stop next # for stopping app
    pm2 start npm --name "next" -- start # start next app
    pm2 stop next # for stopping app
    ```

    # We are done
    Now you have next.js app up and running on nginx reverse proxy with ssl!

    > Congratulations!
    Now you have the Next.js app up and running on Nginx Reverse proxy with SSL on your https://domain.
  3. @kocisov kocisov created this gist Mar 29, 2017.
    142 changes: 142 additions & 0 deletions next_nginx.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,142 @@
    # How to setup next.js app on nginx with letsencrypt
    > next.js, nginx, reverse-proxy, ssl
    ### 1. Install nginx and letsencrypt
    ```bash
    $ sudo apt-get update
    $ sudo apt-get install nginx letsencrypt
    ```
    #### Also enable nginx in ufw
    ```bash
    # after installing nginx!
    $ sudo ufw allow 'Nginx Full'
    ```

    ### 2. Edit our default nginx site file
    ```bash
    $ sudo vim /etc/nginx/sites-available/default
    ```
    ##### Content
    ```
    # *q is our domain
    server {
    listen 80 default_server;
    listen [::]:80 default_server;
    root /var/www/html;
    index index.html index.htm index.nginx-debian.html;
    server_name q*;
    location / {
    try_files $uri $uri/ =404;
    }
    # for letsencrypt
    location ~ /.well-known {
    allow all;
    }
    }
    ```
    #### Restart nginx
    ```bash
    $ sudo nginx -t # check syntax errors
    $ sudo systemctl restart nginx
    ```

    ### 3. Setup letsencrypt
    ```bash
    # *q is our domain
    $ sudo letsencrypt certonly -a webroot --webroot-path=/var/www/html -d *q -d www.q*
    ```

    #### Generate Strong DH Group
    ```bash
    $ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
    ```

    #### Create nginx config file with Strong Encryption Settings
    ```bash
    $ sudo vim /etc/nginx/snippets/ssl-params.conf
    ```
    ##### Content
    ```
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
    ssl_ecdh_curve secp384r1;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;
    add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    ssl_dhparam /etc/ssl/certs/dhparam.pem;
    ```

    #### Edit our nginx file
    ```
    # *q is our domain
    # redirect http to https
    server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name *q www.*q;
    return 301 https://$server_name$request_uri;
    }
    server {
    # listen on *:443 -> ssl; instead of *:80
    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;
    server_name q*;
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    include snippets/ssl-params.conf;
    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_cache_bypass $http_upgrade;
    # we need to remove this 404 handling
    # because next's _next folder and own handling
    # try_files $uri $uri/ =404;
    }
    location ~ /.well-known {
    allow all;
    }
    }
    ```

    #### Restart nginx again
    ```bash
    $ sudo service nginx restart
    ```

    ### 4. Setup next.js app
    ```bash
    $ yarn build # build our app for production (npm build script: next build)
    $ yarn global add pm2 # install pm2 to keep next app alive forever*

    # run start/stop
    $ pm2 start npm --name "next" -- start # start next app (npm start script: next start)
    $ pm2 stop next # for stopping app
    ```

    # We are done
    Now you have next.js app up and running on nginx reverse proxy with ssl!