(5) How to use Nginx to proxy requests to NestJS and serve static resources for Next.js
The previous post deployed NestJS and Next.js services using
docker-compose
.
Now we can access the services through the Public IP address of the EC2 instance.
Since our NestJS and Next.js services are deployed on different ports
for example NestJS on port 3008
and Next.js on port 3009
,
we need to access the Next.js service through 54.166.251.146:3009
Also, when Next.js calls the NestJS API internally, it needs to specify the port as well.
const data = await fetch('http://54.166.251.146:3008/api/get-data', { method: 'get' });
1、How to proxy NestJS API services for a Next.js project.
1、In the development environment, you can use webpack's proxy to forward API requests to the backend service.
So, originally you need to call the API (including port 3008) like this: http://54.166.251.146:3008/api/get-data
After using webpack's proxy (without a port): http://54.166.251.146/api/get-data
(How to use webpack's proxy to forward services is not elaborated here.)
// you can write these code on development environment of Nextjs project,
// No need to specify 3008 port, because webpack proxy has forwarded the service for you
const data = await fetch('/api/get-data', { method: 'get' });
2、Forwarding services in a production environment.
Forwarding services in a production environment is done without webpack, as webpack is only used during development and build phases.
To successfully forward NestJS services, we need an nginx
server to act as a proxy.
2.1、Configure Next.js server to forward "/" to the Next.js service.
# Match frontend route URLs and forward requests to SSR server
location / {
# Because it is a docker deployment of the whole set of services, the host here is not the traditional 127.0.0.1 or localhost, but the name of the docker container ssr
proxy_pass http://ssr:3000;
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;
}
Here it is important to pay very close attention:
Normally, proxy_pass is set to: proxy_pass http://localhost:3000;
Our service is deployed using Docker, so the proxy pass needs to use the Docker service's name instead of localhost. For example, if the Next.js service is named ssr
in the docker-compose file, the proxy pass should be set to proxy_pass http://ssr:3000;
.
2.2、nginx hosts the static resources of Next.js.
It's well known that frontend is very sensitive to performance, so it's necessary to set up caching for static resources to speed up user access.
# Provide static files under the /_next/static/ directory using the alias method
location /_next/static/ {
# "/ssr/standalone/.next/static/" store js,css bundle or chunks
alias $root/ssr/standalone/.next/static/;
# Set cache expiration time to 1 year
expires 1y;
# Set up strong caching
add_header Cache-Control "public, max-age=31536000, immutable";
}
# Provide static files under the /public/ directory using the alias method
location /public/ {
# "/ssr/standalone/public/" store images and media ...
alias $root/ssr/standalone/public/;
# Set cache expiration time to 1 year
expires 1y;
# Set up strong caching
add_header Cache-Control "public, max-age=31536000, immutable";
}
After setting up caching, you can see that static resources are accessed from disk on the second visit, rather than requesting the server again.
This undoubtedly reduces server load and speeds up resource access.
2.3、Forwarding a NestJS service.
In a Next.js project, to differentiate which are API services, we usually add the prefix /api to the request URL.
The configuration for nginx forwarding to a NestJS service is as follows:
location /api/ {
# Because it is a docker deployment of the whole set of services, the host here is not the traditional 127.0.0.1 or localhost, but the name of the docker container nestjs-app
proxy_pass http://nestjs-app:3008;
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;
}
Then in the Next.js code, we don't need to include the 3008 port number, ensuring consistency with the development environment.:
const data = await fetch('/api/get-data', { method: 'get' });
2.4、The complete Nginx configuration is as follows:
server {
# Access services via "/"
listen 80;
# Define the root directory variable
set $root /app;
root $root;
# Match frontend route URLs and forward requests to SSR server
location / {
# Because it is a docker deployment of the whole set of services, the host here is not the traditional 127.0.0.1 or localhost, but the name of the docker container ssr
proxy_pass http://ssr:3000;
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;
}
# Provide static files under the /_next/static/ directory using the alias method
location /_next/static/ {
alias $root/ssr/standalone/.next/static/; # 映射到 Next.js 静态文件目录
}
# Provide static files under the /public/ directory using the alias method
location /public/ {
alias $root/ssr/standalone/public/;
}
# Match backend API URLs and forward requests to the backend server
location /api/ {
# Because it is a docker deployment of the whole set of services, the host here is not the traditional 127.0.0.1 or localhost, but the name of the docker container nestjs-app
proxy_pass http://nestjs-app:3008;
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;
}
# Other static files (e.g., favicon.ico)
location = /favicon.ico {
alias $root/ssr/standalone/public/favicon.ico;
}
}
2.5、Upload the nginx.conf
to /app/nginx
on EC2.
You can upload the local nginx.conf to the /app/nginx directory via Termius
by dragging and dropping.
Then, in the terminal, navigate to the /app directory and restart the nginx service.
docker-compose up --build nginx
So far, you can access your Next.js service via http://54.166.251.146
, with all Next.js static resources being served by nginx for faster speed.
Next article: How to manage CI/CD (Continuous Integration/Continuous Delivery) with Git Actions.