算下来,我已经在本地折腾过好几轮静态网站生成工具了,从最初的 Hexo 到后来的 VuePress,再到偶尔拿来对比的 Hugo。说实话,VuePress 是我用的最顺手的一个,尤其是当你需要快速搭一套技术文档、团队内部手册或者个人知识库的时候,它几乎没有什么学习成本。这篇文章我想完整聊一次“本地部署静态网站生成工具 VuePress 并实现外部访问”这件事,从环境准备、项目初始化、细节配置,到最终把本地服务暴露给外部访问,全套流程我都会拆开讲,并且把我实际踩过的坑也一并列出来。
这里说的“外部访问”,不是让你去做什么不合适的网络操作,而是指你本机起的站点能被局域网内其他设备访问,或者通过云服务器、内网穿透等方式被公网用户访问。这个需求在很多场景下非常真实:比如你给团队搭了一个内部文档站,自己在电脑上用vuepress dev跑得好好的,结果同事访问不了;又比如你在本地部署了 dify、ollama、comfyui 这类大模型工具链,想顺手给它们配一套操作说明书站点;再比如你就是想把自己写的笔记做成一个线上博客。这些都是 VuePress 本地部署后要解决外部访问问题的典型场景。
这篇文章适合的人很明确:用过一点 VuePress 但对部署和公网访问没有完整概念的人,或者说已经在用 VuePress 写文档但始终只敢在自己电脑上localhost:8080预览的人。我不会跳过基础概念,但也不会啰嗦到教你怎么打开命令行。读完你应该能独立完成“本机开发 → 服务器部署 → 外部访问”这整条链路。
1. 为什么选择本地部署 VuePress:需求场景与方案取舍
1.1 本地部署解决了什么真实问题
很多人提起静态网站,第一反应是放 GitHub Pages、Gitee Pages 或者 Vercel 上,提交代码就能自动构建,确实方便。但这类平台有几个绕不开的限制:仓库必须是公开的,或者至少构建产物要对平台可见;国内访问 GitHub Pages 的稳定性有时候不太理想;你没法做内网隔离,团队内部想放一些不能公开的 SOP、运维手册、接口文档,往公网托管平台一放就是安全隐患。
本地部署的意义恰恰在这里:内容完全由你自己掌控,不需要把 Markdown 源文件交给任何第三方平台,构建和托管都落在自己的服务器或者内网环境里。对于小团队来说,一台 2 核 4G 的云服务器,或者公司内网里一台常年开机的老机器,就足够撑起整个文档站。VuePress 这类静态生成工具的部署成本又特别低,构建出来的产物就是纯 HTML、CSS、JavaScript,丢给 Nginx 就能跑,不需要像 WordPress 那样维护 PHP 环境和数据库,也不需要像有些后端框架那样常驻一个 Node 进程。
另外说句实在话,静态网站生成器特别适合跟本地化的工具链搭配。现在很多人在本地折腾大模型、AI 绘图这类应用,dify、ollama、comfyui 这些名字大家都很熟。这类工具装好之后通常没有一套完整的中文说明文档,你自己写一篇部署记录或者使用手册,用 VuePress 建个站放在本地,手机、平板在同一局域网内随时能查,比躺在微信收藏夹里好一百倍。
1.2 静态网站生成工具选型对比
我不太喜欢无脑推荐某个工具,所以先给一份横向对比,免得你选型选得一头雾水。表里这几个是我实际用过的,不是网上抄来的参数表:
| 工具 | 核心语言 | 上手难度 | 内容编写 | 适合场景 | 我的直观感受 |
|---|---|---|---|---|---|
| VuePress | Vue/Vite | 低 | Markdown + Vue SFC | 技术文档、知识库、博客 | 生态大,默认主题就自带搜索和侧边栏,改起来很方便 |
| Hexo | Node.js | 低 | Markdown | 个人博客 | 博客场景很强,但做结构化文档不如 VuePress |
| Hugo | Go | 中 | Markdown | 博客、文档 | 构建极快,主题也多,但模板语法学习成本略高 |
| Docusaurus | React | 中 | Markdown | 开源项目文档 | 适合大型文档站,但初学者容易迷路 |
| 纯手写 HTML | 无 | 看情况 | 直接写 HTML | 极小的个人页面 | 改一次想砸一次电脑,维护成本太高 |
选 VuePress 的理由如果浓缩成一句,那就是“对 Markdown 友好,对开发者友好,对内容维护者更友好”。你不懂 Vue 也可以直接用默认主题写文档,写了几篇之后想自定义页面,又能用 Vue 单文件组件去扩展,这个成长曲线非常平滑。相比之下 Hugo 的模板语言虽然性能好,但对于纯内容型用户来说门槛高了一点。
1.3 本地部署的完整访问链路
在动手之前,我建议你先理解整个服务链路,后面遇到问题才能定位得快。完整链路分三个阶段:
- 开发阶段:本机运行
vuepress dev,VuePress 起一个开发服务器,默认监听localhost:8080,你通过浏览器改文件、实时预览。这个阶段服务只在本机生效。 - 构建阶段:执行
vuepress build,VuePress 把 Markdown 内容编译成静态文件到dist目录。这个目录是整个部署的核心,它包含了站点全部资源。 - 访问阶段:把
dist目录放到 Nginx、Apache、Caddy 等静态服务器里,或者整个目录直接扔到云存储上。外部用户通过服务器 IP、域名来访问这些静态文件。
对于“外部访问”,其实有三层递进含义:第一层是局域网访问,你手机能通过电脑的内网 IP 访问;第二层是云服务器公网访问,需要把构建产物部署到有公网 IP 的机器;第三层是用域名加 HTTPS 访问,需要解析域名并申请证书。很多人卡在这一步,是因为在浏览器开localhost开习惯了,对 IP、端口、防火墙、反向代理这些概念没有建立直觉。别急,后面每一步我都会拿出命令和配置来讲。
2. 动手前的准备:环境安装与项目初始化
2.1 Node.js 环境版本怎么选
VuePress 分两个大版本,VuePress 1.x 用的是 webpack,对 Node.js 版本要求不高,8.x 以上都能跑,但那个时代已经过去太久,官方维护已经停止。现在新建项目建议直接用 VuePress 2.x,它基于 Vite,启动速度快非常多,热更新也是实时的,体感上比 1.x 舒服太多。VuePress 2.x 要求 Node.js 18 以上,所以最稳的版本选择是 Node.js 20 LTS,这也是目前大多数 Node 项目在用的长期维护版本。别装那种奇数版本比如 21、23,它们不是 LTS,在某些依赖上容易出现兼容性问题。
安装 Node.js 的方式各平台不太一样。Windows 用户直接去官网下载 .msi 安装包,一路下一步就行,安装完命令行里验证一下:
node -v npm -v这两个命令能正常输出版本号,说明环境就绪。macOS 用户我建议用 Homebrew 装,brew install node@20,然后记得看终端提示把路径加进 PATH。Linux 服务器上装的话,最省事的方式是先用包管理器装一个基础版本,再用nvm(Node Version Manager)切换和管理版本,这样以后升级或者多个项目并发切换 Node 版本都方便。
还有一个新手经常忽略的点:npm 默认的源在国外,国内网络环境下下载依赖非常煎熬。建议项目开始前就配好镜像源:
npm config set registry https://registry.npmmirror.com这个不是必须的,但你不配的话,第一次npm install可能就要等好几分钟甚至超时,直接影响体验。配完之后可以用npm config get registry验证一下当前源地址。
2.2 创建 VuePress 项目并跑通第一个页面
项目结构我建议这样规划,比较清晰:
my-docs/ ├── docs/ │ ├── .vuepress/ │ │ ├── config.js │ │ └── public/ │ ├── README.md │ ├── guide/ │ │ ├── README.md │ │ └── deploy.md │ └── ... ├── package.json └── package-lock.jsondocs目录是 VuePress 约定的源文件目录,你也可以用别的名字,但默认约定不需要额外配置。.vuepress目录放配置和主题,public目录放静态资源,比如图片、favicon,这些文件会被原样拷贝到构建产物里。
初始化第一步是在项目根目录创建package.json:
npm init -y然后本地安装 VuePress。这里强调一下,个人项目强烈建议作为开发依赖安装,而不是全局安装。全局装的问题在于,一旦项目被移动到别的机器上,你还得重新全局装一遍,而且全局版本和项目要求的版本容易冲突。项目内安装的命令是:
npm install -D vuepress@2安装完之后,修改package.json里的 scripts,添加两个常用命令:
{ "scripts": { "docs:dev": "vuepress dev docs", "docs:build": "vuepress build docs" } }接下来在docs目录下写第一个 Markdown 文件,当作首页,里面放几行字:
# 我的第一个 VuePress 站点 这是通过本地部署搭建的文档站点首页。然后启动开发模式:
npm run docs:dev启动成功之后终端会显示访问地址,默认一般是http://localhost:8080/。浏览器打开,看到那行大字,项目就跑通了。整个过程中我遇到过一个小坑:npm init -y生成的产品名如果包含大写字母,npm 会报错。解决办法是把package.json里name字段改成全小写,比如my-docs。
2.3 快速理解 Markdown 增强语法
VuePress 的一个核心竞争力是它对 Markdown 做了很多开箱即用的扩展。最常用的有三个:
- 代码块语法高亮:
js、python 这种写法在构建时会自动着色,不用额外装插件; - 这里就是你可以放代码的地方,语法高亮是自动的;
- 自定义容器:在 Markdown 里用
:::包裹出带边框的提示块,比如::: tip、::: warning、::: danger,写注意事项时会很好看; - 表格和任务列表:GFM 风格的支持,写需求列表非常顺手。
比如这个带提示块的写法:
::: tip 这里是一段提示文字,构建后会有蓝色的提示框效果。 :::这些语法没有任何学习成本,很多写 GitHub README 的人就已经会了。VuePress 只是把体验做得更完整,让文档站看起来更像一个正式的产品页面,而不是纯文本堆砌。
3. 核心配置与本地调试:把站点调成你想要的样子
3.1 配置文件和常用字段
站点所有核心配置都集中在docs/.vuepress/config.js里。我直接把一个最常用的基础配置贴出来,很多时候你只需要在这个基础上改标题和导航就够了:
module.exports = { lang: 'zh-CN', title: '我的文档站', description: '基于 VuePress 的本地部署文档站点', head: [ ['link', { rel: 'icon', href: '/favicon.ico' }] ], themeConfig: { logo: '/images/logo.png', nav: [ { text: '首页', link: '/' }, { text: '指南', link: '/guide/' }, { text: '部署', link: '/deploy/' } ], sidebar: { '/guide/': [ { text: '基础', children: [ '/guide/readme.md', '/guide/config.md' ] } ] } } }title和description不光是展示用的,构建时还会被写成 HTML 的<title>和<meta name="description">,对 SEO 有影响。themeConfig.nav是顶部导航栏,themeConfig.sidebar是侧边栏。如果你只想快速跑起来,侧边栏可以暂时不配置,VuePress 会按目录结构自动生成;但对内容较多的站点,我建议手动配置,这样能精确控制导航层级。
很多人刚开始会忽略lang字段,不设置的话默认是英文。这个字段包括默认主题里很多展示文案的语言,比如搜索框提示、文章目录标题,所以中文站一定要设成zh-CN。
3.2 开发模式与构建模式的差异理解
npm run docs:dev和npm run docs:build是两回事,我经常看到有人搞混。开发模式启动后,VuePress 会起一个 Vite 开发服务器,它做的事情是:实时监听 Markdown 文件变化,把当前打开页面的改动热更新到浏览器。好处是反馈极快,坏处是它依赖 Node 进程,不能直接拿给外部做正式访问。
构建模式则是完整的编译过程。它会把整个docs目录下的所有 Markdown 文件、配置、主题、静态资源全部处理成静态文件,默认输出到docs/.vuepress/dist。这个目录是“成品”,你把它放到任何静态文件服务器上都能运行,不需要再安装 Node.js,不需要 VuePress,只需要有一个能返回文件的 HTTP 服务器就行。这个“内容与运行时分离”的特性,是静态站方案最大的优势,也是它能以极低成本部署的原因。
要验证构建产物是否正常,可以用一行命令起个临时静态服务来看:
npx serve docs/.vuepress/distserve是一个很轻量的工具,会自动选择端口并打印访问地址。这种方式适合在本地快速检查构建结果,没有 Nginx 也完全不影响开发。
3.3 开发模式下的局域网预览技巧
开发模式下默认监听的是localhost,这意味着只有本机能访问。如果你临时想用手机看一下页面效果,或者让同事在局域网里预览,可以在启动命令里加上--host:
npx vuepress dev docs --host 0.0.0.0也可以把它写进package.json的 scripts 里:
{ "scripts": { "docs:dev": "vuepress dev docs --host 0.0.0.0" } }0.0.0.0的含义是监听本机所有网卡地址。启动后,命令行会打印出局域网访问地址,通常是http://你的内网IP:8080/。在 Windows 上你可以用ipconfig查内网 IP,macOS 或 Linux 用ip addr或ifconfig。让别人访问时,必须确保你们在同一局域网,而且电脑防火墙没有拦截 8080 端口。这个功能在前期内容审核时特别有用,手机上划着看比盯着电脑舒服。
3.4 本地调试中的常见小问题
开发模式下遇到问题,第一反应是看终端输出。VuePress 的错误提示做得比较清楚,常见的无非这几类:Markdown 文件里引用了不存在的图片路径导致构建失败;配置文件写错语法导致启动直接退出;侧边栏里写了没有创建的页面路径导致 404。
还有一个比较隐蔽的问题:在某些网络环境下,开发模式启动时 Vite 需要做依赖预构建,如果 npm 安装依赖的时候没有完整装好,会出现启动很慢或者依赖二度优化的提示。这时候不用重启整个服务,直接删掉node_modules和package-lock.json,重新npm install一般能解决。
我自己的经验是,开发模式出现页面 404 时,先看看 URL 路径是不是带.md后缀了。VuePress 的默认技巧是干净 URL,也就是说/guide/deploy对应的是docs/guide/deploy.md,不要手动把.md加进链接里。
4. 构建产物分析与部署方案:从 dist 到 Nginx
4.1 build 产物里到底有什么
执行npm run docs:build之后,去看docs/.vuepress/dist目录,你大概会看到类似这样的结构:
dist/ ├── assets/ │ ├── css/ │ ├── js/ │ └── img/ ├── guide/ │ ├── index.html │ └── deploy.html ├── index.html └── 404.htmlassets目录里是 Vite 打包后的 JS 和 CSS 文件,文件名通常会带一串哈希值,比如app.9f3a2b.js。哈希的作用是缓存穿透:文件内容变了,哈希跟着变,浏览器就知道要拉新文件;内容没变,哈希不变,浏览器就用本地缓存。dist里每个 Markdown 页面都会生成一个对应的 HTML 文件,这就是静态站的核心——访问者请求什么路径,服务器直接返回那个路径的 HTML,完全不需要后端计算。
有时候你会在dist里看到 404 页面,这是 VuePress 默认主题生成的,用来处理访问了不存在的路径的情况。部署后记得确认 404 页面能被正确返回,这个细节对 SEO 和用户体验都有影响。
理解构建产物的意义在于,你会知道部署的本质就是“把这一堆静态文件放到一个 HTTP 服务里”。它不复杂,但很多人被“部署”这两个字吓住了,其实这一步比开发模式简单得多。
4.2 常见部署方式选型对比
部署静态站的方式很多,我把常见方案和适用场景列一下,方便你对号入座:
| 部署方式 | 前置条件 | 优点 | 缺点 | 推荐度 |
|---|---|---|---|---|
| 直接丢到服务器用 Nginx 托管 | 一台 Linux 服务器 | 可控性最强,性能好,可配 HTTPS | 需要会点服务器基础命令 | 强烈推荐 |
| 云存储托管(OSS/COS/S3)+ CDN | 有云厂商账号 | 高可用,不用担心流量 | 需要额外配置域名和证书 | 流量大的站点推荐 |
| 内网穿透工具 | 一条能出网的本地网络 | 本地就能对外提供访问,不用买服务器 | 带宽受限制,不适合生产 | 临时演示用 |
| GitHub Pages | GitHub 仓库 | 免费,不用维护服务器 | 国内访问不稳定,公开内容 | 个人博客可以考虑 |
我个人默认推荐的是第一类,用 Nginx 托管。原因很简单:Nginx 本身就是为静态内容设计的,处理静态文件能力极强,配置也不复杂,而且它还能兼任反向代理,以后你在服务器上跑别的服务,统一从 Nginx 入口转发非常方便。
4.3 Nginx 部署静态站点的完整配置
假设你把构建出来的dist目录上传到了服务器的/var/www/my-docs路径下,接下来只需要在 Nginx 配置里写一个 server 块。先安装 Nginx,以 Ubuntu / Debian 为例:
sudo apt update sudo apt install nginx然后创建一个站点配置文件,比如/etc/nginx/sites-available/my-docs.conf:
server { listen 80; server_name docs.example.com; root /var/www/my-docs; index index.html; location / { try_files $uri $uri/ /index.html; } gzip on; gzip_min_length 1k; gzip_types text/plain text/css application/javascript application/json; }配置里最关键的就是try_files $uri $uri/ /index.html;这一行。它的意思是,如果请求的路径没有对应的文件,就回退到index.html。这样做有两个原因:一是 VuePress 默认生成的路径都是真实的 HTML 文件,大部分请求能直接命中;二是如果你用了支持 history 模式的路由,比如访问/guide/,但实际没有这个目录,Nginx 会正确返回首页而不是 404。
写完配置后,启用站点并重载 Nginx:
sudo ln -s /etc/nginx/sites-available/my-docs.conf /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginxnginx -t是检查配置语法,这一步很重要,很多错误都是把配置文件路径写错了,导致 Nginx 拒绝启动。重载之后,用浏览器访问你配置的server_name,如果配置了域名且域名解析正确,就能看到站点了。如果你手头没有域名,也可以直接用服务器公网 IP 访问,那server_name可以省略或者写_,表示匹配所有请求。
注意:如果你用的是云服务器,别忘了在云控制台的安全组里放行 80 端口和 443 端口。安全组是云服务器的最外层防火墙,只有它允许流量进来,Nginx 才能收到请求。很多初学者把服务启动了,但外部一直访问不了,八成就是安全组规则没配置。
4.4 用宝塔面板做图形化部署值不值得
我知道有一部分人听到“命令行、Nginx 配置”就头大。如果你真的不想碰命令行,用宝塔面板这类图形化管理工具也可以完成同样的事。宝塔里安装 Nginx,然后把dist目录通过面板的文件管理上传到网站目录,再创建站点绑定域名或者 IP,面板会自动帮你写好 Nginx 配置。
这样的好处是门槛低,坏处是面板本身需要占用一定系统资源,而且为这个功能装一个面板有点大材小用。我的建议是:如果你已经有一台宝塔管理的服务器,顺手用它部署没问题;如果是为了部署 VuePress 特意装个宝塔,那不如花半小时熟悉一下最基础的 Nginx 配置,后面维护同样的服务会顺手得多。部署这件事,本质是改几个文件和跑几条命令,不玄学。
5. 实现外部访问:局域网、公网与域名的完整链路
5.1 固定公网 IP 下的直连部署
如果服务器本身有固定的公网 IP,外部访问路径是最简单的。把dist部署到 Nginx 后,用户直接在浏览器输入http://服务器公网IP就能访问。但这里有几个细节必须处理好:
第一个是端口。Nginx 默认监听 80,所以公网 IP 访问默认就是 80 端口,URL 里不用写端口号。如果你用vuepress dev直接对外提供服务,默认 8080 端口,访问的时候必须写成http://IP:8080,很多没经验的用户会漏掉端口号,然后就以为网站没起来。
第二个是域名与 IP 的关系。直接用 IP 访问能通,但生产环境我更建议绑定域名,因为 IP 地址不便于记忆,而且如果你后续换服务器,IP 变了,用户只能靠重新问地址。域名绑定到 IP 后,换服务器只需要改 DNS 解析记录,对外保持域名不变。
第三个是备案问题。如果你把站点部署在国内机房,用域名访问时根据相关法规需要进行 ICP 备案,这是国内互联网的基础规则,正规流程去对应平台提交即可。如果你的服务器在境外,这个环节就没有了,但也意味着国内访问速度会有波动。这一块我不展开,属于运维常识,需要什么流程搜索一下就有官方指引。
5.2 内网穿透的原理与本地暴露方案
另一种常见情况是:你没有云服务器,不想为临时项目花钱,但确实需要让外部的人访问到你本机运行的 VuePress 站点。这就用到内网穿透。
内网穿透的原理,我换一个生活化的类比来解释。你的电脑在一个局域网里,平时外人找不到它。内网穿透工具做的事情,相当于在公网上租了一个“中转站”(通常是一台有公网 IP 的服务器),你本机持续和这个中转站建立连接,公网用户访问中转站时,请求就被自动转发到你本机运行的 8080 端口上。整个过程不需要改路由器设置,也不需要公网 IP。
常见的内网穿透方案有很多,比如 frp 这种自托管的反向代理工具,你用一台有公网 IP 的服务器做中转,把流量转发到本地;也有一些国内团队提供的穿透服务,注册后能拿到一个临时域名来做访问测试。选择哪种主要看你的需求是临时的还是长期的。临时演示用别人的公共服务完全够,长期使用我更推荐 frp 这类自托管方案,因为你能掌握整个链路的数据流向,不依赖第三方服务商。安全上,穿透工具相当于把内网端口暴露到了公网,因此穿透的目标服务一定要做好访问控制。
5.3 域名解析与 HTTPS 证书的配置细节
域名和 HTTPS 是整个外部访问体验里最“专业感”的部分,但是说实话配置起来并不难。域名解析的本质就是把一个域名指向一个 IP,比如你在域名服务商的控制台添加一条 A 记录,把docs.example.com指向你的服务器公网 IP,整套全球生效通常在几分钟到几小时内。
DNS 配置好之后,访问http://docs.example.com应该已经能通。接下来要做的是 HTTPS。免费的 SSL 证书方案,最常用的是 Let's Encrypt,配合certbot工具,基本一条命令就能签出证书并自动配置到 Nginx:
sudo apt install certbot python3-certbot-nginx sudo certbot --nginx -d docs.example.comcertbot会自动修改你的 Nginx 配置,添加证书路径和 HTTP 跳转 HTTPS 的规则。证书有效期是 90 天,但certbot会安装一个定时任务自动续期,你不需要手动处理。有了 HTTPS,浏览器地址栏就不再提示不安全,这在对外分享链接时非常重要——很多人对这个绿色小锁有莫名的信任感,虽然不是绝对安全,但这是最基本的公网礼仪。
这里还有一个细节是,如果证书申请前 DNS 还没有生效,certbot 会报错。我的建议是先用 dig 或者在线工具确认解析生效后再申请证书,省掉一次不算短的报错排查。
5.4 外部访问的安全踩线与访问控制
站点一旦能从“外部”访问,安全问题就不能完全忽视。按我的经验,静态站的攻击面其实很小,因为你没有数据库、没有服务端脚本,攻击者能做的有限,但仍然有两个方向值得处理。
第一是只允许预期的人访问。如果你的文档站是给团队成员看的,建议在 Nginx 层加 HTTP Basic Auth,也就是账号密码登录。配置方式是在站点目录下生成一个密码文件,然后配置auth_basic。这段配置非常轻量:
location / { auth_basic "Restricted Area"; auth_basic_user_file /etc/nginx/.htpasswd; }密码文件可以用openssl passwd生成,然后把用户名和加密后的密码写进去。这样虽然会在地址栏弹一个系统自带的登录框,样子很朴素,但对于内部协作的文档站已经足够。
第二是如果是公网开放的内容,要控制好 Nginx 访问日志的保留策略和错误页泄露的信息。默认配置下 Nginx 会把客户端 IP、UA、请求路径全量打印到日志里,如果站点是长期运行的,建议配置logrotate定期轮转日志,避免磁盘被日志打满。这两个点都不难做,但很多人从头到尾都忽略了,直到服务器磁盘爆了才发现日志已经几个 G 了。
6. 常见问题与排查技巧实录:我踩过的坑都在这
| 现象 | 大概率原因 | 解决办法 |
|---|---|---|
vuepress dev启动失败 | Node.js 版本太低或者依赖没装完整 | 先执行node -v确认版本,再删除node_modules重新npm install |
| 开发模式正常,构建报错 | Markdown 内引用了不存在的资源,或者代码块语法正确但某个插件冲突 | 看构建日志,定位到具体文件,检查图片路径、链接路径 |
| 外部访问不到,但本机能访问 | 云安全组没放行对应端口 / Nginx 没监听 / 防火墙拦截 | 检查安全组规则、netstat -tlnp看端口监听状态、systemctl status nginx |
| 访问出现 404 | 请求路径和文件路径不匹配 | 确认try_files配置了/index.html回退,或者检查侧边栏链接是否带.md |
| 页面能打开但样式全乱了 | base路径配置错误 | 如果你部署在子路径,需要把base设置为对应路径,比如'/my-docs/' |
| 局域网访问很慢 | 开启了 https 但证书不受信任 | 局域网环境避免使用自签名证书,直接 HTTP 访问即可 |
6.1 端口占用与启动失败
vuepress dev默认使用 8080 端口,如果你机器上正好有其他服务占用了这个端口,启动时会直接报错。解决方式有两个:一个是在启动命令里指定其他端口:
npx vuepress dev docs --port 9090另一个是找到占用进程并结束它。Windows 下用netstat -ano | findstr 8080找到 PID,然后在任务管理器里结束对应进程;Linux 下用lsof -i :8080或者fuser -k 8080/tcp。
6.2 部署后样式丢失
这个问题常见于把 dist 部署到某个子目录,比如你已经有一个主站,VuePress 部署在/blog/下。这个时候必须在config.js里设置 base:
module.exports = { base: '/blog/' }base的值决定了构建产物里所有静态资源的引用路径。如果不设置,VuePress 默认引用根路径/assets/...,导致浏览器在/blog/页面下请求/assets/...,结果当然找不到,样式就全丢了。这个问题不算难,但它很隐蔽,尤其是平时开发模式完全正常,部署之后才暴露。
6.3 内网可访问,外网不通
有一类很典型的现象:局域网里手机用http://192.168.x.x:8080能访问,但到了公网就怎么也进不来。如果确认安全组已经放行了端口,问题大概率出在“你访问的 IP 不是服务所在机器的 IP”。比如你在公司网络里,电脑是通过路由器的 NAT 上网的,外部访问你电脑的流量必须先到路由器,路由器还要把公网端口映射到内网机器。这需要你在路由器管理页面做端口转发,而不是在电脑上配置就能解决。
这也是我推荐“云服务器 + Nginx + 内网穿透”两步走的原因。本地机器做开发、做临时演示非常方便,但要稳定地让外部访问,还是得有一个稳定的公网入口。
6.4 配合本地大模型工具链的扩展场景
最近很多人在本地部署大模型工具链,比如 ollama、dify、comfyui 这些,装完之后生成一个 API 或者 Web 服务,但文档一直是散的。如果你已经有了一套 VuePress 文档站,完全可以把它变成这些工具的本地说明门户。方案也很直观:在文档站里写每个工具的部署步骤、模型拉取命令、API 调用示例,再把这些服务的管理地址统一挂到侧边栏导航里。
这样做的好处是,你把零散的工具说明集中到一个入口,团队新成员加入的时候不用再挨个去翻文档,直接把http://localhost:8080甩给他就行。如果你把 VuePress 站点和这些本地服务都部署在同一台服务器上,还可以用 Nginx 做一个简单的反向代理聚合页,通过/ollama/、/dify/这样的路径转发到不同服务的端口。这个扩展思路不复杂,但对本地化工具链的使用体验提升非常明显,算是把静态站点和动态服务结合得很好的一个方向。
最后说点实际的体会。VuePress 的本地部署和外部访问,技术上真的不算难,难的是把“开发、构建、部署、网络”这条链路完整理解透。我第一次从localhost走到页面能被外网 IP 访问的那个晚上,其实只改了几个配置,但那种打通整条链路的踏实感,比任何工具本身的技巧都重要。如果你看完这篇文章,能动手把一条完整的访问链路跑通,那这个时间花得就值了。