如何在Ubuntu 14.04部署Hugo站点到生产使用Git Hooks

Hugo是一个静态网站生成器,让您可以轻松创建并通过简单的标记语言编写web内容发布。Hugo可以根据您指定的配置解析内容文件,应用主题,并生成漂亮的网页,可以很容易地...

介绍

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

先前的指导 ,我们介绍了如何Hugo安装到一个Ubuntu 14.04系统,并用它来创建内容。 在本指南中,我们将告诉你如何建立一个系统, git ,你可以用它来自动将新内容部署到生产Web服务器。

先决条件

对于本指南中,我们将假定你有一个Ubuntu 14.04整机运行起来作为开发机器作为我们概述Hugo安装指南

我们将建立一个第二的Ubuntu 14.04服务器服务于我们的实际生产中的网站。 在此服务器上,确保你已经创建了一个非root用户sudo权限。 您可以按照我们最初的服务器设置向导来创建此帐户。

准备开发服务器

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

我们需要在这个服务器上做一些事情来设置一步部署。 我们要:

  • 配置SSH密钥访问我们的生产服务器
  • 传送的初始git库到生产服务器
  • 添加生产服务器作为一个git在我们的网站知识库的远程

让我们开始吧。

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

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

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

ls ~/.ssh/id_rsa

如果您回到一条看起来像这样的行,您还没有配置SSH密钥对:

ls: cannot access /home/demouser/.ssh/id_rsa: No such file or directory

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

ssh-keygen

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

如果,另一方面, ls命令给你一条线,看起来像这样,你已经在你的帐户的关键:

/home/demouser/.ssh/id_rsa

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

ssh-copy-id username@production_domain_or_IP

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

通过询问生产服务器与主机名测试此功能ssh命令:

ssh username@production_domain_or_IP cat /etc/hostname

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

prodserver

将初始Git Repo传送到生产服务器

接下来,我们需要将我们的Hugo repo的初始克隆传递到我们的生产服务器。 我们将需要这一点是为了建立一个post-receive后在生产服务器上的钩子。 要做到这一点,我们需要建立我们的“裸”克隆git回购并将其复制到我们的其他服务器。

纯仓库是一个特殊git库,没有工作目录。 在传统git回购,项目文件都保存在主目录和git版本数据被保存在一个名为中的一个隐藏目录.git 裸回购对项目文件没有工作目录,这样通常保存在隐藏的文件和目录.git文件夹是主文件夹来代替。 裸机库通常用于远程服务器,因为它简化了推送内容的过程。

我们将创建一个从我们的主Hugo库裸回购/tmp目录。 裸露的回购协议通常是由尾随确定.gitStapling。 为了创建这个副本中,我们将使用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:

为生产服务器添加Git远程

现在,我们有我们裸露git回购我们的生产服务器上,我们可以添加生产服务器作为跟踪远程仓库。 这将使我们能够轻松地将新内容推送到我们的生产服务器。

移回您的Hugo目录:

cd ~/my-website

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

git remote add prod username@production_domain_or_IP:my-website.git

您将无法测试这个远程链接,直到我们安装后git我们的生产服务器上。

设置生产服务器

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

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

  • 安装gitnginx ,和pygments
  • 安装Hugo和Hugo主题
  • 配置nginx服务于我们的主目录从一个位置的文件
  • 创建post-receive脚本部署新的内容推到我们的代码库

在生产服务器上安装Git,Pygments和Nginx

我们应该做的第一件事就是安装gitpygments ,而nginx到服务器上。 虽然我们的项目库已经是我们的服务器上,我们需要git软件接收推送和执行我们的部署脚本。 我们需要pygments应用服务器端语法高亮任何代码块。 我们将使用nginx作为Web服务器,这将使我们的内容提供给游客。

更新本地包指数和安装gitnginx从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可以建立你的研发和生产机器存储库之间的连接,它会显示裁判的名单,像这样:

103902f5d448cf57425bd6830e544128d9522c51    HEAD
103902f5d448cf57425bd6830e544128d9522c51    refs/heads/master

在生产服务器上安装Hugo

回到我们的生产服务器上,我们需要安装Hugo。 相反,我们的建设开发服务器上我们的内容,我们将建立后,每一个生产服务器上的静态资产git push 为此,我们需要安装Hugo。

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

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

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

sudo dpkg -i hugo*.deb

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

hugo version

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

Hugo Static Site Generator v0.14 BuildDate: 2015-05-25T21:29:16-04:00

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

git clone --recursive https://github.com/spf13/hugoThemes ~/themes

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

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

为了简化而不是把我们生成的内容在我们的部署, var/www/html目录,内容将被放置在一个目录中称为public_html我们的用户的主目录中。

让我们继续前进,创造public_html现在目录:

mkdir ~/public_html

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

sudo nano /etc/nginx/sites-available/default

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

/ etc / nginx / sites-available / default
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与生产服务器上的实际用户名指令。 保存并在完成后关闭文件。

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

sudo service nginx restart

我们的Web服务器现在是准备为我们投入了文件public_html目录。

创建一个接收后挂钩以部署Hugo站点

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

为了创建这个脚本,我们将进入我们的纯仓库我们的生产服务器上生成一个叫做hooks 现在移动到该目录:

cd ~/my-website.git/hooks

这个目录有不少示例脚本,但我们需要一个post-receive脚本本指南。 创建和打开一个文件使用该名称在hooks目录:

nano post-receive

在文件的顶部,在指示这是一个bash脚本之后,我们将通过定义几个变量开始。 我们将设置GIT_REPO我们的纯仓库。 我们将这个克隆由变量指定的临时存储库WORKING_DIRECTORY让·Hugo可以在访问内容构建实际的网站。 因为在我们的主题目录git回购实际上只是指向父目录的位置的符号链接,我们需要确保工作目录克隆在相同的位置,因为我们下载的Hugo主题创建。

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

记住这一点,你的文件的开头应该是这样:

〜/ my-website.git / hooks / post-receive
#!/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目录。

〜/ my-website.git / hooks / post-receive
#!/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

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

在Hugo构建内容之后,我们将删除工作目录。 然后,我们将重新设置trap命令,这样当脚本试图退出我们的备份副本不立即覆盖了新的内容:

〜/ my-website.git / hooks / post-receive
#!/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钩脚本。 这将允许我们来填充我们的~/public_html目录与我们的Web内容的初始副本。 它还将帮助验证脚本的主要组件是否按预期工作:

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地址,您应该会看到您的网站的当前版本:

http://production_domain_or_IP

Hugo初始站点状态

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

hugo new post/Testing-Deployment.md

在新帖子中,只是放了一些内容,以便我们可以测试我们的系统:

〜/ my-website / content / post / Testing-Deployment.md
+++
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'

现在,如果一切都按计划进行,我们可以通过推送到我们的生产服务器来部署我们的新更改:

git push prod master

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

http://production_domain_or_IP

Hugo新内容

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

结论

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

我们的部署系统中涉及的实际机制相当基础。 但是,它们构成了一个易于维护的系统的基础,用于快速,无痛地在Web服务器上获取本地内容。 由于部署过程是自动的,你将不必与服务器进行交互,使超越了简单的变化git push