在gitlab上部署hugo网页服务并自动发布

环境介绍

Hugo

Hugo 是一个用 Go 语言编写的静态站点生成器,它针对速度、易用性和可配置性进行了优化,快速灵活,主题也多,个人使用下来感觉安装部署和配置都很方便

Gitlab Pages

Gitlab Pages 是gitlab提供的一个静态站点托管服务,可以直接将个人、组织或项目的页面托管于上面。本人的gitlab是以docker形式部署在我的unraid上面, docker启动时挂载了一个pages目录用于存放静态html页面,由于gitlab自带nginx服务,所以可以将hugo生成的静态页面直接部署在上面。 下面是我的gitlab docker挂载的目录

/mnt/user/appdata/gitlab-ce/config:/etc/gitlab    # 用于存放gitlab 的配置文件
/mnt/user/appdata/gitlab-ce/data:/var/opt/gitlab  # 用于存放gitlab内部服务的一些数据,pages静态页面和nginx服务配置就在这里面
/mnt/user/appdata/gitlab-ce/log:/var/log/gitlab   # 日志文件

安装Hugo并建站

安装

建议参考 官方文档 进行安装。本人使用的是manjaro系统,直接在系统自带的软件商店里就有,其他linux发行版也可以尝试系统自带软件商店看看。安装完成后在终端执行 hugo version 进行验证是否安装正确

建站

通过hugo命令可以快速生成我们的网站,进入一个你喜欢的目录执行下面的命令

hugo new website your_website_name

这样就新建了一个站点项目。此时站点还无法启动,需要安装主题,本站主题使用的是 Hugo Next , 参考主题安装文档进行安装。安装好后主题后在项目根目录下执行 hugo server -D 命令启动服务,顺利的话应该能看到类似下面的输出

Start building sites  
hugo v0.111.3+extended linux/amd64 BuildDate=unknown
WARN 2023/03/26 21:25:27 Value `experiences` for `widget.handler` in homepage/intro.md is deprecated and will be removed in Eureka v1.0.0. Please use `experience` instead.

                   | ZH  
-------------------+-----
  Pages            | 18  
  Paginator pages  |  0  
  Non-page files   |  0  
  Static files     |  1  
  Processed images | 10  
  Aliases          |  2  
  Sitemaps         |  1  
  Cleaned          |  0  

Built in 125 ms
Watching for changes in /home/admin/workspace/hugo/{content,static}
Watching for changes in /tmp/hugo_cache/modules/filecache/modules/pkg/mod/wangchucheng.com/hugo-eureka@v0.9.3/_vendor/github.com/FortAwesome/Font-Awesome/js-packages/@fortawesome/{fontawesome-svg-core,free-brands-svg-icons,free-regular-svg-icons,free-solid-svg-icons}
Watching for config changes in /home/admin/workspace/hugo/config/_default, /home/admin/workspace/hugo/go.mod
Environment: "development"
Serving pages from memory
Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender
Web Server is available at //localhost:1313/ (bind address 127.0.0.1)
Press Ctrl+C to stop

访问 localhost:1313 就能预览我们的网站了

生成静态页面

在项目根目录下执行hugo命令,该命令会生成public目录,里面是渲染好的html页面。

自动部署和发布

将项目上传到gitlab上,利用gitlab-runner和CI/CD可以做到项目修改提交和push到gitlab后自动生成静态页面并发布。

编写自动部署脚本

gitlab借助gitlab-runner和部署脚本实现自动化部署。在项目根目录下新建 .gitlab-ci.yml 文件,文件内容如下

pages:
  script:
    - hugo
    - mkdir -p /home/gitlab-runner/pages/hugo
    - rm -rf /home/gitlab-runner/pages/hugo/*
    - cp -r public /home/gitlab-runner/pages/hugo
  artifacts:
    paths:
      - public
  tags:
    - hugo
  only:
    - master

这个脚本的含义是项目改动push到master分支后将会触发自动部署,git-runner服务从gitlab拉取到最新的master分支代码,然后执行hugo命令, 前面我们知道这个命令会成静态html页面到public文件夹下。生成完静态页面后删除之前的页面,将新的静态页面拷贝到容器的 /home/gitlab-runner/pages/hugo/public目录下, 这个目录对应宿主机的 /mnt/user/appdata/gitlab-ce/data/gitlab-pages/hugo/public目录,对应gitlab容器的 /var/opt/gitlab/gitlab-pages/hugo/public目录,所以gitlab的nginx服务可以访问到这些静态页面,从而实现了自动部署。

构建支持hugo命令的gitlab-runner镜像

我的gitlab-runner服务是通过docker部署的,官方的gitlab-runner镜像没有安装hugo服务,所以需要手动构建镜像来加入对hugo的支持。新建一个文件夹,下载 hugo extended可执行文件 到文件夹,下载下来的 是一个压缩包,解压缩出来的文件就是hugo可执行文件,默认似乎没有可执行权限,执行 chmod a+x hugo 以使文件可执行。编写Dockerfile文件,内容如下:

FROM gitlab/gitlab-runner:v15.4.2
COPY hugo /usr/bin/hugo

gitlab-runner镜像版本选择和你gitlab一样或者接近的。执行

docker build -t hugo/gitlab-runner . 

编译镜像。执行

docker run
  -d
  --name='hugo-runner'
  --net='host'
  -v '/mnt/user/appdata/gitlab-ce/data/gitlab-pages/':'/home/gitlab-runner/pages/':'rw'
  -v '/mnt/user/appdata/gitlab-runner/':'/etc/gitlab-runner':'rw' 'hugo/gitlab-runner'

宿主机挂载目录可以根据实际情况换成你自己喜欢的,挂载的第一目录用于存放渲染好的静态页面,这个目录和gitlab挂载的存放静态页面的目录在宿主机上是同一个, 所以gitlab-runner这边生成好静态页面后gitlab服务也能够访问,注意gitlab-runner执行任务时是以gitlab-runner用户执行的, 所以可能会存在对挂载的目录没有权限问题,如果出现了没有权限,则进入docker的shell控制台里面执行chown命令将目录所有者改为gitlab-runner这个用户即可。 第二个目录存放的是gitlab-runner的配置文件config.toml。这样gitlab-runner服务就部署好了,接着需要将这个gitlab-runner服务注册到gitlab上面

注册gitlab-runner

通过docker exec 命令进入容器,执行gitlab-runner register 命令,依次填入gitlab服务的访问地址、token、tags。这里的token填项目专用的token,可以在 项目的 Settings > CI/CD > Runners里找到token,然后填入,填写tags时需要和自动部署脚本文件(.gitlab-ci.yml)里面的tags一致, 选择executor时选shell。注册成功后应该能在项目的Settings > CI/CD > Runners里看到。至此,以后只要修改了项目文件并推送到master分支, gitlab-runner就会自动生成静态html页面并将这些文件拷贝到/mnt/user/appdata/gitlab-ce/data/gitlab-pages/hugo/public目录 (对应gitlab容器内部的/var/opt/gitlab/gitlab-pages/hugo/public目录)下

修改gitlab nginx配置

在宿主机的/mnt/user/appdata/gitlab-ce/data/nginx/conf/目录下(对应容器的/var/opt/gitlab/nginx/conf/目录)新建hugo.conf文件,内容如下

server {
  listen *:80;
  server_name  pages.starcloud.cc; #改成你自己的域名
  server_tokens off; ## Don't show the nginx version number, a security best practice
  access_log  /var/log/gitlab/nginx/gitlab_pages_hugo_access.log gitlab_access;
  error_log   /var/log/gitlab/nginx/gitlab_pages_hugo_error.log error;
  root /var/opt/gitlab/gitlab-pages/hugo/public;
  location / {
  }
  error_page 404 /404.html;
}

修改同目录的nginx.conf文件,在最后加上 include /var/opt/gitlab/nginx/conf/hugo.conf;在gitlab docker容器中执行gitlab-ctl restart nginx重启nginx服务,现在访问 pages.starcloud.cc应该就能看到部署好的页面了。