undefined

bokuweb.me

HerokuへDockerを使ってPhoenixアプリをデプロイする

ここ数日全然うまくいかなかったけど、一応動作したので記録として残しておく

前提

herokuへのDeploy方法は公式にもアナウンスされていたり、各所で記事が上がっているんだけどいずれも自分の場合うまく行かなかった。カットアンドトライで今の方法に行き着いたので、とんちんかんなことをしている可能性がある。その場合ご指摘いただけると幸いです。

www.phoenixframework.org

条件

  • Elixir / Phoenix インストール済
  • Heroku登録、Toolbeltインストール済
  • Docker Toolboxインストール済

手順

基本的には以下に沿う。brunchを使用するなら以下に沿えば一応動く。

github.com

プロジェクトの作成

$ mix phoenix.new phoenix_heroku_sample

dockerプラグインのインストール

$ heroku plugins:install heroku-docker
$ cd phoenix_heroku_sample

heroku-dockerについては以下を見ると良さそう。

devcenter.heroku.com

app.jsonProcfileの準備

https://github.com/selvan/docker-heroku-phoenix-app からapp.jsonとProcfileをアプリケーションのルートにもってきて、適宜名前など編集する

  • app.json
{
  "name": "phoenix_heroku_sample",
  "description": "A sample phoenix app",
  "image": "joshwlewis/docker-heroku-phoenix:latest",
  "addons": [
    "heroku-postgresql"
  ]
}
  • Procfile
web: MIX_ENV=prod NODE_ENV=production BRUNCH_ENV=production mix phoenix.server

初期化

Dockerfile

Dockerfileが生成される

heroku docker:init

Dockerfileを以下のように変更。 npm run build でビルドするようにしている。

FROM joshwlewis/docker-heroku-phoenix:latest

ENV MIX_ENV prod

# This causes brunch to build minified and hashed assets
ENV BRUNCH_ENV production

# We add manifests first, to cache deps on successive rebuilds
COPY ["mix.exs", "mix.lock", "/app/user/"]
RUN mix deps.get

# Again, we're caching node_modules if you don't change package.json
ADD package.json /app/user/
RUN npm install

# Add the rest of your app, and compile for production
ADD . /app/user/
RUN mix compile \
    && npm run build \
    && mix phoenix.digest

pacakge.json

{
  "repository": {},
  "scripts": {
    "build-assets": "cp -r web/static/assets/* priv/static",
    "watch-assets": "watch-run -p 'web/static/assets/*' npm run build-assets",
    "build-js": "browserify -t babelify web/static/js/app.js | uglifyjs -mc > priv/static/js/app.js",
    "watch-js": "watchify -t babelify web/static/js/app.js -o priv/static/js/app.js -dv",
    "build-css": "cat web/static/css/*.css > priv/static/css/app.css",
    "watch-css": "catw web/static/css/*.css -o priv/static/css/app.css -v",
    "build": "npm run build-assets && npm run build-js && npm run build-css",
    "watch": "npm run watch-assets & npm run watch-js & npm run watch-css",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "dependencies": {
    "phoenix": "file:deps/phoenix",
    "phoenix_html": "file:deps/phoenix_html"
  },
  "devDependencies": {
    "babel-preset-es2015": "^6.6.0",
    "babel-preset-react": "^6.5.0",
    "babel-preset-stage-0": "^6.5.0",
    "babelify": "^7.2.0",
    "browserify": "^13.0.0",
    "catw": "^1.0.1",
    "uglify-js": "^2.6.2",
    "watch-run": "^1.2.4",
    "watchify": "^3.7.0"
  }
}

.babelrc

プラグイン、プリセットはおこのみで。

{
  "presets": [
    "es2015",
    "react",
    "stage-0"
  ]
}

app.js

web/static/js/app.jsを編集する

  • web/static/js/app.js
import "../../../deps/phoenix_html/web/static/js/phoenix_html";

assets用ディレクトリ

priv/static/jspriv/static/cssを作成しておく

アプリの作成

heroku create phoenix-heroku-sample

prod.secretの編集

  • config/prod.secret.ex
use Mix.Config

# In this file, we keep production configuration that
# you likely want to automate and keep it away from
# your version control system.
config :phoenix_heroku_sample, PhoenixHerokuSample.Endpoint,
  secret_key_base: System.get_env("SECRET_KEY_BASE")

# Configure your database
config :phoenix_heroku_sample, PhoenixHerokuSample.Repo,
  adapter: Ecto.Adapters.Postgres,
  url: {:system, "DATABASE_URL"},
  pool_size: 20

secret key baseを環境変数に移しておく。 以下のようにconfig/prod.secret.exに記載してあった、secret key baseをセットする

heroku config:set SECRET_KEY_BASE="xxxxxxxxxxxxxxxxxxxxxxxxx" --app phoenix-heroku-sample

prod.secretをgitで管理する。 Heroku · Phoenixではprod.secretを使用せずprodを使用する方法が書かれている。

  • .gitignore
# /config/prod.secret.exs

デプロイ

phoenix_heroku_sample heroku docker:release --app phoenix-heroku-sample

問題

  • ローカルで動か無い気がする
    • docker-compose upじゃだめ?
  • フロント以外の各手順の意味が明確に理解できていない