Tiếng Việt

Configure NGINX to host both Backend and Frontend servers in one AWS EC2 instance

avatar-square.jpg

Author

Khanh Mai

03/28/2023

Share

1_hq70yoQVaYG_vKQsyQ6rfw.jpg

My problem: I want to build a website with WordPress as the content management system. However, I don’t want to make use of its frontend template, instead, I will expose REST API from WordPress and have a dedicated Frontend WebApp using Nextjs.

Below is the diagram:

1_9JDIQkG6UOZdWg3VB7vOvg.webpPrerequisites:

  • Basic knowledge of SSH into an EC2 server (or any other VPS) and Ubuntu commands, or ability to read documentation for ubuntu commands.
  • I have a domain name mydomain.com
  • I purchased a wildcard SSL certificate for my domain: *.mydomain.com
  • I already setup SSL for my domain: *.mydomain.com
  • I created manually an AWS EC2 instance.
  • I have a Wordpress backend service to serve REST API at port 8000
  • I also have a Wordpress CMS app running at port 8000
  • I have a frontend app running at port 3001

*Please note that you’re freely to choose the port number.

I choose to use Nginx as a reverse proxy server to configure the domain.

 

Now, let’s jump into the main objective of this blog post.

Step 0:

  • Navigate to `/etc/nginx/sites-enabled/` and edit default file using sudo vim default
  • Better to backup it first by the command mv default defaultbk

Step 1: Configure Nextjs Frontend webapp at port 3001

1_36xC8vGSdwENL11lUHQ0zg.webpwe are at this part

#Nextjs FE app: remove www to avoid canonnical issue
server {
       listen 80;
       listen 443 ssl;

       # Certificate
       ssl_certificate /etc/nginx/ssl/STAR_mydomain.crt;

       # Private Key
       ssl_certificate_key /etc/nginx/ssl/STAR_mydomain.key;

       server_name http://mydomain.com www.mydomain.com;
       return 301 https://mydomain.com$request_uri;
}

#Nextjs FE app: force ssl for mydomain.com (main domain)
server {
        listen 80;
        server_name http://mydomain.com mydomain.com www.mydomain.com;
        return 301 https://mydomain.com$request_uri;
}

#Nextjs FE app: point main domain (Frontend) to port 3001 of Nextjs
server {
       listen 443 ssl;
       listen [::]:443 ssl;
 
       server_name mydomain.com;
       # Certificate
       ssl_certificate /etc/nginx/ssl/STAR_mydomain.crt;

       # Private Key
       ssl_certificate_key /etc/nginx/ssl/STAR_mydomain.key;
       location / {
               proxy_pass http://localhost:3001;
               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;
       }
}

Step 2: Configure the REST API:

1_IpNXpt1ofFBKpdu9w6HM7w.webpwe are at this part

#REST API: force ssl for api.mydomain.com (wordpress backend)
server {
        listen 80;
        server_name api.mydomain.com;
        return 301 https://api.mydomain.com$request_uri;
}

#REST API: point api.mydomain.com to port 8000
server {
        listen 443 ssl;
        listen [::]:443 ssl;

        server_name api.mydomain.com http://api.mydomain.com;
        # Certificate
        ssl_certificate /etc/nginx/ssl/STAR_mydomain.crt;

        # Private Key
        ssl_certificate_key /etc/nginx/ssl/STAR_mydomain.key;
        location / {
               proxy_pass http://localhost:8000;
        }
}

Step 3: Configure the CMS

1_7AtkF4RGNQ1_16At0HNoZA.webpwe are at this part

#CMS: force ssl for cms.mydomain.com (wordpress cms)
server {
        listen 80;
        server_name cms.mydomain.com http://cms.mydomain.com;
        return 301 https://cms.mydomain.com$request_uri;
}

#CMS: point cms.mydomain.com to port 8000
server {
        listen 443 ssl;
        listen [::]:443 ssl;

        server_name cms.mydomain.com;
        # Certificate
        ssl_certificate /etc/nginx/ssl/STAR_mydomain.crt;

        # Private Key
        ssl_certificate_key /etc/nginx/ssl/STAR_mydomain.key;
        location / {
               proxy_pass http://localhost:8000;
               proxy_set_header Host $http_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;
        }
}

Full configuration


#Nextjs FE app: remove www to avoid canonnical issue
server {
       listen 80;
       listen 443 ssl;

       # Certificate
       ssl_certificate /etc/nginx/ssl/STAR_mydomain.crt;

       # Private Key
       ssl_certificate_key /etc/nginx/ssl/STAR_mydomain.key;

       server_name http://mydomain.com www.mydomain.com;
       return 301 https://mydomain.com$request_uri;
}

#Nextjs FE app: force ssl for mydomain.com (main domain)
server {
        listen 80;
        server_name http://mydomain.com mydomain.com www.mydomain.com;
        return 301 https://mydomain.com$request_uri;
}

#Nextjs FE app: point main domain (Frontend) to port 3001 of Nextjs
server {
       listen 443 ssl;
       listen [::]:443 ssl;
 
       server_name mydomain.com;
       # Certificate
       ssl_certificate /etc/nginx/ssl/STAR_mydomain.crt;

       # Private Key
       ssl_certificate_key /etc/nginx/ssl/STAR_mydomain.key;
       location / {
               proxy_pass http://localhost:3001;
               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;
       }
}

#REST API: force ssl for api.mydomain.com (wordpress backend)
server {
        listen 80;
        server_name api.mydomain.com;
        return 301 https://api.mydomain.com$request_uri;
}

#REST API: point api.mydomain.com to port 8000
server {
        listen 443 ssl;
        listen [::]:443 ssl;

        server_name api.mydomain.com http://api.mydomain.com;
        # Certificate
        ssl_certificate /etc/nginx/ssl/STAR_mydomain.crt;

        # Private Key
        ssl_certificate_key /etc/nginx/ssl/STAR_mydomain.key;
        location / {
               proxy_pass http://localhost:8000;
        }
}

#CMS: force ssl for cms.mydomain.com (wordpress cms)
server {
        listen 80;
        server_name cms.mydomain.com http://cms.mydomain.com;
        return 301 https://cms.mydomain.com$request_uri;
}

#CMS: point cms.mydomain.com to port 8000
server {
        listen 443 ssl;
        listen [::]:443 ssl;

        server_name cms.mydomain.com;
        # Certificate
        ssl_certificate /etc/nginx/ssl/STAR_mydomain.crt;

        # Private Key
        ssl_certificate_key /etc/nginx/ssl/STAR_mydomain.key;
        location / {
               proxy_pass http://localhost:8000;
               proxy_set_header Host $http_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;
        }
}

Last step:

  • Reload and restart Nginx with sudo systemctl reload nginx and sudo systemctl restart nginx

I hope this helps not only with the configuration but the overall understanding of your own use cases.

Share

Related Articles

Nginx-ssl-thumbnail.png

Devops

Add SSL to a website on AWS EC2 Ubutnu with Nginx

WordPress-logotype-standard.png

Technology

WORDPRESS: WORKING WITH APIs

Contact Us