☰
云服务器上从零搭建Hugo静态博客:Nginx部署与避坑指南
2026/10/21 10:09:07 网站建设 项目流程

1. 为什么我最终选了Hugo而不是WordPress

很多人第一次想搭个人博客,脑子里蹦出来的第一个词就是WordPress。我一开始也是这么想的,毕竟它名气大、插件多、教程满地都是。但真正动手之后才发现,WordPress对一台低配云服务器来说,负担其实不小——它需要PHP运行环境、MySQL数据库,光是这两个东西就吃掉不少内存。我那台1核1G的入门级云主机,装完LNMP环境之后,系统负载常年飘红,打开后台都要转好几秒。

后来我把目光转向了静态博客生成器。所谓静态博客,简单说就是:你的文章在本地被编译成纯HTML、CSS和JavaScript文件,服务器只负责把这些文件发给访问者,不需要数据库查询,也不需要后端脚本实时渲染。这就好比一家餐厅,WordPress是现点现做,每来一个客人厨房就忙活一阵;而静态博客是提前把菜做好摆在保温柜里,客人来了直接端走。哪个更快、更省资源,一目了然。

在静态博客生成器这个圈子里,比较主流的有Hugo、Hexo、Jekyll这几个。我挨个试了一遍,最后选了Hugo,原因有三个:

  • 编译速度极快:Hugo是用Go语言写的,生成几百篇文章的站点通常只需要几百毫秒。Hexo基于Node.js,同样规模可能要好几秒甚至十几秒。这个差距在你频繁预览、反复调整主题的时候感受特别明显。
  • 单二进制文件,没有依赖地狱:Hugo就是一个可执行文件,下载下来就能用。不需要装Node.js、不需要装Ruby、不需要npm install一大堆包。这一点在云服务器上尤其重要,少一层依赖就少一堆麻烦。
  • 模板系统清晰:Hugo的模板语法虽然一开始需要适应,但它的目录结构和查找逻辑非常规范,搞懂了之后改主题、做定制都很顺手。

所以这篇文章的核心就是:在一台云服务器上,从零开始用Hugo搭建一个静态博客站点。我会把每一步的操作、每个选择的理由、以及我实际踩过的坑都写清楚。不管你是刚买了个云主机不知道怎么用,还是已经试过其他方案但不太满意,这篇内容应该都能帮到你。

注意:本文假设你有一台可以SSH登录的Linux云服务器(Ubuntu或Debian系),并且对基本的命令行操作不陌生。如果你连SSH都没用过,建议先花半小时了解一下Linux基础操作,后面的内容会顺畅很多。

2. 动手之前的准备工作:服务器和本地环境怎么配

2.1 云服务器的选择与初始配置

先说服务器。Hugo生成的静态站点对服务器配置要求极低,1核1G甚至512M内存的入门机型都绰绰有余。因为整个站点就是一堆静态文件,Nginx或者Caddy这样的Web服务器处理起来毫无压力。我目前用的是一台1核2G的入门级云主机,跑了好几个静态站点,CPU和内存几乎没怎么动过。

选好服务器之后,第一件事是做好基础安全配置。不管你用哪家的云服务,拿到服务器后的第一反应应该是:

  1. 更新系统包:apt update && apt upgrade -y,这一步别省,很多镜像自带的软件版本比较旧,可能存在已知问题。
  2. 创建一个非root用户:日常操作不要直接用root,创建一个普通用户并赋予sudo权限。这不是多此一举,而是最基本的安全习惯。
  3. 配置SSH密钥登录:如果你还在用密码登录SSH,强烈建议换成密钥对。密码登录容易被暴力尝试,密钥登录则安全得多。
  4. 设置防火墙:至少只开放80(HTTP)和443(HTTPS)端口,SSH端口可以改成非默认的,减少被扫描的概率。

这些步骤看起来跟Hugo没什么直接关系,但它们是整个站点稳定运行的基础。我见过太多人急着装软件、配环境,结果服务器被人扫出弱密码,站点还没上线就被塞了一堆乱七八糟的东西。

2.2 本地环境的搭建:Hugo的安装方式对比

Hugo的安装方式有好几种,我分别说一下适用场景:

安装方式适用系统优点缺点
包管理器安装macOS (brew)、Ubuntu (apt)一条命令搞定版本可能偏旧
下载二进制文件全平台版本可控,即下即用需要手动配置PATH
Go install有Go环境的机器版本最新需要Go环境
Docker全平台环境隔离,干净需要Docker,略重

我个人的建议是:在本地开发机器上用包管理器或者二进制文件安装,在云服务器上只装Nginx/Caddy用来托管生成好的静态文件。也就是说,Hugo本身不需要装在服务器上,你只需要在本地写好文章、生成好静态文件,然后上传到服务器就行了。

这个思路很重要,我再展开说一下。很多教程会让你在服务器上装Hugo,然后在服务器上直接生成站点。这样做不是不行,但有几个问题:

  • 服务器上装Hugo意味着你需要在服务器上维护文章源文件,编辑起来不如本地方便。
  • 每次写新文章都要SSH到服务器上操作,效率低。
  • 如果服务器出问题,你的文章源文件可能丢失(除非你做了额外备份)。

更好的做法是:本地写文章 → 本地用Hugo生成静态文件 → 把生成好的public目录同步到服务器。这样服务器上只有纯静态文件,没有任何源文件和构建工具,既安全又高效。

2.3 域名和DNS的提前准备

如果你打算绑定自己的域名,建议在开始搭建之前就把域名准备好,并且把DNS解析指向你的服务器IP。具体操作是:在你的域名注册商那里添加一条A记录,把域名(比如blog.example.com)指向服务器的公网IP。

DNS解析生效需要时间,通常几分钟到几小时不等。提前做好这一步,等站点搭好之后就能直接测试域名访问,不用干等着。

提示:如果你暂时没有域名,用服务器IP直接访问也可以。但正式对外发布的话,建议还是绑一个域名,一方面好记,另一方面后面配置HTTPS证书也需要域名。

3. 在服务器上搭建Web服务环境:Nginx的安装与配置

3.1 为什么选Nginx而不是Apache

静态文件托管这件事,Nginx和Apache都能做,但我更推荐Nginx,原因很实际:

  • 内存占用更低:Nginx采用事件驱动的异步架构,处理静态文件的效率极高,内存占用比Apache小很多。在低配服务器上这个优势很明显。
  • 配置更简洁:Nginx的配置文件结构清晰,一个站点一个配置文件,改起来不容易出错。
  • 社区资源丰富:遇到问题搜索解决方案时,Nginx相关的资料非常多。

当然,如果你已经熟悉Apache并且服务器配置足够,用Apache也完全没问题。工具是为人服务的,顺手最重要。

3.2 Nginx的安装与基础配置

在Ubuntu/Debian系统上安装Nginx很简单:

sudo apt update sudo apt install nginx -y

安装完成后,Nginx会自动启动。你可以用systemctl status nginx查看运行状态。如果看到active (running),说明Nginx已经在工作了。

接下来是配置站点。Nginx的站点配置文件通常放在/etc/nginx/sites-available/目录下,启用站点则是通过软链接到/etc/nginx/sites-enabled/。我来创建一个针对Hugo站点的配置:

server { listen 80; server_name blog.example.com; # 替换成你的域名或服务器IP root /var/www/blog/public; # 指向Hugo生成的public目录 index index.html; location / { try_files $uri $uri/ =404; } # 静态资源缓存设置 location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|webp)$ { expires 30d; add_header Cache-Control "public, no-transform"; } # 开启gzip压缩 gzip on; gzip_types text/plain text/css application/json application/javascript text/xml application/xml; gzip_min_length 1000; }

这个配置里几个关键点我解释一下:

  • root指向的是Hugo生成的public目录的绝对路径。后面我们会把生成好的文件放到这个位置。
  • try_files $uri $uri/ =404;是静态站点的标准配置,意思是先找对应的文件,找不到就找目录,再找不到就返回404。
  • 静态资源缓存设置让浏览器把CSS、JS、图片等缓存30天,减少重复请求,加快页面加载速度。
  • gzip压缩可以显著减小传输体积,对文本类文件效果尤其明显。

配置写好后,创建一个软链接启用站点:

sudo ln -s /etc/nginx/sites-available/blog /etc/nginx/sites-enabled/

然后测试配置有没有语法错误:

sudo nginx -t

如果输出syntax is ok和test is successful,就可以重载Nginx让配置生效:

sudo systemctl reload nginx

3.3 目录权限与文件结构规划

在服务器上,我建议把站点文件放在/var/www/下面,每个站点一个独立目录。比如:

/var/www/blog/ ├── public/ # Hugo生成的静态文件 └── releases/ # 历史版本备份(可选)

关于目录权限,有一个容易踩的坑:Nginx默认以www-data用户运行,如果你的站点文件权限设置不当,Nginx可能读不到文件,导致403 Forbidden错误。我的做法是:

sudo chown -R www-data:www-data /var/www/blog/public sudo chmod -R 755 /var/www/blog/public

这样既保证了Nginx能读取文件,又不会给过大的权限。

注意:不要图省事直接chmod -R 777,这是一个非常不好的习惯。正确的权限设置应该是:目录755,文件644,所有者是Web服务器用户。

4. 本地用Hugo生成站点并部署到云服务器

4.1 创建Hugo站点与目录结构解读

在本地机器上,先确认Hugo已经安装好:

hugo version

如果能看到版本号输出,说明安装成功。然后创建一个新站点:

hugo new site my-blog cd my-blog

创建完成后,你会看到这样的目录结构:

my-blog/ ├── archetypes/ # 新建文章时的模板 ├── content/ # 存放文章源文件(Markdown格式) ├── layouts/ # 自定义模板文件 ├── static/ # 静态资源(图片、CSS、JS等) ├── themes/ # 主题目录 └── config.toml # 站点配置文件

这个结构是Hugo的核心,我逐个解释一下它们的作用:

  • content/:你写的所有文章都放在这里,通常是Markdown文件。Hugo会根据目录结构自动生成对应的URL路径。
  • layouts/:存放模板文件。如果你用的是现成主题,一般不需要动这里。但如果要做定制,就需要了解Hugo的模板查找逻辑。
  • static/:这个目录下的文件会被原样复制到生成的站点根目录。图片、favicon、robots.txt等放在这里。
  • themes/:主题目录。Hugo的主题生态很丰富,后面我会推荐几个。
  • config.toml:站点的全局配置,包括站点标题、URL、语言、菜单等。

4.2 选一个合适的主题并完成基础配置

Hugo的主题库里有几百个免费主题,质量参差不齐。我挑主题的标准是:更新活跃、文档清晰、移动端适配好、不依赖太多外部服务。几个我实际用过觉得不错的:

  • PaperMod:简洁清爽,加载速度快,适合技术博客。
  • Stack:卡片式布局,颜值高,适合图文混排。
  • LoveIt:功能丰富,自带搜索、暗色模式等。

安装主题通常是把主题仓库克隆到themes/目录下:

git clone https://github.com/adityatelange/hugo-PaperMod themes/PaperMod

然后在config.toml中指定主题:

theme = "PaperMod" baseURL = "https://blog.example.com/" languageCode = "zh-cn" title = "我的博客"

PaperMod主题有一套自己的配置项,建议直接参考它的官方文档来配置。我在这里只强调几个容易忽略的点:

  • baseURL一定要写对,末尾的斜杠不能少。这个值会影响生成的链接地址,写错了会导致CSS、图片等资源加载失败。
  • 如果站点要部署在子目录下(比如example.com/blog/),需要在配置中设置canonifyURLs和relativeURLs,否则链接会出错。
  • 语言设置成zh-cn之后,主题中的一些界面文字会自动切换成中文(如果主题支持的话)。

4.3 写第一篇文章并本地预览

创建一篇新文章:

hugo new posts/my-first-post.md

这会在content/posts/下生成一个Markdown文件,开头有一段Front Matter(文章元数据):

--- title: "我的第一篇文章" date: 2024-01-15T10:00:00+08:00 draft: true ---

把draft: true改成false,或者删除这一行,文章才会被发布。然后在下面写正文内容,用Markdown语法就行。

本地预览用这个命令:

hugo server -D

-D参数表示包含草稿文章。启动后访问http://localhost:1313就能看到效果。Hugo自带热重载,你修改文章或配置后,浏览器会自动刷新,非常方便。

4.4 生成静态文件并同步到服务器

确认本地预览没问题后,就可以生成最终的静态文件了:

hugo --minify

--minify参数会压缩HTML、CSS、JS文件,减小体积。生成的文件都在public/目录下。

接下来把public/目录同步到服务器的/var/www/blog/public/。我常用的是rsync:

rsync -avz --delete public/ user@your-server-ip:/var/www/blog/public/

--delete参数的作用是:删除服务器上那些在本地已经不存在了的文件。这在更新站点时很有用,避免旧文件残留。

提示:第一次同步之前,确保服务器上的目标目录已经存在,并且权限设置正确。如果遇到权限问题,可以先同步到用户目录,再用sudo移动到目标位置。

同步完成后,在浏览器访问你的域名或服务器IP,应该就能看到博客站点了。

5. 部署过程中容易踩的坑和我的排查思路

5.1 页面样式丢失:从浏览器控制台找到根因

这是最常见的问题之一:页面能打开,但完全没有样式,看起来像纯文本。遇到这种情况,第一步是打开浏览器的开发者工具(F12),看Console面板有没有报错,Network面板有没有资源加载失败。

样式丢失通常有以下几个原因:

  • baseURL配置错误:如果baseURL写的是https://example.com但实际访问的是http://example.com,浏览器可能会因为混合内容或跨域问题拒绝加载资源。解决方法是确保baseURL和实际访问地址一致。
  • 文件路径问题:如果站点部署在子目录下,但配置中没有设置相对路径,生成的链接会指向错误的位置。
  • Nginx配置问题:如果Nginx的root指向了错误的目录,或者location规则拦截了静态资源请求,也会导致样式丢失。

我的排查顺序是:先看浏览器控制台的报错信息,确定是哪个文件加载失败;然后检查该文件的URL路径是否正确;最后检查Nginx配置和文件权限。

5.2 403 Forbidden:权限问题的完整排查链路

403错误说明Nginx找到了文件但无权读取。排查思路如下:

  1. 检查文件权限:ls -la /var/www/blog/public/看看文件的所有者和权限位。
  2. 检查目录权限:Nginx需要对每一级目录都有执行权限(x),否则无法进入目录读取文件。
  3. 检查Nginx运行用户:ps aux | grep nginx看看worker进程以哪个用户运行。
  4. 检查SELinux:如果你的系统开启了SELinux,可能需要额外配置安全上下文。不过大多数云服务器的默认镜像SELinux是关闭的。

我遇到过一次比较隐蔽的情况:/var/www/目录本身的权限是700,只有root能进入,导致Nginx无法访问下面的站点目录。解决办法是给/var/www/设置755权限。

5.3 更新站点后页面没变化:缓存问题的处理

有时候你明明同步了新文件,但浏览器访问还是旧内容。这通常是缓存导致的,可能来自两个层面:

  • 浏览器缓存:强制刷新(Ctrl+Shift+R)或者用无痕窗口测试。
  • CDN缓存:如果你用了CDN服务,需要在CDN控制台刷新缓存。

另外,Nginx配置中的expires指令也会影响缓存行为。如果你在调试阶段,可以临时把缓存时间设短一些,避免频繁手动刷新。

5.4 HTTPS证书配置:Let's Encrypt的自动化方案

站点跑通之后,下一步就是配置HTTPS。我用的是Let's Encrypt的免费证书,配合Certbot工具可以自动申请和续期:

sudo apt install certbot python3-certbot-nginx -y sudo certbot --nginx -d blog.example.com

Certbot会自动修改Nginx配置,添加SSL相关设置,并设置定时任务自动续期。整个过程基本不需要手动干预。

注意:申请证书之前,确保域名已经正确解析到服务器IP,并且80端口可以正常访问。否则验证会失败。

6. 后续可以继续优化的几个方向

站点搭起来只是第一步,后面还有很多可以打磨的地方。我分享几个我实际做过并且觉得值得投入时间的优化方向。

图片处理和优化。静态博客的图片如果直接上传原图,页面加载会很慢。我现在的做法是:用工具把图片压缩成WebP格式,然后在Markdown中引用。Hugo本身也支持图片处理短代码,可以在生成时自动裁剪和压缩。

自动化部署流程。每次手动rsync虽然不麻烦,但时间长了也烦。可以写一个简单的Shell脚本,把生成和同步两步合并成一条命令。更进一步的话,可以用GitHub Actions之类的CI工具,实现推送代码后自动构建和部署。

站点搜索功能。静态站点没有后端,但可以用客户端搜索方案,比如基于JSON索引的搜索。Hugo有相关的插件和主题支持,配置好之后用户体验会好很多。

评论系统。静态博客本身不支持评论,但可以接入第三方的评论服务。选择的时候注意考虑加载速度、隐私政策和长期可用性。

站点地图和SEO。Hugo可以自动生成sitemap.xml,提交给搜索引擎可以加快收录。另外,合理设置每篇文章的title、description和关键词,对搜索排名也有帮助。

我在实际使用中最大的体会是:不要一开始就追求完美。先把站点跑起来,能写文章、能访问,然后再逐步优化。我见过不少人花了好几天折腾主题和配置,结果一篇文章都没写。内容才是博客的核心,技术只是载体。先把写作流程跑通,其他的慢慢来。

最后分享一个小技巧:Hugo的config.toml支持环境变量和配置目录分离,你可以把敏感信息(比如某些第三方服务的API Key)放在单独的文件中,不纳入版本控制。这样即使配置文件公开分享,也不会泄露私密信息。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询