Implementing Gray Release with Nginx, Docker, and NestJS
This guide explains how to set up a gray‑release (canary) deployment using Nginx as a reverse‑proxy gateway, Docker containers for isolation, and two versions of a NestJS service, with traffic split controlled by cookies and configurable percentages.
Software releases are usually iterative, and new versions are tested with a gray‑release system that can route a portion of traffic to the new code while keeping the rest on the stable version, reducing the impact of potential bugs.
We first create two versions of a NestJS application. The first version is generated with:
npx nest new gray_test -p npmand started using:
npm run startAfter confirming the service runs (you should see a "Hello World" response), we modify the AppService and the listening port to obtain a second version.
Next, we run two Nginx containers to act as the gateway layer. Using Docker Desktop we pull the official Nginx image and start the first container named gray1 mapping host port 82 to container port 80 . The container is then copied to the host:
docker cp gray1:/etc/nginx/conf.d ~/nginx-configWe edit the copied default.conf to add a location block that rewrites /api/ requests and proxies them to the Nest service:
location ^~ /api {
rewrite ^/api/(.*)$ /$1 break;
proxy_pass http://192.168.1.6:3001;
}A second Nginx container ( gray2 ) is started with host port 83 mapped to 80 and the local ~/nginx-config directory mounted to /etc/nginx/conf.d inside the container, ensuring the configuration changes are reflected instantly.
To enable traffic splitting, we define multiple upstream groups in the Nginx config:
upstream version1.0_server {
server 192.168.1.6:3000;
}
upstream version2.0_server {
server 192.168.1.6:3001;
}
upstream default {
server 192.168.1.6:3000;
}Routing is then decided based on a cookie named version :
set $group "default";
if ($http_cookie ~* "version=1.0") {
set $group version1.0_server;
}
if ($http_cookie ~* "version=2.0") {
set $group version2.0_server;
}
location ^~ /api {
rewrite ^/api/(.*)$ /$1 break;
proxy_pass http://$group;
}When a request arrives, Nginx checks the cookie and forwards the request to the corresponding upstream, achieving gray‑release behavior. By adjusting the proportion of users that receive different version cookies (e.g., 80% get 1.0 , 20% get 2.0 ), you can gradually roll out new features or run A/B experiments.
The complete flow is: first request → traffic‑coloring service sets a version cookie according to the configured ratio → subsequent requests are routed by Nginx based on that cookie, allowing safe, incremental deployment and product testing.
In summary, Nginx’s reverse‑proxy capabilities combined with Docker isolation and simple cookie‑based routing provide a lightweight yet powerful gray‑release solution for backend services.
IT Services Circle
Delivering cutting-edge internet insights and practical learning resources. We're a passionate and principled IT media platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.