使用AWS的静态主机和用户友好的URL
最近我开始做这个网站,我想避免使用像Wordpress这样的东西,别误会,Wordpress很好,但我想用AWS来托管,而且成本也不只是值得。所以我决定建立一个静态网站,利用S3和Cloudfront的力量来托管它。
这就是雨果出现的原因。这是一个将我的网站和博客建成静态内容的好方法。我对它超级满意,我很快就在本地运行了,但后来是时候把它部署到AWS了,在大多数情况下,它只是工作,除了一个小细节,漂亮的URL根本不工作。
在这篇文章中,我将介绍如何使用AWS S3和Cloudfront配置和部署你的Hugo网站(或任何其他静态网站)。
建立你的网站
我不会在这里详述,有很多关于如何用Hugo或其他工具做这个的教程。
配置平台
在本节中,我们将介绍如何设置你的S3桶,创建你的Cloudfront分布,并部署你的静态网站。
创建S3桶
-
登录到AWS管理控制台,在S3控制台。
-
选择 "创建桶"并完成如下表格。
-
输入水桶名称
注意,该名称必须是DNS-complaint,并且在所有Amazon S3中是唯一的。 -
选择区域
选择一个离你近的区域,以尽量减少延迟和成本,并解决监管要求。 -
选择阻止所有公共访问
这个选项目前是默认的。 -
单击 "创建桶"。
-
创建Cloudfront分布
-
打开Amazon Cloudfront控制台,
-
选择创建分布,并完成如下向导。
-
选择Web作为你的内容的交付方式。
-
完成表格,除了你的用例所需的分发设置外,还要输入以下内容。
- 对于起源域名,选择你创建的桶。
- 对于限制桶的访问,选择是。
- 对于起源访问身份,选择创建一个新的身份。
- 对于注释,您可以选择保留默认值。或者,您可以为OAI输入一个自定义标签。
- 对于授予桶上的读取权限,选择是,更新桶策略。
-
如果你不想为你的网站使用SSL(HTTPS),请进入下一个步骤。要为你的网站使用SSL,对于SSL证书,你可以选择默认CloudFront证书或自定义SSL证书。或者,你可以选择请求或用ACM导入一个证书来请求一个新的证书。
-
选择创建分发
-
更新你的域名的DNS记录,将你的网站的CNAME指向你的CloudFront分布的域名。你可以在 CloudFront 控制台中找到你的分发域名,其格式类似于 d1234abcd.cloudfront.net。
-
等待你的DNS变化传播,并等待以前的DNS条目过期。
-
部署
从Hugo部署到AWS是非常直接的。
对于部署,我使用了一个bash脚本,它简化了我的工作流程,以下是它的工作方式
./deploy.sh
完成了!它被部署了。以下是脚本的代码
#!/bin/bash
echo "Deleting old files"
rm -rf public
echo "Building"
hugo
hugo deploy --maxDeletes -1 --invalidateCDN
echo "Deployment Completed!"
不要忘了给脚本的执行权限。
问题
经过一些测试,你可能会发现有些链接不起作用,它们会出现 "拒绝访问 "的错误。那么,这到底是怎么回事呢?嗯......当我们用Hugo(或其他许多静态CMS)生成一个网站时,你会发现每个页面的生成方式如下。/about/index.html,但这可能不是你在应用程序中设置链接的方式,你可能有类似/about 。
为什么Cloudfront不能解析目录并使用默认根页面?问题在于通过CloudFront在S3上托管一个网站。CloudFront使用S3的API来查找文件,而API是一个带有文件引用的桶,模仿文件夹结构。为S3桶启用网站托管将允许你将流量重定向到S3的HTTP端点,该端点模拟Web服务器,但在前面使用CloudFront时,你就不允许再这样做了。它有效地禁用了类似Apache或Nginx的行为,在那里你可以分配一个目录索引。CloudFront不知道你指的是一个文件夹。
解决方案
该解决方案。Lambda@Edge
在互联网上寻找了一段时间后,我发现了一个解决方案,使用Lambda@Edge来生成重定向,我们可以控制将/index.html ,以追加到用户输入的URL。
什么是Lambda?
对于那些还不知道的人来说,AWS Lambda是一种服务,可以让你按需运行代码,而不需要手动启动服务器。用他们自己的话说。
AWS Lambda让你无需配置或管理服务器就可以运行代码。你只需为你所消耗的计算时间付费。
我在过去的工作中经常使用Lambda,但是我从来没有在Cloudfront中使用过这个功能,我也不知道这有可能。
现在有可能编写你的函数,并手动完成所有的配置,这就是我所做的,然而在更多的研究后,我发现了一个更简单的方法,使用标准重定向-云端仓库。
配置
-
转到无服务器应用程序仓库。
-
按下Deploy按钮。
-
它会打开一个新的模式,显示应用程序的描述,再次按下Deploy来创建所有资源。
-
创建完成后,找到查看CloudFormation Stack按钮或直接进入Cloudformation Console。
-
在资源标签中,找到
AWS::IAM::Role,并打开物理ID,它将打开IAM控制台。 -
转到信任关系选项卡,选择编辑信任关系,允许CloudFront作为Lambda@Edge函数执行该功能,将策略设置为。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com", "edgelambda.amazonaws.com" ] }, "Action": "sts:AssumeRole" } ] } -
回到Cloudformation的Stack Detail页面,在Output标签中,找到键
StandardRedirectsForCloudFrontVersionOutput,并记下它的Value(它看起来会像:arn:aws:lambda:us-east-1:XXXXXXXXXXX:function:aws-serverless-repository-StandardRedirectsForClou-XXXXXXXXXXXX:2)。我们将在接下来的步骤中使用它,因为这是我们将在Cloudfront中使用的Lambda函数的ARN(亚马逊资源名称)。 -
回到CloudFront控制台,选择你的分发。
-
进入 "行为 "标签,编辑默认的 "行为"。
-
现在我们使用Lambda函数,在Lambda函数协会中选择事件类型/原始请求,并输入Lambda函数的StandardRedirectsForCloudFrontVersionOutput ARN值,从上一个步骤开始。