LoginSignup
8
6

More than 5 years have passed since last update.

PhoenixでS3 + CloudFrontでアセットを配信する

Posted at

やりたいこと

priv/static以下の静的ファイルをmixのタスクからS3にアップロードし、CloudFrontからアセットを配信したい

やったこと

PHPでLaravel向けにvinelab/cdnというアセットライブラリがあるのだけどElixirに似たようなライブラリがなかったのでポートしたのを作ってS3 + CloudFrontで配信出来るようにした

cdn | Hex (GitHub)

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

image

  • テンプレートで静的ファイルの読み込み

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って似たようなライブラリが既にありますね(遅)
8
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
6