简介面向正在搭建苍穹外卖前端开发环境的学习者与初级开发者这份文档聚焦 Nginx 启动失败这一高频问题帮助读者从错误日志入手定位环境配置障碍。压缩包内仅有 1 个 docx 文件体积约 100KB内容集中适合在本地搭建与联调阶段快速查阅。文档以 error.log 中创建 client_body_temp 目录失败、系统提示找不到指定路径的案例为主线先说明报错表现和常见成因再给出规避中文路径、在 Nginx 目录下补建 temp 与 client_body_temp 文件夹等操作思路并补充配置文件检查、防火墙端口放行、端口占用检测等延伸排查方向。文中还提醒读者核对 nginx.conf 中的监听端口与 server 块等关键项理解临时目录的生成机制便于按步骤排查。已有 3698 人学习可作为苍穹外卖前端环境搭建的排错参考也能为同类 Windows 环境下 Nginx 部署问题提供一份可复用的检查清单。1. 双击 nginx.exe 打不开页面前端环境到底卡在哪一环苍穹外卖的前端环境搭建真正卡人的地方往往不在代码而在那个双击之后毫无反应的nginx.exe。我在一台 Windows 机器上按流程解压、双击、打开浏览器页面转了三四秒最后丢给我一句「无法访问此网站」可conf/nginx.conf我一个字都没动过。翻到logs/error.log才看到一行[emerg]CreateDirectory()创建temp/client_body_temp失败错误码 3 表示系统找不到指定的路径。这个报错不涉及任何业务逻辑纯粹是目录结构和路径字符的问题但它能把一个下午的时间吃掉而且报错信息藏在 logs 里不看日志就完全是个黑匣子。后面这套流程是给要在一台干净的 Windows 上把前端跑起来的人写的装哪个版本的 Nginx、目录怎么摆、nginx.conf改哪几行、起不来的时候按什么顺序排查。新手照着走能通熟手可以直接看版本取舍和避坑那几段。2. 装什么版本放什么目录Nginx 1.20.2 前端环境准备清单2.1 这套前端环境由哪几块拼起来很多人把「前端环境」理解成装个 Node 就完事实际跑苍穹外卖这种已经打好包的前端链条是这样的Nginx 提供静态文件服务和接口转发前端产物dist提供 HTML/JS/CSS浏览器负责访问后端服务提供接口数据。只有在你要改前端源码重新打包的时候才需要 Node 和包管理器只是把现成的页面跑起来Nginx 加一份 dist 就够了不用先折腾 Node 版本。组件版本作用是否必需Nginx1.20.2 Windows 版静态资源服务 接口反向代理必需前端产物 dist与项目配套提供 index.html 及 js/css 资源必需浏览器任意现代浏览器访问验证、看控制台报错必需Node.js仅在改源码时需要重新构建 dist可选后端服务与前端配套提供接口数据联调时必需版本这块我一般锁死 1.20.2原因不玄学一是手上的教程、配置片段、目录结构都是按这个版本写的语法完全对得上二是 Windows 版是解压即用的 zip 包不写注册表、不装服务删掉文件夹就等于卸载干净翻车了重来成本极低。新版本当然也能用但主版本跨越之后nginx.conf里某些默认值会变初学者对照教程改配置时容易对不上号先跑通再升级比反过来省事。2.2 版本与目录规划路径里出现一个中文字就够你查一晚上目录这件事值得单独拎出来讲。原文里 Nginx 放在D:\IDEA\Code\Projects\CangQiongWaiMai\environment\Nginx\nginx-1.20.2路径本身没有中文照样报了路径找不到。所以判断顺序应该是先确认temp子目录在不在再考虑路径里的字符问题。这两件事都会触发同一个错误码 3混在一起猜就会来回改。我的习惯是把所有需要长期运行的服务类软件放在一个独立的、纯英文、无空格的短路径下比如D:\dev\下面。IDE 的工程目录不适合塞这些东西工程会改名、会挪盘、会被清理工具扫Nginx 一旦跟着动配置文件里的绝对路径就全部失效。路径长度也要留意Windows 默认路径长度限制在 260 字符左右层级一深某些目录创建操作就会静默失败。# Git Bash / WSL 下创建标准目录结构路径全英文无空格 mkdir -p /d/dev/nginx-1.20.2/temp/client_body_temp mkdir -p /d/dev/nginx-1.20.2/temp/proxy_temp mkdir -p /d/dev/nginx-1.20.2/temp/fastcgi_temp mkdir -p /d/dev/cangqiong-front/dist:: 纯 Windows cmd 下的等价写法注意反斜杠 mkdir D:\dev\nginx-1.20.2\temp\client_body_temp mkdir D:\dev\nginx-1.20.2\temp\proxy_temp mkdir D:\dev\nginx-1.20.2\temp\fastcgi_temp mkdir D:\dev\cangqiong-front\dist上面两条只是 shell 不同做的事一样在 Nginx 根目录下补齐temp及其子目录同时给前端产物单独开一个目录。client_body_temp是接收请求体的临时目录proxy_temp用于反向代理时缓存上游响应fastcgi_temp是给 FastCGI 用的。苍穹外卖这种纯静态加接口转发的场景用得最多的是client_body_temp但只要有一个缺失Nginx 启动阶段就会直接退出不会降级运行。2.3 解压后的目录体检与三个必看文件Windows 版的 zip 包解压出来temp目录经常是不存在的——打包时空目录不会被打进去这一点和 Linux 编译安装的自动创建行为不一样所以「配置文件没动过却起不来」在这个组合下是高频事件。解压完先做一次目录体检比直接双击nginx.exe靠谱得多。路径作用缺失后果conf/nginx.conf主配置文件启动即报错找不到配置conf/mime.types文件类型映射页面能开但 CSS/JS 返回 octet-streamlogs/error.log错误日志出问题没有任何线索logs/nginx.pid主进程号停止服务时找不到进程html/index.html默认欢迎页不影响自己的站点可保留temp/client_body_temp请求体临时目录启动失败错误码 3体检的做法很简单进到 Nginx 根目录确认conf、logs、html、temp四个目录都在nginx.exe在根目录然后进logs看一眼error.log有没有历史残留。这一步花不到一分钟但能省掉后面反复重启、反复猜的时间。顺手把解压包里的nginx.conf复制一份改名nginx.conf.origin以后配置改崩了直接覆盖回来这就是我给自己的后悔药。3. 配置 nginx.conflisten、root、index 三个参数决定首页能不能打开3.1 改配置前先做备份与语法自检nginx.conf是一个层级嵌套的配置最外层是全局指令往下是events再往下是httphttp里面才是server和location。层级写错、少一个分号、多一个花括号Nginx 都不会启动而且部分情况下不会给出很直白的提示。所以每次动配置之前第一件事是备份第二件事是用-t做语法检查检查通过再重启。# 进入 Nginx 根目录先备份再校验 cd /d/dev/nginx-1.20.2 cp conf/nginx.conf conf/nginx.conf.bak # -t 只做语法检查不启动-c 指定配置文件路径 ./nginx.exe -t -c conf/nginx.conf-t参数的作用是 test读完配置就退出不会占用端口也不会启动 worker 进程-c用来显式指定配置文件。输出syntax is ok和test is successful两行才算过。如果只写nginx -t默认读的是conf/nginx.conf前提是你已经在 Nginx 根目录下执行。这两行输出在当前目录下看不到就得确认自己是不是在别的路径敲的命令。备份文件命名成.bak有个小坑conf目录下所有.conf结尾的文件在某些启动脚本里会被一并加载用.bak后缀正好避开。这个细节吃过一次亏之后就固定下来了。3.2 最小可用 server 块把 root 指到前端产物目录苍穹外卖前端的配置文件不需要写得多复杂一个server块加一个静态根目录就够跑起来。下面这份是我常用的最小结构直接替换掉原配置里的server部分即可端口特意避开 80原因后面讲。worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { # 对外监听端口避开 80 和 8080 listen 8081; server_name localhost; location / { # 前端产物目录必须用正斜杠 root D:/dev/cangqiong-front/dist; index index.html; # 前端路由是 history 模式时刷新子路径不会 404 try_files $uri $uri/ /index.html; } # 把 /api 开头的请求转给后端 location /api/ { proxy_pass http://127.0.0.1:8080/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } }listen 8081决定浏览器访问的端口写成 80 的话地址栏可以省略端口号但 80 在 Windows 上经常被系统组件或别的服务占着排查成本高先用 8081 跑通再改。root指向 dist 的绝对路径Windows 下必须写成正斜杠D:/dev/...写成反斜杠会被当成转义字符处理。try_files $uri $uri/ /index.html这一行是给前端路由兜底的请求的文件存在就直接返回不存在就回落到index.html由前端路由接管。少了这一行在页面内部跳转后再刷新就会出现白屏或 404。proxy_pass结尾的斜杠有讲究http://127.0.0.1:8080/带斜杠时/api/user/list会被转成/user/list不带斜杠则原样转发成/api/user/list。这个差异在第 5 章会展开讲配错的表现是接口 404 但页面正常。3.3 启动与停止别只会双击 exe双击nginx.exe能启动但它是后台静默运行的没有窗口、没有提示成功和失败在任务栏上都看不出来。更麻烦的是 Windows 下双击多次会拉起多个进程每个都尝试占用同一个端口最后谁在跑、谁在抢只能靠任务管理器猜。命令行启动至少能让失败信息留在屏幕上。cd /d/dev/nginx-1.20.2 # 启动start 让它在后台跑不占住当前终端 start nginx # 确认进程正常应该只有 master 和 worker 两个 tasklist /fi imagename eq nginx.exe # 改完配置热加载不中断服务 ./nginx.exe -s reload # 优雅停止处理完当前请求再退出 ./nginx.exe -s quitstart nginx是 Windows 特性等价于双击但保留了报错输出tasklist加过滤器只看 nginx 进程理想情况是一个 master 加一个 worker出现四五个就要考虑是不是重复启动了。-s reload发信号让 master 重新读配置、平滑替换 worker改端口之外的大部分改动都能用它生效-s quit是优雅停止-s stop是快速停止本地开发用quit更稳。真遇到进程僵住、端口不释放兜底手段是强杀taskkill /im nginx.exe /f。这条命令我一般只在确认没有别的 nginx 实例在跑的时候用因为它不管进程状态全部杀掉。3.4 换端口与放行80 被占用时的处理顺序启动失败先看日志日志里如果是bind() to 0.0.0.0:80 failed (10013: An attempt was made to access a socket in a way forbidden by its access permissions)那基本就是端口层面的问题。Windows 上 80 端口有可能被系统保留区占用改配置换端口比去系统里解绑省事得多。# 查端口占用最后一位是 PID netstat -ano | findstr :8081 # 拿到 PID 后查具体进程名 tasklist /fi pid eq 12345netstat -ano里-a列全部连接-n用数字显示地址和端口-o带上进程号。拿到 PID 再tasklist确认是谁占的是别的 nginx 就停掉是系统服务就换个端口别硬碰。外部访问不通的时候才轮到防火墙。本机127.0.0.1能开、局域网别的机器打不开多半是入站规则没放行加一条规则即可。# 放行 8081 端口的入站 TCP 连接 netsh advfirewall firewall add rule namenginx-8081 dirin actionallow protocolTCP localport8081dirin表示入站方向actionallow是允许localport指定端口。这条规则只对当前机器生效删掉用netsh advfirewall firewall delete rule namenginx-8081。本机调试阶段其实用不上等要给别人访问时再加避免规则越攒越多。4. 前端产物与接口地址页面打开后数据不出来的核对顺序4.1 先分清 404、502、白屏三种表现页面打不开和页面打开了但没数据是两条完全不同的排查线。把表现先分类比上来就翻配置快得多。表现大概率原因先看哪里浏览器转圈后提示无法访问Nginx 没起、端口不对、防火墙拦logs/error.log、netstat -ano404 Not Foundroot 指错目录、dist 没放进去root路径、dist 目录内容白屏但 HTTP 200JS/CSS 加载失败、前端路由缺兜底浏览器控制台 Network 面板页面正常但列表为空接口地址错、后端没起、代理路径不匹配Network 里/api请求状态码502 Bad Gateway反向代理的上游服务没起proxy_pass地址与后端端口这个表我放在手边出问题先对号入座。多数时候看完 Network 面板的请求状态码就能定位到是哪一层出的问题不用从头到尾把配置读一遍。4.2 静态资源路径与 baseURL 的核对清单dist 目录里最容易被忽略的是index.html中引用资源的路径形式。如果是/js/app.js这种以斜杠开头的绝对路径Nginx 会从站点根目录去找只要root指对了就没问题如果是./js/app.js这种相对路径页面在根路径下访问正常一旦前端路由跳到二级路径再刷新相对路径的基准就变了资源全部 404表现就是白屏。接口地址这块打包时通常会抽到一个单独的配置文件里运维阶段改这个文件比重新打包现实得多。文件一般叫config.js或app.config.json放在 dist 根目录改完不用动 Nginx。// dist/config.js打包后可直接修改的运行时配置 window.__APP_CONFIG__ { // 前端请求的基础地址指向 Nginx 自己由 Nginx 转发到后端 baseURL: http://127.0.0.1:8081/api, // 请求超时本地联调可以调大一点避免断点调试时被掐断 timeout: 10000 };baseURL指向 Nginx 的地址加/api前缀而不是直接写后端地址这样浏览器的所有请求都同源不会触发跨域也方便后面换后端地址时只改 Nginx 一处。这里最容易出的错是把端口写成后端端口或者漏掉/api前缀两种都会导致接口 404 但页面看起来完全正常。改完之后一定要清浏览器缓存再刷或者开一个无痕窗口验证。JS 文件被缓存住的情况太常见了改了配置看不到效果八成是缓存没清。4.3 proxy_pass 的斜杠差异反向代理里最值得单独说一句的就是proxy_pass结尾那个斜杠它决定了路径的重写方式而且不报错只体现在接口 404 上。# 写法 A结尾带斜杠/api/user 转发成 /user location /api/ { proxy_pass http://127.0.0.1:8080/; } # 写法 B结尾不带斜杠/api/user 原样转发成 /api/user location /api/ { proxy_pass http://127.0.0.1:8080; }选哪种取决于后端接口有没有统一前缀。后端接口本身带/api就用 B后端是裸路径就用 A。判断方法很直接在浏览器 Network 里看请求被转发后的实际路径或者直接拿curl打一次后端看哪个能通。这个点我踩过不止一次配置看着一模一样结果一个通一个 404差别就在一个字符上。5. 避坑与排查Nginx 在 Windows 上起不来的五条记录5.1 现象error.log 里报 CreateDirectory() failed (3)现象双击nginx.exe后浏览器访问不了logs/error.log里反复出现CreateDirectory() .../temp/client_body_temp failed (3: The system cannot find the path specified)。原因Windows 的 zip 包不携带空目录解压后temp及其子目录不存在Nginx 启动时要往这些目录写临时文件创建失败就直接退出。路径里含中文或特殊字符时会加剧这个问题但不是唯一原因。解决先进 Nginx 根目录看temp在不在不在就手动建temp/client_body_temp、temp/proxy_temp、temp/fastcgi_temp三个同时确认整个路径没有中文和空格。两件事都做完再启动error.log里不再出现新的[emerg]就算过了。5.2 现象双击一闪而过任务管理器里堆了好几个 nginx.exe现象双击后窗口闪一下消失页面打不开任务管理器里能看到四五个 nginx 进程端口状态混乱。原因每次双击都会尝试拉起一组 master/worker前一个没退干净后一个抢不到端口失败后又留下残留进程。解决先taskkill /im nginx.exe /f全部清掉再用命令行start nginx启动这样失败信息会留在终端里。启动后tasklist /fi imagename eq nginx.exe确认只有一个 master 加一个 worker。以后固定用命令行启停不再双击。5.3 现象启动没报错浏览器 404现象nginx -t通过进程也在访问首页返回 404error.log里是open() .../html/index.html failed。原因root指错了目录或者 dist 里的文件没放进去。浏览器请求的是配置里root加index拼出来的路径跟你在哪个目录启动 Nginx 没有关系。解决把root写成 dist 的绝对路径用正斜杠然后直接到文件管理器里确认dist/index.html真实存在。顺手在error.log里搜open()它会把你实际请求的完整路径打出来对照一下就能看出差在哪一级。5.4 现象端口被占用报 bind() failed现象启动即失败日志里bind() to 0.0.0.0:80 failed (10013)或(10048)。原因80 端口被系统组件、其他 Web 服务或上一个没退干净的 nginx 占着。10013 多与权限或系统保留端口有关10048 是典型的地址已被使用。解决netstat -ano | findstr :80拿到 PIDtasklist /fi pid eq PID确认占用者。是残留 nginx 就强杀是别的服务就把listen改成 8081 之类的空闲端口改完nginx -t再-s reload。改端口比解绑系统端口省事本地开发没必要死磕 80。5.5 现象改了 nginx.conf 重启后没生效现象配置明明改了页面行为还是旧的日志里也没新内容。原因三种可能——改的是备份文件不是nginx.conf用start nginx又起了一个实例访问的其实是旧进程浏览器缓存住了旧的 JS/CSS。解决先nginx -t -c conf/nginx.conf确认改的那份语法正确且路径对再taskkill清干净所有 nginx 进程重新start nginx。浏览器开无痕窗口或者按 CtrlF5 强制刷新。顺序别反先确认进程是新的再怀疑缓存。6. 装完怎么验证一套五分钟能跑完的自检流程装完不等于跑通我更愿意用几条命令把整条链路验一遍而不是靠「浏览器能打开」这一个主观判断。下面这套顺序是从下往上验的先确认服务在跑再确认静态资源对最后确认接口通。第一步确认进程和端口。这两条一起看能排除掉大部分「启动了但没起来」的假象。# 进程应该只有一个 master 和一个 worker tasklist /fi imagename eq nginx.exe # 端口8081 处于 LISTENING 状态PID 与上面一致 netstat -ano | findstr :8081第二步用curl直接看响应头和首页内容绕开浏览器缓存和插件干扰。# -I 只看响应头重点看 HTTP 状态码和 Server curl -I http://127.0.0.1:8081/ # 取首页前 20 行确认返回的是自己的 index.html 而不是默认欢迎页 curl -s http://127.0.0.1:8081/ | head -n 20-I只发 HEAD 请求返回HTTP/1.1 200 OK且Server: nginx/1.20.2说明服务和静态配置都对上了如果返回 404问题在root返回 403多半是目录权限或index没配。第二步的head -n 20是为了确认拿到的不是html/index.html那个默认欢迎页——拿到默认页说明root还指着解压时的html目录。第三步验接口转发。这一条最能暴露proxy_pass的问题。# 打一个后端真实存在的接口看是否被正确转发 curl -i http://127.0.0.1:8081/api/your/real/path # 对照直接打后端两者返回应该一致 curl -i http://127.0.0.1:8080/your/real/path两条命令返回的响应体和状态码一致说明转发路径没有多一层或少一层前缀如果第一条 404、第二条 200就回去看proxy_pass结尾的斜杠和location的匹配前缀。第一次配的时候我把location /api/写成了location /api结果只有带斜杠的请求能匹配上排查花了不少时间。验证项命令通过标准进程tasklist /fi imagename eq nginx.exe一个 master、一个 worker端口netstat -ano | findstr :8081LISTENINGPID 对应 nginx语法nginx -t -c conf/nginx.confsyntax is ok / test is successful首页curl -I http://127.0.0.1:8081/200Server 为 nginx/1.20.2首页内容curl -s ... | head -n 20返回自己的 index.html接口转发curl -i .../api/真实路径与直连后端结果一致这三步跑完能覆盖掉九成的环境问题。剩下的那一成通常出在前端打包产物本身比如资源路径写死、接口地址没替换属于前端构建阶段的事不在 Nginx 这一侧。我自己有个习惯每次在新机器上搭完这套环境都会先把这几条命令连着敲一遍把输出截图存下来当作这台机器的「基线」。以后哪次重启之后页面不对先跟基线对一遍是进程少了、端口变了还是接口路径错了一眼就能看出来。这个习惯是被那次temp目录缺失逼出来的——当时配置一个字没改程序就是起不来我在配置文件里反复找问题最后发现缺的只是一个空文件夹。希望帮到你。本文还有配套的精品资源点击获取 SEO 优化官网定制响应式建站教育培训建站