[{"data":1,"prerenderedAt":451},["ShallowReactive",2],{"content:\u002Fposts\u002Fnginx-guide":3,"surround:\u002Fposts\u002Fnginx-guide":441},{"id":4,"title":5,"body":6,"categories":415,"date":417,"description":418,"draft":419,"extension":420,"image":421,"meta":422,"navigation":424,"path":425,"permalink":421,"pinned":419,"published":421,"readingTime":426,"recommend":421,"references":421,"seo":431,"sitemap":432,"stem":433,"tags":434,"type":438,"updated":439,"__hash__":440},"content\u002Fposts\u002Fposts\u002Fnginx-guide.md","Nginx 安装与配置指南",{"type":7,"value":8,"toc":393},"minimark",[9,19,24,29,40,44,50,54,57,66,70,77,81,88,105,108,119,129,136,139,220,223,244,247,250,256,259,265,269,276,280,287,291,302,309,325,329,344,351,362,366,375,386],[10,11,15],"alert",{"type":12,"icon":13,"title":14},"info","tabler:robot","AI 迁移提示",[16,17,18],"p",{},"本文由 AI 协助从旧站迁移，尚未完成逐篇人工审校；内容如有疏漏，将在复核后修订。",[20,21,23],"h2",{"id":22},"一安装","一、安装",[25,26,28],"h3",{"id":27},"centosyum","CentOS（yum）",[30,31,37],"pre",{"className":32,"code":34,"language":35,"meta":36},[33],"language-bash","# 添加 Nginx 官方 YUM 源\nrpm -ivh http:\u002F\u002Fnginx.org\u002Fpackages\u002Fcentos\u002F7\u002Fnoarch\u002FRPMS\u002Fnginx-release-centos-7-0.el7.ngx.noarch.rpm\n\n# 安装 Nginx\nyum install -y nginx\n\n# 启动并设置开机自启\nsystemctl start nginx\nsystemctl enable nginx\n","bash","",[38,39,34],"code",{"__ignoreMap":36},[25,41,43],{"id":42},"ubuntu-debianapt","Ubuntu \u002F Debian（apt）",[30,45,48],{"className":46,"code":47,"language":35,"meta":36},[33],"apt install -y nginx\nsystemctl start nginx\nsystemctl enable nginx\nnginx -t\n",[38,49,47],{"__ignoreMap":36},[20,51,53],{"id":52},"二主配置文件结构","二、主配置文件结构",[16,55,56],{},"通常不会直接修改主配置文件，而是采用引入外部文件的方式管理多个站点。",[30,58,64],{"className":59,"code":61,"filename":62,"language":63,"meta":36},[60],"language-nginx","http {\n  # 注释掉默认的 include，防止 80 端口冲突\n  # include \u002Fetc\u002Fnginx\u002Fconf.d\u002F*.conf;\n\n  # 引入自定义 HTTP 配置\n  include \u002Fopt\u002Fnginx\u002Fhttp\u002F*.conf;\n\n  # 不限制文件上传大小\n  client_max_body_size 0;\n}\n\n# TCP\u002FUDP 代理（需要在 http 块外部）\nstream {\n  include \u002Fopt\u002Fnginx\u002Fserver\u002F*.conf;\n}\n","nginx.conf","nginx",[38,65,61],{"__ignoreMap":36},[20,67,69],{"id":68},"三静态站点-vue-spa","三、静态站点 \u002F Vue SPA",[30,71,75],{"className":72,"code":73,"filename":74,"language":63,"meta":36},[60],"server {\n    listen 80;\n    server_name example.com;\n    root \u002Fopt\u002Fapp\u002Fdist;\n    index index.html;\n\n    location \u002F {\n        try_files $uri $uri\u002F \u002Findex.html;\n    }\n\n    location \u002Fapi\u002F {\n        proxy_set_header Host $http_host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header X-Forwarded-Proto $scheme;\n        proxy_pass http:\u002F\u002F127.0.0.1:8080\u002F;\n    }\n}\n","\u002Fopt\u002Fnginx\u002Fhttp\u002Fspa.conf",[38,76,73],{"__ignoreMap":36},[20,78,80],{"id":79},"四sub_filter-注入自定义-html","四、sub_filter 注入自定义 HTML",[16,82,83,84,87],{},"在反向代理第三方服务时，若需要在页面中注入自定义 JS\u002FCSS，但无法修改源码，可以借助 Nginx 的 ",[38,85,86],{"code":86},"sub_filter"," 指令在响应内容中做字符串替换注入。",[10,89,90,99],{"type":12},[16,91,92,94,95,98],{},[38,93,86],{"code":86}," 由 ",[38,96,97],{"code":97},"ngx_http_sub_module"," 模块提供，编译 Nginx 时需确认已包含该模块：",[30,100,103],{"className":101,"code":102,"language":35,"meta":36},[33],"nginx -V 2>&1 | grep sub_filter\n",[38,104,102],{"__ignoreMap":36},[25,106,107],{"id":107},"配置示例",[10,109,111],{"type":110},"tip",[16,112,113,114],{},"尚未部署 Uptime Kuma？参见：",[115,116,118],"a",{"href":117},"\u002Fposts\u002Fdocker-uptime-kuma","Docker 部署 Uptime Kuma 监控",[16,120,121,122,124,125,128],{},"以下示例在代理 Uptime Kuma 状态页时，通过 ",[38,123,86],{"code":86}," 在 ",[38,126,127],{"code":127},"\u003C\u002Fhead>"," 前注入自定义资源：",[30,130,134],{"className":131,"code":132,"filename":133,"language":63,"meta":36},[60],"map $http_upgrade $connection_upgrade {\n    default upgrade;\n    ''      close;\n}\n\nserver {\n    listen 80;\n    server_name status.example.com;\n\n    location ^~ \u002Fstatus\u002Fexternal {\n        proxy_pass http:\u002F\u002F10.0.0.11:3001\u002Fstatus\u002Fexternal;\n\n        proxy_set_header Host $http_host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header X-Forwarded-Proto $scheme;\n\n        proxy_http_version 1.1;\n        proxy_set_header Upgrade $http_upgrade;\n        proxy_set_header Connection $connection_upgrade;\n\n        # 在 \u003C\u002Fhead> 前注入自定义资源\n        sub_filter '\u003C\u002Fhead>' '\u003Cscript src=\"\u002Fmain.js\">\u003C\u002Fscript>';\n        sub_filter '\u003C\u002Fhead>' '\u003Clink rel=\"stylesheet\" href=\"\u002Fmain.css\">';\n        sub_filter '\u003C\u002Fhead>' '\u003Clink rel=\"stylesheet\" href=\"\u002Ficonfont.css\">';\n\n        sub_filter_once off;   # off = 替换所有匹配\n        sub_filter_types *;    # 对所有 MIME 类型生效\n    }\n}\n","\u002Fopt\u002Fnginx\u002Fhttp\u002Fstatus.conf",[38,135,132],{"__ignoreMap":36},[25,137,138],{"id":138},"常用指令",[140,141,142,155],"table",{},[143,144,145],"thead",{},[146,147,148,152],"tr",{},[149,150,151],"th",{},"指令",[149,153,154],{},"说明",[156,157,158,176,193,206],"tbody",{},[146,159,160,166],{},[161,162,163],"td",{},[38,164,165],{"code":165},"sub_filter string replacement",[161,167,168,169,172,173],{},"将响应中的 ",[38,170,171],{"code":171},"string"," 替换为 ",[38,174,175],{"code":175},"replacement",[146,177,178,183],{},[161,179,180],{},[38,181,182],{"code":182},"sub_filter_once on|off",[161,184,185,188,189,192],{},[38,186,187],{"code":187},"on","（默认）只替换第一处；",[38,190,191],{"code":191},"off"," 替换全部匹配",[146,194,195,200],{},[161,196,197],{},[38,198,199],{"code":199},"sub_filter_types *",[161,201,202,203],{},"指定生效的 MIME 类型，默认仅 ",[38,204,205],{"code":205},"text\u002Fhtml",[146,207,208,213],{},[161,209,210],{},[38,211,212],{"code":212},"sub_filter_last_modified on|off",[161,214,215,216,219],{},"是否在替换后修改响应的 ",[38,217,218],{"code":218},"Last-Modified"," 头",[25,221,222],{"id":222},"注意事项",[224,225,226,241],"ul",{},[227,228,229,230,232,233,236,237,240],"li",{},"如果后端响应启用了 gzip 压缩，",[38,231,86],{"code":86}," 无法处理压缩内容，需在 ",[38,234,235],{"code":235},"location"," 内添加 ",[38,238,239],{"code":239},"proxy_set_header Accept-Encoding \"\";"," 禁用后端压缩。",[227,242,243],{},"注入的静态资源路径中不能使用动态变量，否则浏览器无法解析。建议将静态资源缓存到 Nginx 本地后统一提供。",[25,245,246],{"id":246},"环境标识示例",[16,248,249],{},"可为开发或测试环境注入固定提示条，无需修改应用代码：",[30,251,254],{"className":252,"code":253,"language":63,"meta":36},[60],"location \u002F {\n    # 插入自定义提示头\n    sub_filter '\u003C\u002Fbody>' '\u003Cdiv style=\"position:fixed;top:0;left:50%;transform:translateX(-50%);background:red;color:white;padding:2px 10px;z-index:9999;font-size:12px;pointer-events:none;opacity:0.8;border-radius:0 0 5px 5px;\">当前环境：DEV 开发版\u003C\u002Fdiv>\u003C\u002Fbody>';\n    sub_filter_once on;\n\n    root $root\u002Fplatform;\n    index index.html;\n    try_files $uri $uri\u002F \u002Findex.html;\n    add_header Access-Control-Allow-Origin *;\n    add_header 'Access-Control-Allow-Credentials' 'true';\n    add_header 'Access-Control-Allow-Methods' *;\n    add_header 'Access-Control-Allow-Headers' *;\n    add_header Cache-Control no-cache;\n}\n",[38,255,253],{"__ignoreMap":36},[16,257,258],{},"效果如下：",[16,260,261],{},[262,263],"img",{"alt":36,"src":264},".\u002Fimages\u002FNginx%E6%B3%A8%E5%85%A5%E8%87%AA%E5%AE%9A%E4%B9%89HTML%E6%A0%87%E7%AD%BE-2.webp",[20,266,268],{"id":267},"五ssl-https","五、SSL \u002F HTTPS",[30,270,274],{"className":271,"code":272,"filename":273,"language":63,"meta":36},[60],"server {\n    listen 80;\n    server_name example.com;\n    return 301 https:\u002F\u002F$host$request_uri;\n}\n\nserver {\n    listen 443 ssl http2;\n    server_name example.com;\n\n    ssl_certificate        \u002Fopt\u002Fcert\u002Fexample.com.pem;\n    ssl_certificate_key    \u002Fopt\u002Fcert\u002Fexample.com.key;\n    ssl_protocols          TLSv1.1 TLSv1.2 TLSv1.3;\n    ssl_ciphers            EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:!MD5;\n    ssl_prefer_server_ciphers on;\n    ssl_session_cache      shared:SSL:10m;\n    ssl_session_timeout    10m;\n    add_header Strict-Transport-Security \"max-age=31536000\" always;\n\n    root \u002Fopt\u002Fapp\u002Fdist;\n    index index.html;\n\n    location \u002F {\n        try_files $uri $uri\u002F \u002Findex.html;\n    }\n\n    location \u002Fapi\u002F {\n        proxy_set_header Host $http_host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header X-Forwarded-Proto $scheme;\n        proxy_pass http:\u002F\u002F127.0.0.1:8080\u002F;\n    }\n}\n","\u002Fopt\u002Fnginx\u002Fhttp\u002Fssl.conf",[38,275,272],{"__ignoreMap":36},[20,277,279],{"id":278},"六反向代理","六、反向代理",[30,281,285],{"className":282,"code":283,"filename":284,"language":63,"meta":36},[60],"server {\n    listen 80;\n    server_name app.example.com;\n\n    location \u002F {\n        proxy_set_header Host $http_host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header X-Forwarded-Proto $scheme;\n        proxy_connect_timeout 60s;\n        proxy_send_timeout    600s;\n        proxy_read_timeout    600s;\n        proxy_pass http:\u002F\u002F127.0.0.1:3000;\n    }\n}\n","\u002Fopt\u002Fnginx\u002Fhttp\u002Fproxy.conf",[38,286,283],{"__ignoreMap":36},[20,288,290],{"id":289},"七websocket-代理","七、WebSocket 代理",[16,292,293,294,297,298,301],{},"代理 WebSocket 服务时需额外设置 ",[38,295,296],{"code":296},"Upgrade"," 和 ",[38,299,300],{"code":300},"Connection"," 请求头，否则 WS 握手会失败。",[30,303,307],{"className":304,"code":305,"filename":306,"language":63,"meta":36},[60],"map $http_upgrade $connection_upgrade {\n    default upgrade;\n    ''      close;\n}\n\nserver {\n    listen 80;\n    server_name ws.example.com;\n\n    location \u002F {\n        proxy_set_header Host $http_host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header X-Forwarded-Proto $scheme;\n        proxy_http_version 1.1;\n        proxy_set_header Upgrade $http_upgrade;\n        proxy_set_header Connection $connection_upgrade;\n        proxy_connect_timeout 60s;\n        proxy_read_timeout    3600s;\n        proxy_send_timeout    3600s;\n        proxy_pass http:\u002F\u002F127.0.0.1:3001;\n    }\n}\n","\u002Fopt\u002Fnginx\u002Fhttp\u002Fws.conf",[38,308,305],{"__ignoreMap":36},[10,310,311],{"type":110},[16,312,313,316,317,320,321,324],{},[38,314,315],{"code":315},"map"," 指令需放在 ",[38,318,319],{"code":319},"http"," 块内（通常在主配置文件中定义一次即可），用于自动将 HTTP 升级为 WebSocket 连接。",[38,322,323],{"code":323},"proxy_read_timeout"," 建议设置较大值，防止长连接被提前断开。",[20,326,328],{"id":327},"八tcp-流量转发stream-模块","八、TCP 流量转发（stream 模块）",[16,330,331,332,335,336,338,339,343],{},"适用于转发 MySQL、Redis 等 TCP 服务。",[38,333,334],{"code":334},"stream"," 块与 ",[38,337,319],{"code":319}," 块同级。以 MySQL 为例（安装参见 ",[115,340,342],{"href":341},"\u002Fposts\u002Fcentos-mysql-57","CentOS MySQL 5.7 安装","）：",[30,345,349],{"className":346,"code":347,"filename":348,"language":63,"meta":36},[60],"upstream mysql3306 {\n    hash $remote_addr consistent;\n    server 192.168.1.58:3306 weight=5 max_fails=3 fail_timeout=30s;\n}\n\nserver {\n    listen 33306;\n    proxy_connect_timeout 100s;\n    proxy_timeout 500s;\n    proxy_pass mysql3306;\n}\n","\u002Fopt\u002Fnginx\u002Fserver\u002Fmysql.conf",[38,350,347],{"__ignoreMap":36},[10,352,353,356],{"type":12},[16,354,355],{},"使用 stream 模块前需确认编译时包含了该模块：",[30,357,360],{"className":358,"code":359,"language":35,"meta":36},[33],"nginx -V 2>&1 | grep with-stream\n",[38,361,359],{"__ignoreMap":36},[20,363,365],{"id":364},"九minio-反向代理","九、MinIO 反向代理",[10,367,368],{"type":12},[16,369,370,371],{},"尚未部署 MinIO？参见：",[115,372,374],{"href":373},"\u002Fposts\u002Fminio-install","MinIO 对象存储安装指南",[16,376,377,378,381,382,385],{},"MinIO 签名验证依赖 ",[38,379,380],{"code":380},"Host"," 头，必须正确透传，否则出现 ",[38,383,384],{"code":384},"The request signature we calculated does not match the signature you provided"," 错误。",[30,387,391],{"className":388,"code":389,"filename":390,"language":63,"meta":36},[60],"server {\n    listen 9000;\n    server_name minio.example.com;\n    client_max_body_size 0;\n\n    location \u002F {\n        proxy_set_header Host $http_host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_pass http:\u002F\u002F127.0.0.1:9001;\n    }\n}\n","\u002Fopt\u002Fnginx\u002Fhttp\u002Fminio.conf",[38,392,389],{"__ignoreMap":36},{"title":36,"searchDepth":394,"depth":394,"links":395},4,[396,402,403,404,410,411,412,413,414],{"id":22,"depth":397,"text":23,"children":398},2,[399,401],{"id":27,"depth":400,"text":28},3,{"id":42,"depth":400,"text":43},{"id":52,"depth":397,"text":53},{"id":68,"depth":397,"text":69},{"id":79,"depth":397,"text":80,"children":405},[406,407,408,409],{"id":107,"depth":400,"text":107},{"id":138,"depth":400,"text":138},{"id":222,"depth":400,"text":222},{"id":246,"depth":400,"text":246},{"id":267,"depth":397,"text":268},{"id":278,"depth":397,"text":279},{"id":289,"depth":397,"text":290},{"id":327,"depth":397,"text":328},{"id":364,"depth":397,"text":365},[416],"服务","2026-01-09","介绍 Nginx 在 CentOS 和 Ubuntu 上的安装方法，以及静态站点、SSL\u002FHTTPS、反向代理、WebSocket、TCP、MinIO 和 sub_filter 注入配置。",false,"md",null,{"slots":423},{},true,"\u002Fposts\u002Fnginx-guide",{"text":427,"minutes":428,"time":429,"words":430},"6 min read",5.245,314700,1049,{"title":5,"description":418},{"loc":425},"posts\u002Fposts\u002Fnginx-guide",[435,436,437,86],"Nginx","反向代理","SSL","tech","2026-04-11","cOK3DZxbCwO-1kW3nRna6SLy9mQVx2p04Nb3EiEW6pU",[442,447],{"title":443,"path":444,"stem":445,"date":446,"type":438,"children":-1},"Linux 搭建 Nexus Maven 私服完整指南","\u002Fposts\u002Fnexus-maven-private","posts\u002Fposts\u002Fnexus-maven-private","2026-01-07",{"title":448,"path":341,"stem":449,"date":450,"type":438,"children":-1},"CentOS 安装 MySQL 5.7 完整指南","posts\u002Fposts\u002Fcentos-mysql-57","2026-01-11",1788712225557]