やりたいこと
priv/static
以下の静的ファイルをmix
のタスクからS3にアップロードし、CloudFrontからアセットを配信したい
やったこと
PHPでLaravel向けにvinelab/cdn
というアセットライブラリがあるのだけどElixirに似たようなライブラリがなかったのでポートしたのを作ってS3 + CloudFrontで配信出来るようにした
Installation
- mix.exsに依存を追加
{:cdn, "~> 0.0.4"}
- 依存更新
mix deps.get
- configを追加
config/config.exs
config :cdn, include: [
directories: ["priv/static"],
patterns: ["**/*"],
hidden: true
],
exclude: [
directories: [],
patterns: [],
hidden: true
],
acl: :public_read,
bypass: true,
cache_control: "max-age=#{86400 * 30}",
expires_after: 86400 * 30
項目 | 説明 |
---|---|
include |
directories : アップロード対象のディレクトリpatterns : Glob patternでアップロード対象の絞込。複数指定可。hidden : 隠しファイルを含めるかどうかをtrue, falseで指定 |
exclude |
除外対象のファイル。include と同じようにディレクトリとパターンを指定。 |
acl |
アップロードしたオブジェクトの権限。アセットとして公開されるので通常はpublic_read にする。 |
cache_control |
Cache-Control ヘッダに指定する値 |
expires_after |
Expires ヘッダに指定するキャッシュ期限切れまでの秒数 |
config/dev.exs
config :cdn, bucket: "foobar.assets",
cloudfront_url: "https://foobar.cloudfront.net",
bypass: true
項目 | 説明 |
---|---|
bucket |
アップロード対象のS3バケット |
cloudfront_url |
S3と紐付けられているCloudFrontのURL |
bypass |
true の場合ビュー用のヘルパーでURLを補完しない。e.g. cdn("/css/app.css") => "/css/app.css"
|
config/prod.exs
config :cdn, bucket: System.get_env("ASSET_BUCKET") || "foobar.production.assets",
cloudfront_url: System.get_env("ASSET_HOST") || "https://foobar.cloudfront.net",
bypass: false
項目 | 説明 |
---|---|
bypass |
false の場合ビュー用ヘルパーでURLを補完する。e.g. cdn("/css/app.css") => "https://foobar.cloudfront.net/css/app.css"
|
- AWSのアクセスキーを環境変数にセット
export AWS_ACCESS_KEY_ID=foo
export AWS_SECRET_ACCESS_KEY=bar
Usage
- アセットアップロード
mix cdn.push
- 削除
mix cdn.empty
- テンプレートで静的ファイルの読み込み
web/web.ex
def view do
~中略~
# 追加
import Cdn.Helpers
end
app.html.eex
<script src="<%= cdn static_path(@conn, "/js/vendor.js") %>"></script>
# bypass=trueの場合
#=> "<script src="/js/vendor.js"></script>"
# bypass=falseの場合
#=> "<script src="https://foobar.cloudfront.net/js/vendor.js"></script>"
まとめ
- PhoenixでS3 + CloudFrontでアセットを配信出来るようにした
- Elixir内で完結するので他のツール使いたくない場合はいいかも
- 今気づいたけどasset_syncって似たようなライブラリが既にありますね(遅)