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:
Prerequisites:
- 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 usingsudo vim default
- Better to backup it first by the command
mv default defaultbk
Step 1: Configure Nextjs Frontend webapp at port 3001
we 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:
we 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
we 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
andsudo systemctl restart nginx
I hope this helps not only with the configuration but the overall understanding of your own use cases.