[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"blog-mcsm-openresty-reverse-proxy":3,"prev-next-mcsm-openresty-reverse-proxy":631},{"id":4,"title":5,"body":6,"date":621,"description":48,"extension":622,"math":623,"meta":624,"navigation":625,"path":626,"seo":627,"stem":628,"summary":629,"__hash__":630},"blog\u002Fblog\u002Fmcsm-openresty-reverse-proxy.mdx","MCSManager + OpenResty 的反向代理指北",{"type":7,"value":8,"toc":581},"minimark",[9,13,17,27,30,35,38,51,55,62,66,73,76,80,97,100,107,110,125,132,136,139,146,153,166,170,177,186,193,196,203,206,213,228,231,235,256,259,266,270,284,288,291,298,301,315,318,325,329,336,339,346,353,356,367,370,377,380,387,394,398,404,408,411,418,421,432,435,437,443,454,457,460,467,470,487,490,494,501,505,508,515,522,527,531,541,545,550,553,560,563],[10,11,12],"h2",{"id":12},"环境信息",[14,15,16],"h3",{"id":16},"面板",[18,19,20,24],"ul",{},[21,22,23],"li",{},"MCSManager 4.13.0",[21,25,26],{},"使用官方 Linux 安装脚本部署",[14,28,29],{"id":29},"反向代理",[18,31,32],{},[21,33,34],{},"1panel 默认的 OpenResty",[14,36,37],{"id":37},"实例域名",[39,40,45],"pre",{"className":41,"code":43,"language":44},[42],"language-text","mcsm.example.com\n","text",[46,47,43],"code",{"__ignoreMap":48,"className":49},"",[50,42],"hljs",[14,52,54],{"id":53},"daemon-默认端口","Daemon 默认端口",[39,56,59],{"className":57,"code":58,"language":44},[42],"24444\n",[46,60,58],{"__ignoreMap":48,"className":61},[50,42],[14,63,65],{"id":64},"httpswss-反代端口","HTTPS\u002FWSS 反代端口",[39,67,70],{"className":68,"code":69,"language":44},[42],"24443\n",[46,71,69],{"__ignoreMap":48,"className":72},[50,42],[10,74,75],{"id":75},"问题现象",[77,78,79],"p",{},"MCSManager 面板正常访问。但是：",[18,81,82,85,88,91],{},[21,83,84],{},"实例控制台打不开",[21,86,87],{},"文件上传失败",[21,89,90],{},"文件下载失败",[21,92,93,94],{},"节点显示：",[46,95,96],{},"网页直连：异常",[77,98,99],{},"错误信息：",[39,101,104],{"className":102,"code":103,"language":44},[42],"无法连接到远程节点\n\n浏览器无法连接到地址：\nwss:\u002F\u002Fmcsm.example.com:24444\n\nxhr poll error\n",[46,105,103],{"__ignoreMap":48,"className":106},[50,42],[10,108,109],{"id":109},"原因分析",[77,111,112,113,116,117,120,121,124],{},"MCSManager 在 HTTPS 页面下，浏览器必须通过 ",[46,114,115],{},"WSS:\u002F\u002F"," 连接 daemon。如果 daemon 仍然是 ",[46,118,119],{},"ws:\u002F\u002F"," 或 ",[46,122,123],{},"http:\u002F\u002F","，浏览器会因为 Mixed Content 安全策略直接拒绝连接。",[77,126,127,128],{},"因此：",[129,130,131],"strong",{},"必须给 daemon 单独配置 HTTPS + WebSocket 反向代理。",[10,133,135],{"id":134},"openresty-docker-挂载目录","OpenResty Docker 挂载目录",[77,137,138],{},"1Panel OpenResty 容器挂载：",[39,140,143],{"className":141,"code":142,"language":44},[42],"宿主机:  \u002Fopt\u002F1panel\u002Fwww\u002Fconf.d\n容器内:  \u002Fusr\u002Flocal\u002Fopenresty\u002Fnginx\u002Fconf\u002Fconf.d\n",[46,144,142],{"__ignoreMap":48,"className":145},[50,42],[77,147,148,149,152],{},"只需要在宿主机 ",[46,150,151],{},"\u002Fopt\u002F1panel\u002Fwww\u002Fconf.d"," 创建配置文件即可。",[154,155,156],"blockquote",{},[77,157,158,161,162,165],{},[129,159,160],{},"前提","：记得提前在 1Panel 中为域名 ",[46,163,164],{},"mcsm.example.com"," 申请 SSL 证书，这里不做详细说明。",[10,167,169],{"id":168},"创建-daemon-https-配置","创建 daemon HTTPS 配置",[77,171,172,173,176],{},"创建 ",[46,174,175],{},"\u002Fopt\u002F1panel\u002Fwww\u002Fconf.d\u002Fmcsm-daemon.conf","：",[39,178,183],{"className":179,"code":181,"language":182,"meta":48},[180],"language-nginx","server {\n    listen 24443 ssl;\n    listen [::]:24443 ssl;\n\n    http2 on;\n\n    server_name mcsm.example.com;\n\n    ssl_certificate \u002Fwww\u002Fsites\u002Fmcsm.example.com\u002Fssl\u002Ffullchain.pem;\n    ssl_certificate_key \u002Fwww\u002Fsites\u002Fmcsm.example.com\u002Fssl\u002Fprivkey.pem;\n\n    ssl_protocols TLSv1.2 TLSv1.3;\n\n    location \u002F {\n\n        proxy_pass http:\u002F\u002F127.0.0.1:24444;\n\n        proxy_http_version 1.1;\n\n        proxy_set_header Upgrade $http_upgrade;\n        proxy_set_header Connection \"upgrade\";\n\n        proxy_set_header Host $host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n\n        proxy_buffering off;\n        proxy_request_buffering off;\n\n        client_max_body_size 0;\n    }\n}\n","nginx",[46,184,181],{"__ignoreMap":48,"className":185},[50,180],[10,187,189,190],{"id":188},"特别注意不要写","特别注意：不要写 ",[46,191,192],{},"\\$",[77,194,195],{},"错误写法：",[39,197,200],{"className":198,"code":199,"language":182,"meta":48},[180],"proxy_set_header Upgrade \\$http_upgrade;\n",[46,201,199],{"__ignoreMap":48,"className":202},[50,180],[77,204,205],{},"正确写法：",[39,207,210],{"className":208,"code":209,"language":182,"meta":48},[180],"proxy_set_header Upgrade $http_upgrade;\n",[46,211,209],{"__ignoreMap":48,"className":212},[50,180],[77,214,215,216,219,220,223,224,227],{},"原因是如果你使用了单引号 heredoc（",[46,217,218],{},"\u003C\u003C'EOF'","），Shell 不会展开变量，因此不需要额外转义 ",[46,221,222],{},"$","。否则 nginx 会把 ",[46,225,226],{},"\\$http_upgrade"," 当作普通字符串，最终 WebSocket Upgrade Header 失效。",[10,229,230],{"id":230},"测试配置",[14,232,234],{"id":233},"检查-nginx-配置","检查 nginx 配置",[39,236,241],{"className":237,"code":239,"language":240,"meta":48},[238],"language-bash","sudo docker exec 1Panel-openresty-TlM5 openresty -t\n","bash",[46,242,244,250,251,255],{"__ignoreMap":48,"className":243},[50,238],[245,246,249],"span",{"className":247},[248],"hljs-built_in","sudo"," docker ",[245,252,254],{"className":253},[248],"exec"," 1Panel-openresty-TlM5 openresty -t\n",[77,257,258],{},"成功输出：",[39,260,263],{"className":261,"code":262,"language":44},[42],"syntax is ok\ntest is successful\n",[46,264,262],{"__ignoreMap":48,"className":265},[50,42],[14,267,269],{"id":268},"重载-openresty","重载 OpenResty",[39,271,274],{"className":272,"code":273,"language":240,"meta":48},[238],"sudo docker exec 1Panel-openresty-TlM5 openresty -s reload\n",[46,275,277,250,280,283],{"__ignoreMap":48,"className":276},[50,238],[245,278,249],{"className":279},[248],[245,281,254],{"className":282},[248]," 1Panel-openresty-TlM5 openresty -s reload\n",[14,285,287],{"id":286},"测试-daemon-是否可访问","测试 daemon 是否可访问",[77,289,290],{},"宿主机：",[39,292,295],{"className":293,"code":294,"language":240,"meta":48},[238],"curl http:\u002F\u002F127.0.0.1:24444\n",[46,296,294],{"__ignoreMap":48,"className":297},[50,238],[77,299,300],{},"Docker 容器内部：",[39,302,305],{"className":303,"code":304,"language":240,"meta":48},[238],"sudo docker exec -it 1Panel-openresty-TlM5 curl http:\u002F\u002F127.0.0.1:24444\n",[46,306,308,250,311,314],{"__ignoreMap":48,"className":307},[50,238],[245,309,249],{"className":310},[248],[245,312,254],{"className":313},[248]," -it 1Panel-openresty-TlM5 curl http:\u002F\u002F127.0.0.1:24444\n",[77,316,317],{},"都应返回：",[39,319,322],{"className":320,"code":321,"language":44},[42],"MCSManager Daemon is Running\n",[46,323,321],{"__ignoreMap":48,"className":324},[50,42],[14,326,328],{"id":327},"检查-docker-bridge-ip","检查 docker bridge IP",[39,330,333],{"className":331,"code":332,"language":240,"meta":48},[238],"ip addr show docker0\n",[46,334,332],{"__ignoreMap":48,"className":335},[50,238],[77,337,338],{},"输出：",[39,340,343],{"className":341,"code":342,"language":44},[42],"inet 127.0.0.1\u002F16\n",[46,344,342],{"__ignoreMap":48,"className":345},[50,42],[77,347,348,349,352],{},"因此 ",[46,350,351],{},"proxy_pass http:\u002F\u002F127.0.0.1:24444;"," 是正确的。",[14,354,355],{"id":355},"检查监听端口",[39,357,360],{"className":358,"code":359,"language":240,"meta":48},[238],"sudo ss -tlnp | grep 24443\n",[46,361,363,366],{"__ignoreMap":48,"className":362},[50,238],[245,364,249],{"className":365},[248]," ss -tlnp | grep 24443\n",[77,368,369],{},"应看到：",[39,371,374],{"className":372,"code":373,"language":44},[42],"0.0.0.0:24443\n",[46,375,373],{"__ignoreMap":48,"className":376},[50,42],[14,378,379],{"id":379},"浏览器测试",[77,381,382,383,386],{},"打开 ",[46,384,385],{},"https:\u002F\u002Fmcsm.example.com:24443","，如果成功会显示：",[39,388,391],{"className":389,"code":390,"language":44},[42],"MCSManager Daemon 程序运行中\n",[46,392,390],{"__ignoreMap":48,"className":393},[50,42],[10,395,397],{"id":396},"mcsmanager-节点配置","MCSManager 节点配置",[77,399,400,401],{},"进入：",[46,402,403],{},"管理面板 → 节点 → 编辑节点",[14,405,407],{"id":406},"远程节点-ip-地址","远程节点 IP 地址",[77,409,410],{},"填写：",[39,412,415],{"className":413,"code":414,"language":44},[42],"wss:\u002F\u002Fmcsm.example.com\n",[46,416,414],{"__ignoreMap":48,"className":417},[50,42],[77,419,420],{},"注意：",[18,422,423,429],{},[21,424,425,426],{},"必须写 ",[46,427,428],{},"wss:\u002F\u002F",[21,430,431],{},"不要写端口",[14,433,434],{"id":434},"远程节点端口",[77,436,410],{},[39,438,440],{"className":439,"code":69,"language":44},[42],[46,441,69],{"__ignoreMap":48,"className":442},[50,42],[77,444,445,446,449,450,453],{},"配置完成后点击 ",[129,447,448],{},"更新节点","，再 ",[129,451,452],{},"重新连接","。",[10,455,456],{"id":456},"最终效果",[77,458,459],{},"节点状态：",[39,461,464],{"className":462,"code":463,"language":44},[42],"节点状态：在线\n网页直连：正常\n",[46,465,463],{"__ignoreMap":48,"className":466},[50,42],[77,468,469],{},"以下功能恢复：",[18,471,472,475,478,481,484],{},[21,473,474],{},"控制台",[21,476,477],{},"文件上传",[21,479,480],{},"文件下载",[21,482,483],{},"WebSocket",[21,485,486],{},"实例终端",[10,488,489],{"id":489},"常见坑总结",[14,491,493],{"id":492},"_1-docker-内无法访问宿主机","1. Docker 内无法访问宿主机",[77,495,496,497,500],{},"检查 ",[46,498,499],{},"curl http:\u002F\u002F127.0.0.1:24444"," 是否可达。",[14,502,504],{"id":503},"_2-忘记-websocket-headers","2. 忘记 WebSocket Headers",[77,506,507],{},"必须设置：",[39,509,512],{"className":510,"code":511,"language":182,"meta":48},[180],"proxy_set_header Upgrade $http_upgrade;\nproxy_set_header Connection \"upgrade\";\n",[46,513,511],{"__ignoreMap":48,"className":514},[50,180],[14,516,518,519,521],{"id":517},"_3-被错误转义","3. ",[46,520,222],{}," 被错误转义",[77,523,524,525,453],{},"不要写 ",[46,526,226],{},[14,528,530],{"id":529},"_4-节点-ip-写错","4. 节点 IP 写错",[77,532,524,533,536,537,540],{},[46,534,535],{},"mcsm.example.com:24443","，正确格式是 ",[46,538,539],{},"wss:\u002F\u002Fmcsm.example.com","，端口单独填写。",[14,542,544],{"id":543},"_5-https-页面连接-http-websocket","5. HTTPS 页面连接 HTTP WebSocket",[77,546,547,548,453],{},"浏览器会直接拒绝（Mixed Content），因此必须使用 ",[46,549,115],{},[10,551,552],{"id":552},"最终网络结构",[39,554,557],{"className":555,"code":556,"language":44},[42],"Browser\n    ↓ HTTPS\u002FWSS\nOpenResty :24443\n    ↓ HTTP\u002FWS\nMCSManager Daemon :24444\n",[46,558,556],{"__ignoreMap":48,"className":559},[50,42],[10,561,562],{"id":562},"参考文档",[18,564,565,574],{},[21,566,567],{},[568,569,573],"a",{"href":570,"rel":571},"https:\u002F\u002Fdocs.mcsmanager.com\u002Fzh_cn\u002Fops\u002Fproxy_https.html",[572],"nofollow","MCSManager - 反代 HTTPS",[21,575,576],{},[568,577,580],{"href":578,"rel":579},"https:\u002F\u002Fdocs.mcsmanager.com\u002Fzh_cn\u002Fadvanced\u002Fdistributed.html",[572],"MCSManager - 分布式部署",{"title":48,"searchDepth":582,"depth":582,"links":583},2,[584,592,593,594,595,596,598,606,610,611,619,620],{"id":12,"depth":582,"text":12,"children":585},[586,588,589,590,591],{"id":16,"depth":587,"text":16},3,{"id":29,"depth":587,"text":29},{"id":37,"depth":587,"text":37},{"id":53,"depth":587,"text":54},{"id":64,"depth":587,"text":65},{"id":75,"depth":582,"text":75},{"id":109,"depth":582,"text":109},{"id":134,"depth":582,"text":135},{"id":168,"depth":582,"text":169},{"id":188,"depth":582,"text":597},"特别注意：不要写 \\$",{"id":230,"depth":582,"text":230,"children":599},[600,601,602,603,604,605],{"id":233,"depth":587,"text":234},{"id":268,"depth":587,"text":269},{"id":286,"depth":587,"text":287},{"id":327,"depth":587,"text":328},{"id":355,"depth":587,"text":355},{"id":379,"depth":587,"text":379},{"id":396,"depth":582,"text":397,"children":607},[608,609],{"id":406,"depth":587,"text":407},{"id":434,"depth":587,"text":434},{"id":456,"depth":582,"text":456},{"id":489,"depth":582,"text":489,"children":612},[613,614,615,617,618],{"id":492,"depth":587,"text":493},{"id":503,"depth":587,"text":504},{"id":517,"depth":587,"text":616},"3. $ 被错误转义",{"id":529,"depth":587,"text":530},{"id":543,"depth":587,"text":544},{"id":552,"depth":582,"text":552},{"id":562,"depth":582,"text":562},"2026-06-06","mdx",false,{},true,"\u002Fblog\u002Fmcsm-openresty-reverse-proxy",{"title":5,"description":48},"blog\u002Fmcsm-openresty-reverse-proxy","记录 MCSManager Daemon 在 OpenResty 反代下配置 HTTPS 与 WebSocket 的完整过程，含常见坑与最终正确配置。","h6qKlerFqZx6HbcU9J1xbBWs8lHZX8Ax8RIKToimjqc",{"prev":632,"next":635},{"slug":633,"title":634},"hello-world","Hello, World! 🌍",{"slug":636,"title":637},"non-functional-harmony","非功能和声小记"]