静的サイトを s3 にデプロイするツールを作りました。aws s3 sync は便利なのですがContent-Type
やCache-Control
などのメタデータをファイル個別に設定できない(よね?)ので似たようなものを作りました。直接 S3 から或いは CloudFront から配信するときにこれらのメタデータをつけておきたいですよね。
https://github.com/akr4/webapp-deployer
指定したバケットの中身を全部削除(!)して、ローカルのディレクトリのファイルをアップロードします。アップロードするファイルとメタデータを、こんな感じの設定ファイルで指定できます。
[[instructions]]
pattern = "^static/css/.*\\.css$"
action = "Upload"
[instructions.meta]
content_type = "text/css"
cache_control = "max-age=31536000"
最適な s3 へのデプロイ方法とは
このツールはバケットにある既存のファイルを全て削除して、その後ローカルファイルを順次アップロードしてゆきます。瞬間的にでもサイトが不完全な状態となるわけで、この間にアクセスしたユーザーには表示がおかしい、動作しないなどの問題が発生するかもしれません。
CloudFront を使っているならデプロイのタイミングとキャッシュが切れたタイミングがちょうど合わないと問題にならないので、稀だと思います。
CloudFront を使っている場合に完璧にやるなら、もうひとつ用意したバケットにファイルをアップロードしてから、CloudFront のオリジンを変更する手法が良いでしょうか? デプロイのたびにインフラの設定を変更することになり手軽ではないですね。
webpackでビルドされるSPAの場合は JavaScript や CSS にはファイル名にハッシュがつくため基本的には重複しません。そこでこれらのファイルを先にアップロードしておいて、次にエントリポイントとなるindex.html
をアップロード、最後に古いファイルを削除すれば、より安全です。ただこの場合でもservice-worker.js
のようにファイル名が変わらず中身が変わるファイルがあれば完璧ではありません。
結局完璧でないならば単純な方が良いと考えてこのツールでは全消し->アップロードの手法を選びました。