Close-up of hand writing in notebook using a blue pen, focus on creativity.

使用 Travis CI 持续集成部署 Hugo 项目到云主机

前言

最近刚开始写博客,也没有买云主机,使用的主题有现成的netlify配置文件,支持一键部署到 netlify 上,只需将博客 hugo 项目提交到github 上就可以根据配置的分支进行自动部署,使用上来说也是很方便。虽说 netlify 有全球 cdn 加速,但在国内访问的话速度感觉一般般 (其实日常访问也还凑合,个人博客刚开始也没啥内容影响也不大,应该是我自己搭博客不是用来写的,就想拿来折腾折腾),于是趁着腾讯云搞活动就整了个服务器来玩玩。

在腾讯云CVM 上部署的时候,最初没有想到用 CI 部署,博客也没几篇,采用的方案是本地 hugo 生成 public 前端页面,将 public 目录直接和 markdown 博客文件一块推送到GitHub 上,再远程登录服务器 git pull,又是但是腾讯云主机访问 GitHub 的速度太慢了,简单的拉个代码就得好一会,还有就是把 public 目录提交上去的 git 提交记录会显得非常凌乱,部署方式也比较麻烦。还是持续集成方便。


部署流程

hugo 项目的目前是有现成的持续集成 GitHub Page 上,主机部署的话就需要自己摸索下了,之前刷博客的时候刚好了解到有 travis CI 持续集成方案,就开始了尝试。这块就记录一下踩坑过程,防止以后又给忘了。

我的想法是在向GitHub上提交代码时,ci 自动生成 public 目录,然后 scp 到服务器上就行。

首先在 travis-ci 上创建账号新建 ci 任务,就是配置一些 GitHub 仓库,分支等信息,当项目仓库发生变化时 ci 任务能够感知到进行部署,相对简单就不做赘述了。

在博客项目根目录新增 travis-ci 文件 .travis.yml,配置信息作用看注释即可很好理解,部署也是调试的过程,先看看 hugo public 前端页面能不能正确生成,之后再调试 scp ci 逻辑。配置信息,具体配置如下:

dist: xenial
os: linux
language: go
go:
  - "1.15" # 指定Golang version
# Specify which branches to build using a safelist
# 分支白名单限制:只有 master 分支的提交才会触发构建
branches:
  only:
    - master
install:
  # 安装指定版本的hugo
  - wget "https://github.com/gohugoio/hugo/releases/download/v0.81.0/hugo_extended_0.81.0_Linux-64bit.deb"
  - sudo dpkg -i hugo*.deb
script:
  # 运行hugo命令
  - hugo version
  - hugo --gc --minify

这块特别说明我使用的 hugo 博客主题 wowchemy-hugo-modules 采用的是 hugo module 进行主题文件获取和升级,直接命令 hugo 就可以生成 public前端页面(hugo 通过 go.mod 会自动来取主题文件)。像其他一些主题可能使用的是 git submodule 来管理主题,ci 配置文件可能稍有变化。

提交对应分支后到 travis-ci 网站上查看 是否感知到分支变化,有无对应的 build job 正在运行。查看 job log ,发现 build 正常运行,能够正常生成前端页面。

最后一步 scp public 目录到服务器即可,我先进行了本地 hugo 生成 public, scp 到服务器,这样等调试成功之后再编写 ci 配置文件,避免调试一次就 git push 一下耽误时间。

scp  -i ~/Documents/server_pravite.pem -v -r  ./public server_user_name@server_ip:/public_dir/

这块的报了一个错误,去服务端查看了目录权限,目录是我用 root 创建的,scp 的时候使用 另一个账号上传导致,修改下目录所属组就行。

sudo chown -R user:user your_deploy_dir

scp 的话使用的私钥 (密钥使用 ssh-keygen 命令生成,服务器 本地生成都可以,把生成的公钥文件追加到服务器 .ssh/authorized_keys就行,远程生成的私钥文件下载下来需要 chmod 修改下文件权限 )上传,调试了几次上传发现一个问题,scp 命令只会覆盖更新服务器本地相同文件,对于服务器有 本地没有的文件不会做删除操作,目录可能是不同步的,服务器上的文件可能会有越来越多没用的文件,看来 scp 这个办法行不通。

文件同步的除了 scp 还有 rsync ,看了对应文档果然有一个 --delete参数来删除服务端多余文件,这样就可以保证每次新生成的 public 和 服务器上的目录文件是一致的。调试没问题之后在 .travis.yml 文件新增配置:

deploy:
  provider: script
  skip_cleanup: true
  script: rsync -av --delete -P -e "ssh -i  ./server_pravite.pem" ./public your_server_name@your_server_ip:/public_dir
  on:
    branch: master

由于我的博客项目是私有项目,就直接把私钥放在项目根目录了,如果是公开项目的话可不敢这么干。最后提交验证。

这里卡住需要手动确认一下,持续集成就是不需要人工接入,这肯定是不行的。是不是可以把人工接入步骤也可以通过命令提前确认好?其实这块出现的问题和服务器刚下载下来私钥使用是一样需要修改权限,具体解决可见参考文章。

before_script:
  - chmod 600 server_pravite.pem
  - ssh-add server_pravite.pem
  - echo -e "Host server_ip\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config

再上传代码,ci 运行成功,去服务器查看 public 前端页面文件也都 ok,最后再把 .travis.yml 文件整理一下。

dist: xenial
os: linux
language: go
go:
  - "1.15" # 指定Golang version
# Specify which branches to build using a safelist
# 分支白名单限制:只有 master 分支的提交才会触发构建
branches:
  only:
    - master
install:
  # 安装最新的hugo
  - wget "https://github.com/gohugoio/hugo/releases/download/v${HUGO_RELEASE}/hugo_extended_${HUGO_RELEASE}_Linux-64bit.deb"
  - sudo dpkg -i hugo*.deb
script:
  # 运行hugo命令
  - hugo version
  - hugo --gc --minify
env:
  global:
    - PRODUCTION=true
    - HUGO_RELEASE=0.81.0
    - DEPLOY_USER=ubuntu
    - DEPLOY_HOST=your_server_ip
    - DEPLOY_DIRECTORY=/your_server_deploy_dir
    - PEM_DER=your_server_privite_key
deploy:
  provider: script
  skip_cleanup: true
  script: rsync -av --delete -P -e "ssh -i  ${PEM_DER}" ./public ${DEPLOY_USER}@${DEPLOY_HOST}:${DEPLOY_DIRECTORY}
  on:
    branch: master
before_script:
  - chmod 600 ${PEM_DER}
  - ssh-add ${PEM_DER}
  - echo -e "Host ${DEPLOY_HOST}\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config

小结一下

部署测试过程中,最多的问题就是各种权限问题,还有一点不好的是私钥文件直接放在项目代码中,私钥文件是可以配置 travis ci 控制台的,然后直接通过变量获取,这块后续再优化完善下。

参考文章:

1人评论了“使用 Travis CI 持续集成部署 Hugo 项目到云主机”

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注