(教程) 静态网站部署1: 使用S3+CloudFront
本文写于2021-5-11
这篇文章讲什么?
怎么使用 AWS S3 + CloudFront 部署静态网站
(AWS 中国区)
这篇文章对谁有用?
想部署静态网站的程序员
我为什么写这篇文章?
因为我在这个事情上面浪费了不少时间,希望其他人能通过看我的文章节省时间。
这里的静态网站指的是
React.js / Vue.js 等前端项目 yarn build / npm build 之后
得到的 production build,用来部署的 .html .css .js 文件
问题:为什么选 S3 + CloudFront?
静态网站部署选项
- 用自己的服务器(AWS EC2/其他云服务器) + nginx/apache 来做
- 托管到第三方:
- 国内服务商:
- Coding
- 腾讯云-静态网站托管
- 阿里云
- 21 云盒子
- 七牛
- Gitee Pages
- 青云
- 百度云
- 国外服务商:
- Gitlab
- Bitbucket & aerobatic
- Github Pages
- Netlify
- Surge
- Vercel
- Gatsby Cloud
- Google Cloud Storage
- Render
- Firebase
- Cloudflare
- Heroku
- Digital Ocean
- Azure
- deployhq
- 不好分类:
- AWS S3 + CloudFront(AWS 在国内国外都有区域)
- 国内服务商:
由于我们的用户都是国内用户,所以国外服务商类似 Netlify 和 Github Pages 就不予考虑了,除非有办法加速,目前暂时没有找到好的方案。
如果不考虑网络因素,其实我会选 Netlify 因为用户体验很好,用起来很方便,但由于国内访问速度太慢,所以就不用它。
为什么不用阿里云 OSS / 腾讯云 COS / 七牛 / 21云盒子/等国内服务商?
因为之前我司已经有网站是用 S3+CloudFront 部署的。
而且我司目前大部分东西都是用 AWS (中国区)搞定的。
既然如此就继续沿用这个方案,因为之前已经有成功案例了。
不过之前的是其他同事弄的。这次是我来弄。
为什么不用 AWS Amplify?
中国区不支持(截止至2021-5-13)
S3 负责什么?CloudFront 负责什么?
S3 负责存放文件,就是 .html.css.js 这些文件。
CloudFront 负责做 CDN,加速访问。
能不能不用 CloudFront,只用 S3?
HTTPS 必须通过 CloudFront 来实现。所以必须用 CloudFront。
S3 本身只提供 HTTP 访问。
那用 S3 搭配其他的 CDN?比如 Cloudflare?
这我没试过,不知道,读者可以自己去试试。
步骤概览
在讲具体一步步怎么做之前,先写一个概览:
- 把文件传到 AWS S3(.html .css .js 等)
- 给 S3 设置权限,变成"可公开访问"
- 给 S3 设置"静态网站托管" (S3 就此告一段落,不用再回头来设置了)
- 去 CloudFront 设置,指向这个 S3 bucket。同时设定自定义域名(我们的域名是用阿里云管理的,没用 AWS 的 Route 53)域名是
news.(主域名部分隐去).com
- 设置 HTTPS 时,证书自己上传一下。
结束了,一共就这几步。
最终成果:
其实这个事情很简单,就是部署个静态站而已。
如果用 Netlify,哪怕是第一次用 Netlify,摸索一下,10分钟也就搞定了。
但 S3+CloudFront 麻烦多了。第一次弄会摸不着头脑。
具体步骤
第一步:新建一个 bucket
到时候所有的静态文件都会放到这个 bucket 里头。
这里随便建了一个 bucket 名字叫做 test-static
我在网上资料说, bucket 名字要和域名一致,但我实测结果是可以不一致,不一致也能用。
里面放一个 index.html。反正是测试嘛,内容随便写写就好了。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>简单网站2021</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="">
</head>
<body>
<h1>世界你好</h1>
<h1>本页面用于做一些简单测试</h1>
</body>
</html>
第二步:修改 S3 Bucket 的权限
弄成可公开访问就行了。
第三步:S3 bucket 的 "存储桶策略"要写一下
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws-cn:s3:::test-static/*"
}
]
}
第四步:启用"静态网站托管"
静态网站托管启用后,会有一个域名。
比如: http://test-static.s3-website.cn-north-1.amazonaws.com.cn/
复制下来,待会我们还用得上这个域名,要填写在其他地方。
第五步:去设置 CloudFront
进入 CloudFront 首页长这样:
这里用黑色方块隐藏掉了一些内容,和本文章无关,是公司的现有设置。
点击左上角蓝色按钮"创建分配"
然后点击"入门"
注意:"源域名"这里,不要用下拉菜单里弹出来的提示,不要在里面选。
填我们刚刚在 S3 开启静态网站托管之后得到的 HTTP 域名:
http://test-static.s3-website.cn-north-1.amazonaws.com.cn/
为什么 AWS 要做这么迷惑的行为,下拉菜单里的不能直接用,这个我也不懂。
反正我只知道下拉菜单里选的不能用,不要管它,这是 AWS 的锅,我们接着做下一步。
选择"将 HTTP 重定向到 HTTPS"
下一步:填这里
备用域名(CNAMEs) 填你想要的自定义域名,
比如我的是 news.[隐去主域名].com 是一个二级域名。
这里也可以填一级域名。
重点来了,HTTPS 这里
点击"传证书至 IAM"按钮,会打开如下窗口:
问题:为什么不用 ACM?
(ACM 指的是 AWS Certificate Manager)
因为用这玩意我怎么设置都不对,搞了很久。
和 CloudFront 搭配的证书用 ACM 怎么搞都不成功。
所以我们不用 ACM。
网上我查信息还看到说,必须去 us-east-1 在 ACM 里导入/新建证书,这样 CloudFront 里才能看到(真是奇葩)
我这里可是 AWS 中国区,哪儿来的 us-ease-1 给我用。我登录国际区的 ACM,整个页面空白,加载失败,所以也不知道是怎么回事。
反正用不了,不用它。
我们去阿里云搞一个免费证书
可以看到红框的 news.xxx.com 就是我们申请好的证书。
那一行的右侧有一个"下载",点击之后会弹出一个窗口,这里选择"其他"那一行。
点击下载。
会得到一个压缩包
5621740_news.xxx.com_other.zip
解压之后有2个文件。
5621740_news.xxx.com.key
5621740_news.xxx.com.pem
一个 .key 一个.pem
.key 里的内容是
-----BEGIN RSA PRIVATE KEY-----
一大堆
-----END RSA PRIVATE KEY-----
.pem 里的内容是
-----BEGIN CERTIFICATE-----
第一段
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
第二段
-----END CERTIFICATE-----
复制粘贴,填到框里:
注意开头结尾的部分也要复制,比如:
-----BEGIN CERTIFICATE-----
的部分
最后
填写完成后,等待 CloudFront 完成即可。
"分配状态"从 inProgress 变成 Deployed 就是完成了。
这时候访问 news.xxx.com 应该是可以看到成果的。
正文结束
至此,已经有一个可以访问的 HTTPS 网站了。