前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何使用Ubuntu 14.04上的Git Hooks将Hugo站点部署到生产环境

如何使用Ubuntu 14.04上的Git Hooks将Hugo站点部署到生产环境

原创
作者头像
朝朝
修改2018-09-26 17:16:02
2K0
修改2018-09-26 17:16:02
举报

介绍

Hugo是一个静态站点生成器,允许您通过使用简单的标记语言轻松创建和发布Web内容。Hugo可以根据提供的要求解析您的内容并应用主题,以生成可以轻松托管在任何Web服务器或主机上的一致网页。

在本指南中,我们将向您展示如何设置一个系统git,您可以使用该系统将新内容自动部署到生产Web服务器。

准备

对于本指南,我们假设您已经启动并运行了Ubuntu 14.04计算机作为您的开发计算机。(一台已经设置好可以使用sudo命令的非root账号的Ubuntu服务器,并且已开启防火墙。没有服务器的同学可以在这里购买,不过我个人更推荐您使用免费的腾讯云开发者实验室进行试验,学会安装后再购买服务器。)

我们将建立第二台 Ubuntu 14.04服务器来为我们的实际生产网站服务。在此服务器上,确保已创建具有sudo权限的非root用户。

准备开发服务器

我们将从我们的开发服务器(通过之前的Hugo指南设置的服务器)开始。使用您上次使用的相同非root帐户登录该服务器。

我们需要在此服务器上执行一些操作以设置一步式部署。我们要:

  • 配置对我们的生产服务器的SSH密钥访问
  • 将初始git存储库传输到生产服务器
  • 将生产服务器作为git远程添加到我们的站点存储库中

让我们开始吧。

配置对生产服务器的SSH密钥访问

我们要做的第一件事是在两台服务器之间配置SSH密钥访问。这将允许我们部署而无需每次都输入密码。如果要在每个部署中提示输入密码,可以跳过此步骤。有些人喜欢在部署过程中保持密码提示,这是在推送内容之前重新考虑的一个小机会。

首先,检查您是否已在开发服务器上的帐户中配置了SSH密钥对:

代码语言:javascript
复制
ls ~/.ssh/id_rsa

如果您返回如下所示的行,则尚未配置SSH密钥对:

代码语言:javascript
复制
ls: cannot access /home/demouser/.ssh/id_rsa: No such file or directory

您可以键入以下内容来创建缺少的密钥对:

代码语言:javascript
复制
ssh-keygen

在所有提示中按ENTER键以创建无密码密钥。

另一方面,如果该ls命令为您提供了如下所示的行,则您的帐户中已有一个密钥:

代码语言:javascript
复制
/home/demouser/.ssh/id_rsa

获得密钥对后,可以通过键入密钥将公钥传输到生产服务器。在命令中,在本指南的先决条件阶段替换您在生产服务器上配置的非root帐户名称:

代码语言:javascript
复制
ssh-copy-id username@production_domain_or_IP

如果这是您第一次在这两台计算机之间使用SSH,则会要求您键入“是”来确认连接。之后,系统将提示您输入生产服务器的用户密码。您的公钥将被传输到生产服务器,允许您下次无需密码登录。

通过使用以下ssh命令询问生产服务器的主机名来测试此功能:

代码语言:javascript
复制
ssh username@production_domain_or_IP cat /etc/hostname

这次不应该提示您输入密码。您应该收到生产服务器的主机名:

代码语言:javascript
复制
prodserver

将Initial Git Repo传输到Production Server

接下来,我们需要将Hugo仓库的初始克隆转移到我们的生产服务器。我们将需要这个以便post-receive稍后在生产服务器上设置一个钩子。为了实现这一点,我们需要创建一个gitrepo 的“裸”克隆并将其复制到我们的其他服务器。

裸存储库是一个git没有工作目录的特殊存储库。在传统的gitrepos中,项目文件保存在主目录中,git版本控制数据保存在被调用的隐藏目录中.git。裸仓库没有项目文件的工作目录,因此通常保存在隐藏.git文件夹中的文件和目录位于主文件夹中。Bare repos通常用于远程服务器,因为它简化了推送内容的过程。

我们将从/tmp目录中的主Hugo存储库创建一个裸仓库。裸回购通常由尾随.git后缀标识。要创建此副本,我们将使用git clone带有以下--bare选项的命令:

代码语言:javascript
复制
git clone --bare ~/my-website /tmp/my-website.git

我们可以将这个裸存储库传输到我们的生产服务器scp。确保在命令末尾包含尾部“:”,以便将repo放置在远程系统上用户的主目录中。

代码语言:javascript
复制
scp -r /tmp/my-website.git username@production_domain_or_IP:

为Production Server添加Git Remote

现在我们git在生产服务器上有了我们的裸仓库,我们可以将生产服务器添加为跟踪的远程仓库。这将允许我们轻松地将新内容推送到我们的生产服务器。

回到你的Hugo目录:

代码语言:javascript
复制
cd ~/my-website

我们需要做的就是决定遥控器的名称。在本指南中,我们将使用prod。然后,我们可以在远程系统上指定裸存储库的连接信息和位置:

代码语言:javascript
复制
git remote add prod username@production_domain_or_IP:my-website.git

在我们的生产服务器上安装git之前,您将无法测试此远程链接。

设置生产服务器

现在我们的开发机器已完全配置,我们可以继续设置我们的生产系统。

在我们的生产系统中,我们需要完成以下步骤:

  • 安装gitnginxpygments
  • 安装Hugo和Hugo主题
  • 配置nginx为从主目录中的位置提供文件
  • 创建post-receive脚本以部署推送到我们的存储库的新内容

在Production Server上安装Git,Pygments和Nginx

我们应该做的第一件事就是安装gitpygmentsnginx到服务器上。虽然我们的项目存储库已经在我们的服务器上,但我们需要该git软件来接收推送并执行我们的部署脚本。我们需要pygments为任何代码块应用服务器端语法高亮。我们将使用nginxWeb服务器,使访问者可以访问我们的内容。

更新本地包指数和安装git,并nginx从Ubuntu的默认存储库。我们需要安装pipPython包管理器来获取pygments

代码语言:javascript
复制
sudo apt-get update
sudo apt-get install git nginx python-pip

然后我们可以pip用来安装pygments

代码语言:javascript
复制
sudo pip install Pygments

下载完成后,我们可以测试我们是否在开发计算机上正确设置了远程存储库。在您的开发计算机上,进入Hugo项目目录并使用以下git ls-remote命令:

代码语言:javascript
复制
cd ~/my-website
git ls-remote prod

如果git可以在开发和生产机器上的存储库之间建立连接,它将显示refs列表,如下所示:

代码语言:javascript
复制
103902f5d448cf57425bd6830e544128d9522c51    HEAD
103902f5d448cf57425bd6830e544128d9522c51    refs/heads/master

在Production Server上安装Hugo

回到我们的生产服务器,我们需要安装Hugo。我们将在生产服务器之后构建静态资产,而不是在我们的开发服务器上构建我们的内容git push。要做到这一点,我们需要安装Hugo。

我们可以使用与开发机器相同的方法安装Hugo。首先检查生产服务器的体系结构:

代码语言:javascript
复制
uname -i

接下来,访问Hugo发布页面。向下滚动到最新Hugo版本的“下载”部分。右键单击与您的体系结构对应的链接:

  • 如果该uname -i命令生成了x86_64,请右键单击并复制以该amd64.deb结尾的链接
  • 如果该uname -i命令生成了i686,请右键单击并复制以该i386.deb结尾的链接

在生产服务器上,进入您的主目录并使用wget下载您复制的链接:

代码语言:javascript
复制
cd ~
wget https://github.com/spf13/hugo/releases/download/v0.14/hugo_0.14_amd64.deb

下载完成后,您可以通过键入以下内容来安装软件包:

代码语言:javascript
复制
sudo dpkg -i hugo*.deb

通过要求Hugo显示其版本号来测试安装是否成功:

代码语言:javascript
复制
hugo version

您应该看到显示的版本行,表明Hugo现在可用:

代码语言:javascript
复制
Hugo Static Site Generator v0.14 BuildDate: 2015-05-25T21:29:16-04:00

在我们继续之前,我们需要将Hugo主题克隆到我们的生产服务器:

代码语言:javascript
复制
git clone --recursive https://github.com/spf13/hugoThemes ~/themes

配置Nginx以服务部署期间生成的文件

接下来,我们需要稍微修改我们的Nginx配置。

为了简化部署,不是将生成的内容放在var/www/html目录中,而是将内容放在public_html用户主目录中调用的目录中。

让我们继续创建public_html目录:

代码语言:javascript
复制
mkdir ~/public_html

接下来,让我们打开默认的Nginx服务器块配置文件进行必要的调整:

代码语言:javascript
复制
sudo nano /etc/nginx/sites-available/default

我们需要更改的唯一选项是server_name,应指向生产服务器的域名或IP地址以及root指令,该指令应指向我们刚刚创建的public_html目录:

代码语言:javascript
复制
server {
        listen 80 default_server;
        listen [::]:80 default_server ipv6only=on;
​
        root /home/username/public_html;
        index index.html index.htm;
​
        # Make site accessible from http://localhost/
        server_name server_domain_or_IP;
​
. . .

确保将root指令中的“username”替换为生产服务器上的实际用户名。完成后保存并关闭文件。

重新启动Nginx服务器以应用您的更改:

代码语言:javascript
复制
sudo service nginx restart

我们的Web服务器现在可以为我们放入public_html目录的文件提供服务。

创建一个Post-Receive Hook来部署Hugo站点

现在,我们终于准备好创建我们的post-receive部署钩子脚本了。每当您将新内容推送到生产代码时,都会调用此脚本。

要创建此脚本,我们将在生产服务器上的裸存储库中进入名为hooks的目录。立即进入该目录:

代码语言:javascript
复制
cd ~/my-website.git/hooks

这个目录有很多示例脚本,但我们需要一个post-receive本指南的脚本。在hooks目录中创建并打开具有此名称的文件:

代码语言:javascript
复制
nano post-receive

在文件的顶部,在指出这是一个bash脚本之后,我们将从定义一些变量开始。我们将设置GIT_REPO为裸存储库。我们将把它克隆到WORKING_DIRECTORY变量指定的临时存储库,以便Hugo可以访问其中的内容来构建实际的站点。因为我们的gitrepo中的themes目录实际上只是指向父目录中某个位置的符号链接,所以我们需要确保工作目录克隆在与我们下载的Hugo主题相同的位置创建。

公共Web文件夹将由PUBLIC_WWW变量指定,备份Web文件夹将通过BACKUP_WWW变量保持可访问。最后,我们将设置MY_DOMAIN为服务器的域名或公共IP地址:

考虑到这一点,文件的开头应如下所示:

代码语言:javascript
复制
#!/bin/bash
​
GIT_REPO=$HOME/my-website.git
WORKING_DIRECTORY=$HOME/my-website-working
PUBLIC_WWW=$HOME/public_html
BACKUP_WWW=$HOME/backup_html
MY_DOMAIN=server_domain_or_IP

设置变量后,我们可以从脚本的逻辑开始。首先,我们将使用bash的set -e命令指定脚本在遇到任何错误时应立即退出。我们将在瞬间出现问题时使用它来清理。

之后,让我们确保为我们的部署设置了环境。我们想要删除任何现有的工作目录,因为我们希望在部署期间克隆新的副本。我们还想备份我们的web目录,以便我们可以在出现任何问题时进行恢复。我们在这里使用rsync是因为它处理空目录和目录,其中的内容比cp一致。确保在$PUBLIC_WWW后面包含尾部/,以便正确解析caommand。

我们要做的最后一个设置过程是设置trap命令,以便在收到“退出”信号时进行响应。由于我们包含了该set -e命令,因此只要我们的部署中的命令失败,就会发生退出信号。在这种情况下,陷阱指定的命令会将我们的备份副本还原到Web目录并删除工作git目录的任何实例。

代码语言:javascript
复制
#!/bin/bash
​
GIT_REPO=$HOME/my-website.git
WORKING_DIRECTORY=$HOME/my-website-working
PUBLIC_WWW=$HOME/public_html
BACKUP_WWW=$HOME/backup_html
MY_DOMAIN=server_domain_or_IP
​
set -e
​
rm -rf $WORKING_DIRECTORY
rsync -aqz $PUBLIC_WWW/ $BACKUP_WWW
trap "echo 'A problem occurred.  Reverting to backup.'; rsync -aqz --del $BACKUP_WWW/ $PUBLIC_WWW; rm -rf $WORKING_DIRECTORY" EXIT

现在,我们可以开始部署了。我们将创建一个我们裸仓库的常规克隆,以便Hugo可以访问repo内容。然后,我们将从公共Web目录中删除所有内容,以便公共Web目录中只有新文件可用。之后,我们将使用Hugo来构建我们的网站。我们将它指向我们的新克隆作为源目录,并告诉它将生成的内容放在公共Web文件夹中。我们还将传递包含我们的生产服务器的域名或IP地址的变量,以便它可以正确地构建链接。

在Hugo构建内容之后,我们将删除工作目录。然后,我们将重置trap命令,以便在脚本尝试退出时,我们的备份副本不会立即覆盖我们的新内容:

代码语言:javascript
复制
#!/bin/bash
​
GIT_REPO=$HOME/my-website.git
WORKING_DIRECTORY=$HOME/my-website-working
PUBLIC_WWW=$HOME/public_html
BACKUP_WWW=$HOME/backup_html
MY_DOMAIN=server_domain_or_IP
​
set -e
​
rm -rf $WORKING_DIRECTORY
rsync -aqz $PUBLIC_WWW/ $BACKUP_WWW
trap "echo 'A problem occurred.  Reverting to backup.'; rsync -aqz --del $BACKUP_WWW/ $PUBLIC_WWW; rm -rf $WORKING_DIRECTORY" EXIT
​
git clone $GIT_REPO $WORKING_DIRECTORY
rm -rf $PUBLIC_WWW/*
/usr/bin/hugo -s $WORKING_DIRECTORY -d $PUBLIC_WWW -b "http://${MY_DOMAIN}"
rm -rf $WORKING_DIRECTORY
trap - EXIT

此时,我们的脚本已完成。完成后保存并关闭文件。

我们现在要做的就是使脚本可执行,以便git在适当的时候调用它:

代码语言:javascript
复制
chmod +x post-receive

我们的部署系统现已完成。我们来试试吧。

测试部署系统

现在我们已经建立了系统,我们可以继续进行测试。

让我们开始测试我们的post-receive钩子脚本。这将允许我们使用我们的Web内容的初始副本填充我们的~/public_html目录。它还有助于验证脚本的主要组件是否按预期工作:

代码语言:javascript
复制
bash ~/my-website.git/hooks/post-receive

这应该运行您的脚本并将普通git和Hugo消息输出到屏幕:

代码语言:javascript
复制
Cloning into '/home/justin/my-website-working'...
done.
0 draft content
0 future content 
4 pages created
0 paginator pages created
0 tags created
1 categories created
in 26 ms

如果您在Web浏览器中访问生产服务器的域名或IP地址,您应该会看到您网站的当前版本:

代码语言:javascript
复制
http://production_domain_or_IP

现在,我们可以回到我们用于Hugo开发的机器。在那台机器上,让我们创建一个新帖子:

代码语言:javascript
复制
hugo new post/Testing-Deployment.md

在新帖子中,只需添加一些内容,以便我们可以测试我们的系统:

代码语言:javascript
复制
+++
categories = ["misc"]
date = "2015-11-11T16:24:33-05:00"
title = "Testing Deployment"

+++

## A Test of the New Deployment System

I hope this works!

现在,将内容添加到git并提交更改:

代码语言:javascript
复制
git add .
git commit -m 'Deployment test'

现在,如果一切按计划进行,我们只需推送到我们的生产服务器即可部署新的更改:

代码语言:javascript
复制
git push prod master

现在,如果您在Web浏览器中重新访问您的生产站点,您应该看到新内容:

代码语言:javascript
复制
http://production_domain_or_IP

我们的部署系统似乎运行正常。

结论

在本指南中,我们设置了一个单独的生产服务器,专门为访问者提供Web内容。在此服务器上,我们安装并配置了多个组件,以便Hugo可以正确构建和提供我们的内容。然后,我们创建了一个部署脚本,只要我们从开发计算机将新内容推送到服务器,就会触发该脚本。

我们的部署系统中涉及的实际机制是相当基本的。但是,它们构成了易于维护的系统的基础,可以快速,轻松地在Web服务器上获取本地内容。由于部署过程是自动化的,因此您无需与服务器进行交互即可进行简单的git push更改。

更多Ubuntu教程请前往腾讯云+社区学习更多知识。

参考文献:《How To Deploy a Hugo Site to Production with Git Hooks on Ubuntu 14.04》

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 准备
  • 准备开发服务器
    • 配置对生产服务器的SSH密钥访问
      • 将Initial Git Repo传输到Production Server
        • 为Production Server添加Git Remote
        • 设置生产服务器
          • 在Production Server上安装Git,Pygments和Nginx
            • 在Production Server上安装Hugo
              • 配置Nginx以服务部署期间生成的文件
                • 创建一个Post-Receive Hook来部署Hugo站点
                • 测试部署系统
                • 结论
                相关产品与服务
                云开发 CloudBase
                云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档