How to Implement Gray Release in Nginx Using Cookies, Weights, IP, and Lua
This guide explains multiple Nginx gray‑release techniques—including cookie‑based routing with if and map directives, weight‑based upstream selection, source‑IP routing for separate or shared servers, and a Lua script solution—providing complete configuration snippets and practical tips.
Cookie‑Based Gray Release
Read the version cookie; if it equals V1 forward to server_01, if V2 forward to server_02, otherwise default to server_01.
1. Using if directive
upstream server_01 {
server 192.168.1.100:8080 max_fails=1 fail_timeout=60;
}
upstream server_02 {
server 192.168.1.101:8080 max_fails=1 fail_timeout=60;
}
server {
listen 80;
server_name www.server.com;
set $server "server_01";
if ($http_cookie ~* "version=V1") { set $server server_01; }
if ($http_cookie ~* "version=V2") { set $server server_02; }
location / {
proxy_pass http://$server;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
index index.html index.htm;
}
}2. Using map directive
upstream server_01 { server 192.168.1.100:8080 max_fails=1 fail_timeout=60; }
upstream server_02 { server 192.168.1.101:8080 max_fails=1 fail_timeout=60; }
map $COOKIE_version $server {
~*V1$ server_01;
~*V2$ server_02;
default server_01;
}
server {
listen 80;
server_name www.server.com;
location / {
proxy_pass http://$server;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
index index.html index.htm;
}
}Weight‑Based Gray Release
Assign different weights to upstream servers; higher weight receives more traffic.
upstream server {
server 192.168.1.100:8080 max_fails=1 fail_timeout=60 weight=5;
server 192.168.1.101:8080 max_fails=1 fail_timeout=60 weight=1;
}
server {
listen 80;
server_name www.server.com;
location / {
proxy_pass http://server;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
index index.html index.htm;
}
}Source‑IP Based Gray Release
1. Resources on different servers
upstream server_01 { server 192.168.1.100:8080 max_fails=1 fail_timeout=60; }
upstream server_02 { server 192.168.1.101:8080 max_fails=1 fail_timeout=60; }
server {
listen 80;
server_name www.server.com;
set $server "server_01";
if ($remote_addr ~ "211.118.119.11") { set $server server_02; }
location / {
proxy_pass http://$server;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
index index.html index.htm;
}
}2. Resources on the same server (different document roots)
server {
listen 80;
server_name www.server.com;
set $rootdir "/var/www/html";
if ($remote_addr ~ "211.118.119.11") { set $rootdir "/var/www/test"; }
location / {
root $rootdir;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
index index.html index.htm;
}
}Nginx + Lua Gray Release
If the client IP matches an entry in ipList.conf , route to @test_env ; otherwise route to @product_env .
ip_gray.lua script
local ip_config = ngx.shared.config;
local ClientIP = ngx.req.get_headers()["X-Real-IP"]
if ClientIP == nil then
ClientIP = ngx.req.get_headers()["x_forworded_for"]
end
if ClientIP == nil then
ClientIP = ngx.var.remote_addr
end
for line in io.lines("/usr/local/nginx/conf/lua/ipList.conf") do
if not ip_config:get(line) then
ip_config:set(line, "0")
end
end
if ip_config:get(ClientIP) == "0" then
ngx.exec("@test_env")
else
ngx.exec("@product_env")
endLua configuration and locations
lua_code_cache on;
lua_shared_dict config 1m;
upstream MyServer {
server 192.168.1.199:8099 max_fails=3 fail_timeout=30s;
server 192.168.1.200:8099 max_fails=3 fail_timeout=30s;
ip_hash;
}
server {
listen 80;
server_name jokerzhang.cn;
access_log off;
location / {
access_by_lua_file /usr/local/nginx/conf/lua/ip_gray.lua;
}
location @test_env {
proxy_pass http://192.168.1.199:8099;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location @product_env {
proxy_pass http://MyServer;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Open Source Tech Hub
Sharing cutting-edge internet technologies and practical AI resources.
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.
