- ブログサイトの公開方法は、
GitHub Pages
やその他無料サービスなどあるようですが、
ここではAWSを使ってブログサイトを公開する方法を紹介します。 - AWSを使う理由は、自由度の高さと運用費用の安さです。
- AWS利用開始1年未満であれば無料枠で運用できますし、1年経過後でも月額10円未満程度で運用できます。
この記事の目的
- ブログサイトをAWS のS3とCloudFrontを利用して公開します。
- 公開中のサイトが以下です。
https://docusaurus.plant11.com
👇これより先は下記記事の内容を前提とします
導入手順
- 本家AWSの説明サイトがあります。
CloudFront を使用して、Amazon S3 でホストされた静的ウェブサイトを公開するにはどうすればよいですか?
https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/getting-started-secure-static-website-cloudformation-template.html#deploy-secure-static-website-cloudformation - 他にも説明サイトがいろいろあります。
https://dev.classmethod.jp/articles/sap-exam-study-1-2/
https://dev.classmethod.jp/articles/distributing-s3-content-with-cloudfront/
https://qiita.com/NaokiIshimura/items/46994e67b712831c3016
デプロイの効率化
サイトをビルドし、S3へアップロードする処理をpythonで作成しました。
deploy.py
deploy.py
import os
import subprocess
import boto3
import pathlib
def clear_before():
s3 = boto3.client('s3')
bucket_name = "your.bucket.name"
response = s3.list_objects_v2(Bucket=bucket_name, Prefix="docusaurus/")
if 'Contents' in response:
contents = response['Contents']
for content in contents:
print("delete:" + content['Key'])
s3.delete_object(Bucket=bucket_name,Key=content['Key'])
def upload(prefix,file):
print("filename:" + file.name)
#print(file.name.split(".")[-1])
ext = file.name.split(".")[-1]
content_type="text/html"
if ext == "txt":
content_type="text/plain"
elif ext == "ico":
content_type="image/x-icon"
elif ext == "svg":
content_type="image/svg+xml"
elif ext == "js":
content_type="application/javascript"
elif ext == "css":
content_type="text/css"
print("content_type:" + content_type)
s3 = boto3.client('s3')
key_value = file.name
if(len(prefix)):
key_value = prefix + "/" + file.name
with open(file, 'rb') as f:
res = s3.put_object(
Body=f,
Bucket="your.bucket.name",
Key=key_value,
ContentType=content_type,
)
if __name__ == '__main__':
cmd = ["npm", "run", "build"]
subprocess.run(cmd,cwd=".",shell=True)
clear_before()
files = pathlib.Path("build").glob("**/*")
for file in files:
if pathlib.Path.is_file(file):
dir_prefix = "docusaurus/" + str(file.parent).replace("\\","/")[len("build/"):]
if dir_prefix.endswith('/'):
dir_prefix = dir_prefix[:-1]
upload(dir_prefix,file)
index.html
参照エラーの回避
CloudFrontでDocusaurusのサイトを公開すると、index.html
が参照できないことにより、画面遷移の際に画面表示エラーが発生します。
AWSからもこの問題に対する解決方法が公開されています。
index.html を追加してファイル名を含まない URL をリクエストする
具体的手順を以下に記載します。
Lambdaの作成
CloudFrontへ適用するLambda関数はバージニア北部リージョンで作成する必要があります。
lambda_function.py
lambda_function.py
import json
def lambda_handler(event, context):
request = event['Records'][0]['cf']['request']
print(request['uri'])
if request['uri'].endswith("/"):
request['uri'] += "index.html"
print(request['uri'])
elif not '.' in request['uri']:
request['uri'] += "/index.html"
print(request['uri'])
return request
CloudFrontへの適用
Lambda関数のコンソールから、Lambda@Edge へのデプロイを指定します。
👇前提記事
👇関連記事
👇参考URL
- CloudFront を使用して、Amazon S3 でホストされた静的ウェブサイトを公開するにはどうすればよいですか?
- https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/getting-started-secure-static-website-cloudformation-template.html#deploy-secure-static-website-cloudformation
- https://dev.classmethod.jp/articles/sap-exam-study-1-2/
- https://dev.classmethod.jp/articles/distributing-s3-content-with-cloudfront/
- https://qiita.com/NaokiIshimura/items/46994e67b712831c3016
- index.html を追加してファイル名を含まない URL をリクエストする