如何在现有Nginx配置中新增三个Server块?最佳方案咨询
Nginx多Server块最佳实现方案(同配置/证书、不同后端IP)
我现在有一份包含单个Server块的Nginx配置(如下所示),需要添加三个配置项完全相同、SSL证书一致,但后端IP不同的额外Server块。想咨询最佳实现方式:是在原配置文件中直接新增,还是拆分到独立文件,或是有其他更优方法?
# odoo server upstream odoo15.0 { server 192.168.0.101:8069; } upstream chat_odoo15.0 { server 192.168.0.101:8072; } server { server_name xxx.be www.xxx.be; proxy_read_timeout 720s; proxy_connect_timeout 720s; proxy_send_timeout 720s; # Add Headers for odoo proxy mode proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; # log access_log /var/log/nginx/odoo-15.0.access.log; error_log /var/log/nginx/odoo-15.0.error.log; # Redirect requests to odoo backend server location / { proxy_redirect off; proxy_pass http://odoo15.0; } location /longpolling { proxy_pass http://chat_odoo15.0; } # Specifies the maximum accepted body size of a client request, # as indicated by the request header Content-Length. client_max_body_size 200m; # common gzip gzip_types text/css text/less text/plain text/xml application/xml application/json application/javascript; gzip on; listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/www.xxx.be/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/www.xxx.be/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } server { if ($host = www.xxx.be) { return 301 https://$host$request_uri; } # managed by Certbot server_name xxx.be www.xxx.be; listen 80; return 404; # managed by Certbot }
几种实现方式的优劣对比
1. 直接在原文件新增Server块(快但难维护)
直接复制现有server块,修改server_name、upstream的IP、日志文件名这几个差异化内容,粘贴到原文件末尾即可。
- 优点:无需调整Nginx配置结构,上手快,适合临时测试场景。
- 缺点:配置文件会迅速膨胀,后续修改通用配置(比如超时时间、proxy_header)时,需要同时修改4个Server块,极易遗漏出错,长期维护成本极高。
2. 拆分到独立配置文件(清晰易扩展)
利用Nginx的include指令,把通用配置抽成公共片段,每个域名的差异化配置单独放在一个文件里。
具体操作:
- 创建通用配置片段文件,比如
/etc/nginx/snippets/odoo-shared.conf,存放所有Server块共用的代码:
proxy_read_timeout 720s; proxy_connect_timeout 720s; proxy_send_timeout 720s; # Add Headers for odoo proxy mode proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; # Redirect requests to odoo backend server location / { proxy_redirect off; proxy_pass http://$odoo_backend; } location /longpolling { proxy_pass http://$chat_backend; } client_max_body_size 200m; gzip_types text/css text/less text/plain text/xml application/xml application/json application/javascript; gzip on; listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/www.xxx.be/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/www.xxx.be/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
- 在
/etc/nginx/conf.d/下为每个域名创建单独的配置文件,比如odoo-a.conf:
# odoo server for a.be upstream odoo_a { server 192.168.0.102:8069; } upstream chat_odoo_a { server 192.168.0.102:8072; } server { server_name a.be www.a.be; set $odoo_backend odoo_a; set $chat_backend chat_odoo_a; access_log /var/log/nginx/odoo-a.access.log; error_log /var/log/nginx/odoo-a.error.log; include /etc/nginx/snippets/odoo-shared.conf; } server { if ($host = www.a.be) { return 301 https://$host$request_uri; } # managed by Certbot server_name a.be www.a.be; listen 80; return 404; # managed by Certbot }
同理创建odoo-b.conf、odoo-c.conf,仅修改upstream的IP、server_name、日志文件名即可。
- 优点:配置结构清晰,通用配置统一管理,修改一次同步所有域名;每个域名的配置独立,便于单独启用/禁用。
- 缺点:初期需要花时间整理配置结构,新增域名要创建新文件。
3. 使用Map指令+单个Server块(最优解,证书需覆盖所有域名)
如果你的SSL证书是通配符证书或包含所有新增域名的多域名证书,可以用Nginx的map指令根据域名映射到对应后端,只用一个Server块就能处理所有域名。
具体操作:
- 定义域名与后端的映射关系(可放在主配置或单独文件中):
map $host $odoo_backend { default odoo15.0; a.be odoo_a; www.a.be odoo_a; b.be odoo_b; www.b.be odoo_b; c.be odoo_c; www.c.be odoo_c; } map $host $chat_backend { default chat_odoo15.0; a.be chat_odoo_a; www.a.be chat_odoo_a; b.be chat_odoo_b; www.b.be chat_odoo_b; c.be chat_odoo_c; www.c.be chat_odoo_c; } # 所有后端的upstream定义 upstream odoo15.0 { server 192.168.0.101:8069; } upstream chat_odoo15.0 { server 192.168.0.101:8072; } upstream odoo_a { server 192.168.0.102:8069; } upstream chat_odoo_a { server 192.168.0.102:8072; } upstream odoo_b { server 192.168.0.103:8069; } upstream chat_odoo_b { server 192.168.0.103:8072; } upstream odoo_c { server 192.168.0.104:8069; } upstream chat_odoo_c { server 192.168.0.104:8072; }
- 修改原Server块,覆盖所有域名并使用变量:
server { server_name xxx.be www.xxx.be a.be www.a.be b.be www.b.be c.be www.c.be; proxy_read_timeout 720s; proxy_connect_timeout 720s; proxy_send_timeout 720s; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; # 按域名自动区分日志 access_log /var/log/nginx/odoo-$host.access.log; error_log /var/log/nginx/odoo-$host.error.log; location / { proxy_redirect off; proxy_pass http://$odoo_backend; } location /longpolling { proxy_pass http://$chat_backend; } client_max_body_size 200m; gzip_types text/css text/less text/plain text/xml application/xml application/json application/javascript; gzip on; listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/www.xxx.be/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/www.xxx.be/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } # 统一处理HTTP跳转 server { listen 80; server_name xxx.be www.xxx.be a.be www.a.be b.be www.b.be c.be www.c.be; if ($host ~* ^www\.(.*)) { set $without_www $1; return 301 https://$without_www$request_uri; } return 301 https://$host$request_uri; }
- 优点:无重复代码,维护成本极低;新增域名仅需添加一行map映射和对应的upstream。
- 缺点:要求SSL证书覆盖所有新增域名;若后续某域名需单独配置,需拆分出独立Server块。
最终推荐
- 证书满足覆盖所有域名的要求时,优先选方案3,简洁高效,长期维护最省心。
- 证书不满足或未来可能有域名需要独立配置时,选方案2,结构清晰,扩展性强。
- 仅临时测试场景,才考虑方案1,避免给长期维护留坑。
内容的提问来源于stack exchange,提问作者Y. Boujraf
相关产品推荐
相关产品推荐

