利用Hugo in Docker快速建自己的个人博客
在Docker容器中快速运行Hugo,配合nginx一行代码都不用写。
Hugo的介绍网上很多,不再赘述,只需关注其核心——把原生md文件转换为html,在不关注前端细节的情况下完成静态网页的搭建。
推荐搭建在Docker里是部署和转移特别方便,完全不用记住需要安装哪些前置包,版本是否一致,不同操作系统是否有不同差异,特别是经常变更云服务器的情况下,卷数据打包好scp到新机子上,一个解压,一个docker run命令两行搞定。吐槽一下国内好多云服务器首年优惠只要几十,第二年续期直接变成大几百甚至上千,这个情况下就能体会到这套体系有多方便了。
理解端口映射和卷挂载
先看这条启动命令:
docker run -it --name hugo --entrypoint "" -p 7913:1313 -v "/home/docker_hugo:/src" klakegg/hugo:0.111.0-ext /bin/bash
其实就两个关键点:
-v "/home/docker_hugo:/src" 把宿主机的/home/docker_hugo目录映射到容器内的/src。这样做的好处是所有文件操作都可以在宿主机完成,用你习惯的编辑器写文章,改配置,容器里实时生效。不需要在容器内用vi这种原始工具折腾。-p 7913:1313 把容器的1313端口暴露到宿主机的7913端口。Hugo默认跑在1313端口,但为了避免和其他服务冲突,映射到7913。访问http://localhost:7913就能看到你的博客效果。这种设计让开发体验很舒服:宿主机负责编辑,容器负责运行,各司其职。
快速启动流程
实际操作确实用不了几分钟:
在宿主机上执行:
mkdir -p /home/docker_hugo
cd /home/docker_hugo
启动容器:
docker run -it --name hugo --entrypoint "" -p 7913:1313 -v "/home/docker_hugo:/src" klakegg/hugo:0.111.0-ext /bin/bash
进入容器后初始化Hugo站点:
cd /src
hugo new site . --force
--force参数允许在非空目录创建站点,避免一些权限或目录冲突问题。
继续在容器内操作:
git init
git submodule add https://github.com/theNewDynamic/gohugo-theme-ananke.git themes/ananke
这里用的是Ananke主题,算是Hugo官方推荐的入门主题,简洁实用。如果网络不好,可以换成国内能访问的主题仓库。
这步建议在宿主机操作,用你熟悉的编辑器。编辑/home/docker_hugo/config.toml:
baseURL = 'http://localhost:7913/'
languageCode = 'zh-cn'
title = '我的第一个Hugo站'
theme = 'ananke'
[params]
description = '测试站点'
注意baseURL要和端口映射保持一致,不然静态资源路径会出问题。
回到容器内:
hugo new posts/hello-world.md
Hugo会在content/posts/目录下生成一个带有Front Matter的markdown文件。默认draft: true,记得改成false才能在正式环境显示。
这是最关键的一步,在容器内执行:
hugo server --bind=0.0.0.0 --port=1313 --buildDrafts
--bind=0.0.0.0很重要,默认Hugo只监听localhost,这样容器外访问不到。加上这个参数才能让宿主机通过端口映射访问。
http://localhost:7913,应该能看到你的博客首页了。如果看不到文章,检查一下markdown文件的draft字段是不是改成false了。日常开发工作流
搞定初始化后,以后的工作流程更简单。
如果容器停了,重新启动:
docker start -ai hugo
-ai参数会附加到容器的交互式终端,直接进入bash环境。
在宿主机用VS Code、Sublime或任何你喜欢的编辑器打开/home/docker_hugo目录。修改文章、调整配置、添加图片,都在宿主机完成。保存后容器内立即生效,这就是卷挂载的优势。
比如编辑/home/docker_hugo/content/posts/hello-world.md:
---
title: "Hello World"
date: 2025-10-20T23:00:16+08:00
draft: false
---
这是我的第一篇博客文章。
## 小标题
随便写点什么,Markdown语法都支持。
在容器内启动服务器,加上--watch参数:
hugo server --bind=0.0.0.0 --port=1313 --buildDrafts --watch
这样每次保存文件,Hugo会自动重新构建,浏览器刷新就能看到最新效果。有些主题支持LiveReload,甚至不用手动刷新。
Hugo文章的元信息写在文件开头的Front Matter里。最简单的配置就这几项:
---
title: "文章标题"
date: 2025-10-20T23:00:16+08:00
draft: false
tags: ["标签1", "标签2"]
categories: ["分类"]
---
draft: false表示正式发布,draft: true是草稿状态。开发时用--buildDrafts参数可以预览草稿,生产构建时草稿会被忽略。
构建与部署
写完文章后,需要生成静态文件部署到服务器。
在容器内执行:
hugo --minify
--minify会压缩HTML、CSS、JS文件,减少体积。生成的文件在/home/docker_hugo/public/目录,这就是最终的静态网站。
把public目录的内容上传到任何Web服务器都行。用Nginx的话,配置超简单:
server {
listen 80;
server_name yourdomain.com;
root /path/to/public;
index index.html;
}
或者更docker化的方式,在宿主机直接操作:
docker exec hugo hugo --minify
然后把/home/docker_hugo/public目录复制到你的服务器。
hugo --minify,然后用rsync或scp把public目录传到服务器。常见问题排查
首先检查容器是否在运行:
docker ps
如果没看到hugo容器,说明挂了或者没启动。然后检查hugo server命令是否执行成功,有没有报错信息。
hugo server启动时带了--watch参数。另外检查文件是否真的保存了,有些编辑器需要手动保存或设置自动保存。最常见的问题是config.toml里的theme名称写错了。主题名称必须和themes/目录下的文件夹名完全一致,大小写也要对。
另外检查主题目录是否真的存在:
ls /home/docker_hugo/themes/
如果是空的,说明git submodule没添加成功,可能是网络问题。
在宿主机删除旧主题:
rm -rf /home/docker_hugo/themes/ananke
在容器内添加新主题:
cd /src
git submodule add https://github.com/xxx/new-theme.git themes/new-theme
修改config.toml中的theme字段为新主题名称,重启hugo server就行。
快速启动
为了进一步简化操作,可以写个启动脚本。其实常用命令就两个,hugo server测试一下,然后hugo完成构建。
可以在宿主机创建/home/docker_hugo/start.sh:
#!/bin/bash
docker exec -it hugo /bin/bash hugo
也可以在容器内创建/src/run.sh:
#!/bin/bash
cd /src
hugo server --bind=0.0.0.0 --port=1313 --buildDrafts --watch
根据喜好怎么放都行,hugo本身的记忆点不多,命令也很简单,开发确实很方便。
总结
用Docker跑Hugo的好处是环境隔离,不会污染宿主机。配合卷挂载和端口映射,开发体验和本地运行几乎没区别。整个流程下来,从零到看到博客效果,确实只需要几分钟。
后续如果要折腾主题定制、SEO优化、评论系统这些,都可以在这个基础上慢慢扩展。Hugo的静态站点生成速度很快,几百篇文章也就几秒钟,这点比WordPress之类的动态博客强太多了。