介绍
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
命令为您提供了如下所示的行,则您的帐户中已有一个密钥:
/home/demouser/.ssh/id_rsa
获得密钥对后,可以通过键入密钥将公钥传输到生产服务器。在命令中,在本指南的先决条件阶段替换您在生产服务器上配置的非root帐户名称:
代码语言:javascript复制ssh-copy-id username@production_domain_or_IP
如果这是您第一次在这两台计算机之间使用SSH,则会要求您键入“是”来确认连接。之后,系统将提示您输入生产服务器的用户密码。您的公钥将被传输到生产服务器,允许您下次无需密码登录。
通过使用以下ssh
命令询问生产服务器的主机名来测试此功能:
ssh username@production_domain_or_IP cat /etc/hostname
这次不应该提示您输入密码。您应该收到生产服务器的主机名:
代码语言:javascript复制prodserver
将Initial Git Repo传输到Production Server
接下来,我们需要将Hugo仓库的初始克隆转移到我们的生产服务器。我们将需要这个以便post-receive
稍后在生产服务器上设置一个钩子。为了实现这一点,我们需要创建一个git
repo 的“裸”克隆并将其复制到我们的其他服务器。
裸存储库是一个git
没有工作目录的特殊存储库。在传统的git
repos中,项目文件保存在主目录中,git
版本控制数据保存在被调用的隐藏目录中.git
。裸仓库没有项目文件的工作目录,因此通常保存在隐藏.git
文件夹中的文件和目录位于主文件夹中。Bare repos通常用于远程服务器,因为它简化了推送内容的过程。
我们将从/tmp
目录中的主Hugo存储库创建一个裸仓库。裸回购通常由尾随.git
后缀标识。要创建此副本,我们将使用git clone
带有以下--bare
选项的命令:
git clone --bare ~/my-website /tmp/my-website.git
我们可以将这个裸存储库传输到我们的生产服务器scp
。确保在命令末尾包含尾部“:”,以便将repo放置在远程系统上用户的主目录中。
scp -r /tmp/my-website.git username@production_domain_or_IP:
为Production Server添加Git Remote
现在我们git
在生产服务器上有了我们的裸仓库,我们可以将生产服务器添加为跟踪的远程仓库。这将允许我们轻松地将新内容推送到我们的生产服务器。
回到你的Hugo目录:
代码语言:javascript复制cd ~/my-website
我们需要做的就是决定遥控器的名称。在本指南中,我们将使用prod
。然后,我们可以在远程系统上指定裸存储库的连接信息和位置:
git remote add prod username@production_domain_or_IP:my-website.git
在我们的生产服务器上安装git
之前,您将无法测试此远程链接。
设置生产服务器
现在我们的开发机器已完全配置,我们可以继续设置我们的生产系统。
在我们的生产系统中,我们需要完成以下步骤:
- 安装
git
,nginx
和pygments
- 安装Hugo和Hugo主题
- 配置
nginx
为从主目录中的位置提供文件 - 创建
post-receive
脚本以部署推送到我们的存储库的新内容
在Production Server上安装Git,Pygments和Nginx
我们应该做的第一件事就是安装git
,pygments
和nginx
到服务器上。虽然我们的项目存储库已经在我们的服务器上,但我们需要该git
软件来接收推送并执行我们的部署脚本。我们需要pygments
为任何代码块应用服务器端语法高亮。我们将使用nginx
Web服务器,使访问者可以访问我们的内容。
更新本地包指数和安装git
,并nginx
从Ubuntu的默认存储库。我们需要安装pip
Python包管理器来获取pygments
:
sudo apt-get update
sudo apt-get install git nginx python-pip
然后我们可以pip
用来安装pygments
:
sudo pip install Pygments
下载完成后,我们可以测试我们是否在开发计算机上正确设置了远程存储库。在您的开发计算机上,进入Hugo项目目录并使用以下git ls-remote
命令:
cd ~/my-website
git ls-remote prod
如果git
可以在开发和生产机器上的存储库之间建立连接,它将显示refs列表,如下所示:
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
下载您复制的链接:
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
目录:
mkdir ~/public_html
接下来,让我们打开默认的Nginx服务器块配置文件进行必要的调整:
代码语言:javascript复制sudo nano /etc/nginx/sites-available/default
我们需要更改的唯一选项是server_name
,应指向生产服务器的域名或IP地址以及root
指令,该指令应指向我们刚刚创建的public_html
目录:
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
的目录。立即进入该目录:
cd ~/my-website.git/hooks
这个目录有很多示例脚本,但我们需要一个post-receive
本指南的脚本。在hooks
目录中创建并打开具有此名称的文件:
nano post-receive
在文件的顶部,在指出这是一个bash脚本之后,我们将从定义一些变量开始。我们将设置GIT_REPO
为裸存储库。我们将把它克隆到WORKING_DIRECTORY
变量指定的临时存储库,以便Hugo可以访问其中的内容来构建实际的站点。因为我们的git
repo中的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
目录的任何实例。
#!/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
命令,以便在脚本尝试退出时,我们的备份副本不会立即覆盖我们的新内容:
#!/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
在适当的时候调用它:
chmod x post-receive
我们的部署系统现已完成。我们来试试吧。
测试部署系统
现在我们已经建立了系统,我们可以继续进行测试。
让我们开始测试我们的post-receive
钩子脚本。这将允许我们使用我们的Web内容的初始副本填充我们的~/public_html
目录。它还有助于验证脚本的主要组件是否按预期工作:
bash ~/my-website.git/hooks/post-receive
这应该运行您的脚本并将普通git
和Hugo消息输出到屏幕:
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
并提交更改:
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》