
本地部署一个静态网站生成工具这两年被问得越来越频繁问的最多的就是 VuePress。我自己的个人博客和团队文档站都是用它搭的本地开发、构建出静态文件、再决定要不要开放给外部访问这一整套流程闭着眼都能走完。今天把完整过程写清楚从安装 Node、初始化项目、写第一个页面到构建产物再到三种把站点暴露到外网的方式每一步都有命令、有配置、有踩坑记录。你照着做基本不会卡壳。先说下这篇适合谁想搭个人博客但不想折腾数据库的人团队里要维护一套低成本文档库的人以及前端刚入门想搞清楚“静态网站生成工具到底怎么运作”的人。VuePress 的上手门槛不高只要会 Markdown半小时内就能看到一个能跑起来的站点。1. VuePress 本地部署前的方案选型与整体思路1.1 静态网站生成工具是什么为什么我选了 VuePress静态网站生成工具也就是常说的 SSG做的事情很简单把 Markdown 文档或数据文件作为原料通过模板和组件渲染在本地生成一堆纯 HTML、CSS、JavaScript 文件。这堆文件不需要数据库不需要 PHP、Node 之类的服务端运行时任何能托管静态文件的服务器都能直接跑。VuePress 在同类工具里的优势很明显它是 Vue.js 生态下的产物核心技术栈跟做前端的人日常写的东西完全一致。默认主题直接给你配好了导航栏、侧边栏、搜索框、目录层级这些做技术文档最常用的功能开箱即用。而且 Markdown 里可以直接写 Vue 组件遇到需要展示动态示例的页面会很舒服。我拿它和身边几个工具对比过选型时可以看这张表工具技术栈适合场景特点VuePressVue技术文档、组件库文档、个人笔记默认主题完善Markdown 内嵌组件方便HexoNode纯博客站点主题多、生态老但自定义文档站比较费力DocusaurusReact团队文档、多版本文档国际化、版本管理强React 使用者友好Astro多框架内容站、复杂首页灵活度高但要自己搭的东西也多如果你跟我一样主要写技术文档和博客VuePress 是性价比最高的选择。它的学习成本低到可以忽略文档本身是中文的遇到问题社区资料也多。1.2 本地部署与线上托管的边界怎么划分很多人对“本地部署”有个误解以为就是把服务跑在自己电脑上自己玩。实际上我日常的开发路径是分阶段的开发阶段本地跑vuepress dev改一个文件浏览器立刻热更新效率远高于在服务器上直接改。内部分享阶段构建出静态产物后往局域网一扔同事通过 IP 地址就能访问。公网开放阶段再做一次产物同步或端口映射让外部访客访问。本地部署的最大价值是可控、免费、离线也能用数据在自己手里。但代价也明显没有云厂商帮你扛流量和 CDN机器断电服务就没了公网访问还需要自己搞定入口、安全和 HTTPS。所以不用迷信某一种模式哪个阶段用哪种方式心里有数就行。1.3 我最终采用的部署架构我的思路可以概括成“本地开发、产物分发、网关接入”个人电脑上做所有写作和 theme 调试构建后的静态文件有两种出口。常规情况下用rsync把产物推到云服务器由 Nginx 托管临时要给合作方看效果时才用端口映射工具开一条临时公网地址用完就关。这样既稳当又省钱。2. 从零开始搭建 VuePress依赖、初始化与配置2.1 先看版本别让 Node.js 变成第一个坑跑 VuePress 需要 Node.js这是绕不开的一步。如果你只装一个环境建议直接上 Node.js 18.16 或更高的版本因为这是 VuePress v2 的硬性要求。先确认当前版本node -v npm -v如果版本偏旧可以考虑用 nvm 来管理多版本它能在项目之间灵活切换 Node 版本。我踩过一个典型坑VuePress v1 在 Node 17 以上运行时会报一个跟 OpenSSL 有关的错误这个后面常见问题里细说。简单讲2025 年的今天新项目直接上 v2 就好。另外提一句 npm 下载速度的问题如果你发现官方源安装依赖很慢可以临时换用镜像源加参数例如npm install -D vuepressnext --registryhttps://registry.npmmirror.com这纯粹是下载层面的加速不影响任何其他环节。2.2 初始化项目搞清楚每个文件干什么我比较推荐手工初始化哪怕多敲两行命令它会让知道每个文件在哪里、是干什么的。先建目录再初始化mkdir docs-site cd docs-site npm init -y然后安装 VuePress。v2 正式版发布后直接装 latest 就行如果你习惯用 next 标记也可以npm install -D vuepressnext等依赖装完创建这样的目录结构docs-site/ ├─ docs/ │ ├─ .vuepress/ │ │ ├─ config.js │ │ └─ public/ │ └─ README.md ├─ package.json └─ .gitignoredocs是 VuePress 默认的源目录你在里面写的所有 Markdown 文件就是站点的页面。.vuepress放配置和静态资源README.md就是首页。.gitignore记得把node_modules和dist排除掉。如果你想省事官方也提供了脚手架命令npm create vuepresslatest但新手我不建议直接用因为脚手架帮你隐藏了太多细节出了问题不好排查。2.3 package.json 脚本与 config.js 关键参数在package.json里配置两条最常用的命令scripts: { dev: vuepress dev docs, build: vuepress build docs }然后在docs/.vuepress/config.js里写入基础配置const { defaultTheme } require(vuepress); module.exports { base: /, lang: zh-CN, title: 我的文档站, description: 用 VuePress 本地部署的静态网站, host: 0.0.0.0, port: 8080, theme: defaultTheme({ navbar: [ { text: 首页, link: / }, { text: 指南, link: /guide/ }, ], }), };这里几个参数值得先说清楚base决定资源引用的根路径。如果你部署在域名根路径那就用/如果要部署到https://example.com/docs/这里必须改成/docs/否则页面能打开但样式和脚本全部 404。host默认是localhost这意味着只有本机能访问。想局域网访问必须改成0.0.0.0。port是开发服务器端口默认 8080被占用时可以换。3. 本地预览、构建生成静态产物与局域网访问配置3.1 dev 模式的正确启动姿势在你已经完成上面配置的前提下启动命令非常简单npm run dev正常情况下终端会打印两条地址Localhttp://localhost:8080/Networkhttp://192.168.x.x:8080/前者是本机访问后者是局域网内其他设备使用的地址。如果你发现 Network 那行地址不对或者显示不出来优先检查config.js里的host到底改成0.0.0.0没有。这一步是很多新手首次局域网访问失败的原因。在电脑上查局域网 IPWindows 用ipconfigmacOS 或 Linux 用ip addr或ifconfig。找到类似192.168.x.x的地址让同一 Wi-Fi 下的手机浏览器直接访问这个地址加端口号即可。VuePress 的 dev 模式带热更新改 Markdown 内容浏览器会自动刷新不需要手动重启。写长文档时这个体验非常关键实时看到排版效果比写完再构建高效得多。3.2 build 构建产物验证纯静态文件开发完成以后需要构建出可上线的静态产物npm run build默认输出目录是docs/.vuepress/dist。打开这个目录你会看到里面全是index.html、assets之类的静态文件。这就是静态网站生成工具的效果所有页面已经渲染成纯 HTML不再依赖 Node 运行时。构建完成后你可以在本地用任意静态服务器模拟线上环境npx serve docs/.vuepress/dist这一步强烈建议做因为 dev 模式下 VuePress 会帮你处理路由和各种资源路径很多问题在 dev 下看不出来只有以纯静态方式访问时才会暴露。3.3 局域网访问最容易踩的防火墙坑当你兴致勃勃把192.168.x.x:8080发给同事结果对方打不开十有八九是防火墙拦住了入站端口。Windows 上的处理方式打开“Windows 安全中心”进入“防火墙和网络保护”里的“高级设置”在“入站规则”中新建规则选择“端口”填上 8080允许连接应用到所有网络类型。整个过程一点不复杂但很多人第一次操作时会卡在找不到入口。如果用的是 Linux 服务器或开发机常见命令是# ufw sudo ufw allow 8080 # firewalld sudo firewall-cmd --add-port8080/tcp --permanent sudo firewall-cmd --reload另外提醒一句不要为了省事直接把防火墙关了。放行指定端口就够了关掉防火墙会带来完全没必要的安全风险。这也是我在本机折腾时最常看到的错误操作。4. 实现外部访问三种方案对比与完整实操4.1 方案一构建产物部署到云服务器正式环境首选这是个人站和团队文档站最常见、也最稳定的一种外部访问方式。思路是把本地构建好的静态文件用同步工具传到远程服务器再用 Nginx 或其他静态服务器托管。先在本机构建npm run build然后通过 rsync 同步到服务器一条命令就能搞定增量同步rsync -av --delete docs/.vuepress/dist/ useryour-server:/var/www/my-site/注意路径末尾的斜杠它表示把dist目录下的内容同步到目标目录而不是把dist本身嵌套进去。--delete会让远端删除那些源端已经移除的旧文件避免发布后残留垃圾文件。服务器上的 Nginx 配置可以参考server { listen 80; server_name docs.example.com; root /var/www/my-site; index index.html; location / { try_files $uri $uri/ /index.html; } }这里核心是try_files那行它会让请求在找不到实际文件时回退到index.html避免刷新子页面出现 404。改完配置后执行sudo nginx -t检查语法然后sudo systemctl reload nginx让配置生效。这个方案的好处是所有文件都落在服务器上访问质量和速度都受你自己控制。代价是你需要一台云服务器和一个域名。如果你暂时没有服务器可以看下面两个方案。4.2 方案二路由器端口映射把公网请求引到本地如果你的网络环境有公网 IP可以在路由器上做端口映射把外部访问引导到本地运行 VuePress 的电脑。操作步骤进入路由器后台找到“端口映射”或“端口转发”功能新增一条规则。外部端口填8080内部 IP 填你电脑的局域网地址例如192.168.1.100内部端口也填8080协议选 TCP 即可。这个方案有个前提你的宽带给到路由器 WAN 口的 IP 必须是真正的公网 IP。很多家庭宽带其实是运营商二次分配的内网 IP这种情况下路由器端口映射做得再对也没用。判断方法很简单路由器 WAN 口 IP 跟你在百度上搜到的出口 IP 是否一致一致就是公网 IP。实际用这个方案时有两点提醒暴露给外网的一定是构建后的静态产物而不是 dev server。开发模式有热更新调试接口等额外能力不适合作为对外服务。如果可以优先在路由器上更换一个不常见的端口比如18080这样能减少一些自动化扫描的骚扰。4.3 方案三用内网映射工具临时生成公网地址适合快速演示这是我最常用来给临时访客展示效果的方式。它可以在没有公网 IP、没有云服务器的前提下把本地端口映射成一个公网临时地址。常见的工具有 ngrok、frp、cpolar 等它们的使用场景都是开发者自己的项目演示和测试操作上够简单、用完随时可以关闭。以 ngrok 这类托管型工具为例安装并注册后一行命令就能把本地服务公开出去ngrok http 8080执行后会生成一个临时的公网域名任何人在浏览器里打开都能访问到你本机的 VuePress 页面。这个临时域名在免费模式下每次启动会变化适合演示完就关闭的场景。如果你追求稳定可控可以用 frp 这类自建映射工具。原理是一台有公网 IP 的服务器做中转你本地安装客户端连接到它之后所有访问都会转发到你的电脑。服务端配置frps.ini[common] bind_port 7000客户端配置frpc.ini[common] server_addr your-server-ip server_port 7000 [web] type tcp local_ip 127.0.0.1 local_port 8080 remote_port 8080再分别启动服务端和客户端外部访问your-server-ip:8080就会落到你本地的 8080 端口。手法很简单但要注意这类工具要把本机服务短暂暴露给公网必须严格限定在自己项目的演示、测试这类合规场景中使用不要用来做任何绕过访问控制的事情用完立刻关闭映射进程。4.4 外部访问上线前的检查清单不管选哪种方案正式开放外部访问之前我都建议过一遍自己定下的检查清单域名有没有做解析解析是否已经生效ping一下确认。对应端口是否放行云服务器安全组、系统防火墙、路由器端口映射这三层都要查。base路径和最终访问路径是否一致子目录部署最容易翻车。你暴露出去的是不是静态产物而不是开发服务器。如果对外长期提供服务建议在网关层配置 HTTPS这个虽然不会影响访问成功率但影响访客信任度。确认有日志或者有办法在异常时立刻关掉入口避免站点裸奔。5. 常见问题与排查技巧实录5.1 npm run build 报错 ERR_OSSL_EVP_UNSUPPORTED这个报错信息很有特点完整提示通常是Error: error:0308010C:digital envelope routines::unsupported原因是 Node.js 17 之后默认启用了 OpenSSL 3.0而 VuePress v1 使用的 webpack 4 跟它不兼容。如果你还在维护 v1 老项目临时解决办法是在命令前加一个环境变量NODE_OPTIONS--openssl-legacy-provider npm run devWindows 的 PowerShell 用$env:NODE_OPTIONS--openssl-legacy-provider; npm run dev但这不是长久之计最一劳永逸的办法是把项目升级到 VuePress v2它是基于 Vite 的没有这个历史包袱。5.2 页面能打开但 CSS 和 JS 全部 404这个坑十个人里有八个会踩。现象是首页 HTML 加载出来了但样式全丢、排版乱成一片点开控制台全是.css和.js资源 404。原因几乎都是base配置不对。你如果把站点部署到https://example.com/docs/但config.js里还写着base: /所有资源都会从域名根路径去找自然 404。修复方式非常简单打开docs/.vuepress/config.js把base改成你实际的子路径module.exports { base: /docs/, };改完以后重新npm run build再上传产物。一定要构建后再传因为base是构建期写进产物里的不是运行时配置。5.3 端口被占用dev 模式“悄悄”换端口VuePress dev 模式有个行为如果配置的端口已经被占用它会自动往上寻找下一个可用端口。很多人没注意终端日志以为自己访问的是 8080结果实际服务跑在 8081然后一顿排查发现没毛病就是端口对不上。检查端口占用# macOS / Linux lsof -i:8080 # Windows netstat -ano | findstr 8080找到占用进程后如果是旧开发服务残留直接结束进程再重启。不想处理旧进程的话也可以干脆在config.js改一个不常用的端口比如9090。5.4 外部访问始终打不开的排查清单当你在本地一切正常但外部访问死活不通时不要慌按顺序逐层排查。我一般按照这张表来定位现象可能原因排查方式外部请求无响应端口未放行依次检查系统防火墙、路由器端口映射、云服务器安全组局域网能访问公网不行宽带没有公网 IP对比路由器 WAN 口 IP 与出口 IP 是否一致有响应但打不开页面暴露的是 dev server 而非产物dev 模式只建议本机用外部访问必须用构建产物页面乱码、样式丢失base配置错误确认实际访问路径和构建配置中的base是否一致刷新子页面 404缺少路由回退规则Nginx 配置里必须写try_files $uri $uri/ /index.html;5.5 rsync 同步后权限导致 Nginx 403同步完静态文件到服务器后如果 Nginx 返回 403多半是目录权限问题。rsync 默认会保留源文件的权限而你本机文件的所有者跟服务器上 Nginx 运行用户不一致。检查并修复sudo chown -R www-data:www-data /var/www/my-site sudo chmod -R 755 /var/www/my-site修改完记得刷新浏览器Nginx 这类静态服务不需要重启也能生效但权限问题要先确认文件确实能被启动 Nginx 的用户读取。最后再分享一个我自己的使用习惯平时所有开发和写作都在本地 dev 模式完成构建产物用一条脚本自动 rsync 到服务器临时给合作方演示时才用映射工具开一个公网地址用完立即关闭。这个流程跟了我快两年基本没有出过大问题。你只要把上面这些细节都过一遍VuePress 本地部署加外部访问这件事真的不算复杂。