おぐらです。
このブログは、Middlemanを使って生成した静的コンテンツをAmazon S3にアップロードし、S3 Static Website Hosting機能を使ってWebサイトとして配信しています。
今回は、この構成を実現するための手順として、
- コンテンツをS3にアップロードするmiddleman-syncの導入
- S3 Static Website Hostingの設定
について解説します。
既にMiddlemanでサイトを運用している場合、1時間ほどでS3での独自ドメイン運用ができるようになると思います。
S3 Static Website Hostingとは何か
S3には静的なサイトをホスティングする「Static Website Hosting」という機能があり、Bucket毎のWebsite Hosting設定を行うことで、Bucket内にアップロードしたファイルに以下のようなURLでアクセスできるようになります。
<bucket-name>.s3-website-<AWS-region>.amazonaws.com
URLはBucket名とリージョン名によって決まるので、例えば東京リージョン(ap-northeast-1
)にblog.qnyp.com
というBucketを作成した場合は、
blog.qnyp.com.s3-website-ap-northeast-1.amazonaws.com
というURLになります。
なお、Bucket名を決める際には以下のような制約があるので注意してください。
- サブドメインを割り当てるには、
www.example.com
やblog.example.com
のようにCNAMEと同じBucket名にする必要がある example.com
のようなサブドメイン部を含まないネイキッドドメインを割り当てるには、DNSとしてAmazon Route 53を利用する必要がある
middleman-syncの導入
middleman-syncという拡張を利用すると、Middlemanで生成したコンテンツを簡単にAmazon S3にアップロードすることができます。
MiddlemanプロジェクトフォルダにあるGemfile
にmiddleman-syncを追加して、
gem 'middleman-sync', '3.0.9' # 本稿執筆時点の最新版
bundle
します。
$ bundle
middleman-syncの設定
config.rb
にmiddleman-syncの設定を追加します。
# Activate sync extension
activate :sync do |sync|
# 利用するストレージプロバイダの識別子。S3を利用する場合は`AWS`
sync.fog_provider = 'AWS'
# アップロード先となるS3 Bucketの名前
sync.fog_directory = 'blog.qnyp.com'
# AWSリージョンの識別子。東京リージョンの場合は`ap-northeast-1`
sync.fog_region = 'ap-northeast-1'
# AWSアクセスキーID
sync.aws_access_key_id = '*****'
# AWSシークレットアクセスキー
sync.aws_secret_access_key = '*****'
# アップロード時に既存ファイルを削除するかどうか。`delete`または`keep`
sync.existing_remote_files = 'keep'
# ファイルをgzip圧縮したもので置き換えるかどうか。`true`または`false`
sync.gzip_compression = false
# Middlemanのビルド完了後に自動で同期を行うかどうか。`true`または`false`
# デフォルトでは行う(`true`)
sync.after_build = false
end
middleman-syncのデフォルトではmiddleman build
でコンテンツのビルドが完了すると、自動的にS3への同期が始まるようになっています。複数人でコンテンツを作成しているような場合は、レビュー前に公開されてしまうと都合が悪いので、その場合はsync.after_build
をfalse
に設定しておきましょう。
S3への同期
sync.after_build
が未設定またはtrue
の場合は、プロジェクトをビルドすると、S3への同期が始まります。
$ middleman build
自動同期を行わないように設定している場合は、build
コマンドでコンテンツを生成した後、sync
コマンドで同期を行います。
$ middleman build
$ middleman sync
== LiveReload is waiting for a browser to connect
AssetSync: Syncing.
Using: Directory Search of build/**
Uploading: 2012/01/02/index.html
(中略)
Uploading: tags/technology/index.html
AssetSync: Done.
上記のようにAssetSync: Done.
と表示されれば、S3への同期は完了です。
middleman-syncによる同期は差分の同期ではなく、build
ディレクトリ以下のコンテンツをすべて上書きアップロードする方式のようなので、コンテンツが膨大になってくると同期にかかる時間も増えてしまうという問題があります(対策を考えているところです)。
S3の設定
S3 BucketをWebサイトとして公開するには、AWS Management Consoleから以下の設定を行います。
- Website Hostingを有効にする
- Bucket Policyを追加する
Website Hostingを有効にする
S3の管理画面でBucketを選択して「Properties」タブを表示すると、下図のように「Static Website Hosting」という項目があるので、これをクリックして展開します。
項目を展開すると、Webサイトとしてのホスティングを有効にするかどうかのラジオボタンが表示されます。
ここでは「Enable website hosting」を選択して、さらに「Index Document」と「Error Document」を入力します。
Index Documentには、http://example.com/
やhttp://example.com/articles/
のようにファイル名を含まないURLにアクセスされた場合に表示するファイルの名前を入力します。
Error Documentには、ファイルが存在しないURLにアクセスされた場合に表示するファイルの名前を入力します。
設定が完了したら「Save」ボタンを押して、変更を反映します。
なお、「Do not enable website hosting」を選択した場合は、BucketにHTTPでアクセスしてもステータスコード404
が返されるだけとなります。
Bucket Policyを追加する
Bucket内のコンテンツに誰でもアクセスできるように、Bucket Policyを追加します。
S3の管理画面でBucketを選択して「Properties」タブを表示し、「Permissions」をクリックして展開すると、以下のようにパーミッション設定ができるようになるので、「Add bucket policy」ボタンをクリックします。
Bucket Policy Editorが開くので、ポリシーを設定して「Save」ボタンをクリックします。
ここでは、以下のようにBucket内のすべてのファイルを参照可能とするポリシーを設定します。「Bucket名」の部分を実際の値に置き換えてください。
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "AllowPublicRead",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::Bucket名/*"
}
]
}
ここまでの設定が完了すると、http://<bucket-name>.s3-website-<AWS-region>.amazonaws.com/
のようなURLでコンテンツにアクセスできるようになります。
ドメインの割り当て
サブドメインの場合
blog.example.com
のようなサブドメインでBucketにアクセスできるようにするには、DNSでCNAMEレコードを作成し、レコードの値として<bucket-name>.s3-website-<AWS-region>.amazonaws.com
のようなドメイン名を設定します。
ネイキッドドメインの場合
example.com
のようにサブドメインを含まないドメインでアクセスできるようにする場合は、example.com
用のS3 Bucketを作成してリダイレクトの設定を行ったうえで、Route 53にAレコードを追加します。
詳細な手順については、以下のブログ記事が参考になります。
まとめ
S3でサイトを公開すると、サーバーのセットアップや運用などに頭を悩ませる必要がなくなるため、動的な仕組みが不要なサイトにはとてもおすすめです。
Middlemanで生成したコンテンツをS3で公開するにあたっては、キャッシュの設定やContent-Typeの設定など、いくつか考慮したほうがよい点もあるので、それらについても後日フォローしていこうと思います。