主夫在宅パートのeitoballです。野菜の値段が高くて、ちょっと困っているこの頃です。
HerokuがDocker対応を2ヶ月半ほど前に発表しました。そこで、試しにPhoenix Frameworkを使ったアプリをDocker対応経由でHerokuへデプロイしてみましたので、共有したいと思います。
関連記事
- Phoenix Framework (Elixir)でReact.jsのTutorialを写経してみる - Misoca開発ブログ
- Phoenix Framework (Elixir)で React.jsを動かしてみる - Misoca開発ブログ
はじめに
今回の事前条件としては、
- Phoenix Frameworkが使用できる。
- Herokuのアカウントを持っている。
- Heroku Toolbeltが使用できる。
- Dockerが使用できる。
になります。
アプリの作成
おなじみのmix
を使って作成します。
$ mix phoenix.new hello_heroku * creating hello_heroku/config/config.exs ...
dockerプラグインのインストール
以下のコマンドを実行して、dockerプラグインをインストールします。
$ heroku plugins:install heroku-docker Installing plugin heroku-docker... done
Dockerfileの作成
先ほど、作成したアプリのディレクトリに移動して、以下のコマンドを実行します。
$ heroku docker:init Wrote Dockerfile (node)
HerokuへデプロイできるDockerコンテナを作成するDockerfileが作成されます。
Dockerfileの編集
Dockerfileを次のように編集します。
FROM heroku/cedar:14 RUN locale-gen en_US.UTF-8 RUN cp /usr/share/zoneinfo/Japan /etc/localtime RUN useradd -d /app -m app USER app WORKDIR /app ENV HOME /app ENV NODE_ENGINE 0.10.38 ENV PORT 3000 RUN mkdir -p /app/heroku/node RUN mkdir -p /app/src RUN curl -s https://s3pository.heroku.com/node/v$NODE_ENGINE/node-v$NODE_ENGINE-linux-x64.tar.gz | tar --strip-components=1 -xz -C /app/heroku/node ENV PATH /app/heroku/node/bin:$PATH RUN mkdir -p /app/.profile.d RUN echo "export PATH=\"/app/heroku/node/bin:/app/bin:/app/src/node_modules/.bin:\$PATH\"" > /app/.profile.d/nodejs.sh RUN echo "cd /app/src" >> /app/.profile.d/nodejs.sh WORKDIR /app/src RUN mkdir -p /app/erlang RUN curl -s https://s3.amazonaws.com/s3.hex.pm/builds/erlang/cedar-14/OTP-17.5.tar.gz | tar --strip-components=1 -xz -C /app/erlang RUN /app/erlang/Install -minimal /app/erlang ENV PATH /app/erlang/bin:$PATH RUN mkdir -p /app/elixir RUN curl -s https://s3.amazonaws.com/s3.hex.pm/builds/elixir/v1.0.4.zip -o /app/elixir/v1.0.4.zip RUN (cd /app/elixir; unzip -q v1.0.4.zip) ENV PATH /app/elixir/bin:$PATH ENV LANG=en_US.UTF-8 LANGUAGE=en_US.UTF-8 LC_ALL=en_US.UTF-8 RUN mix local.hex --force && mix local.rebar --force RUN echo "export PATH=\"/app/elixir/bin:/app/erlang/bin:\$PATH\"" > /app/.profile.d/elixir.sh ONBUILD COPY . /app/src ONBUILD USER root ONBUILD RUN chown -Rh app /app/src ONBUILD USER app ONBUILD RUN mix do deps.get, deps.compile ONBUILD RUN rm -rf node_modules ONBUILD RUN npm install ONBUILD RUN node_modules/.bin/brunch build ONBUILD RUN sed -e 's/port: 4000/port: 3000/' -i config/dev.exs ONBUILD RUN MIX_ENV=prod mix do compile.protocols, phoenix.digest ONBUILD EXPOSE 3000
ポイントはアセットファイルやアプリを事前にコンパイルしていることです。(下から4行目と2行目)
Procfileの作成
Procfileにデプロイ後にどのようにアプリを実行するかを記述します。以下の内容でProcfileを作成します。
web: MIX_ENV=prod elixir -pa _build/prod/consolidated -S mix phoenix.server
コンパイルされてまとまったアプリを実行します。
ローカル環境でのテスト
ローカル環境でアプリを動作させてみます。heroku docker:start
で起動します。
$ heroku docker:start building image... ... tarting container... web process will be available at http://192.168.0.1:3000/ 01:23:45.678 [info] Running HelloHeroku.Endpoint with Cowboy on port 3000 (http)
表示されている(環境によって異なります)IPアドレスにブラウザでアクセスして、
のような画面が表示されれば、テストは成功です。
Herokuへのデプロイ
Heroku上にアプリを新規作成して、アプリをデプロイします。
$ heroku create Creating some-fake-1234... done, stack is cedar-14 https://some-fake-1234.herokuapp.com/ | https://git.heroku.com/desolate-lake-5348.git $ heroku docker:release --app=some-fake-1234 creating local slug... building image... Sending build context to Docker daemon ... uccessfully built 936664d30cff creating remote slug... uploading slug... releasing slug... $ heroku open --app=some-fake-1234
ブラウザにローカル環境でテストした時と同じ画面が表示されれば、デプロイ成功です。
データベースへの接続
データベースに接続する例です。Heroku Postgresの場合、はじめにプラグインを追加して、
$ heroku addons:create heroku-postgresql:hobby-dev --app=some-fake-1234
データベースの接続情報を環境変数(DATABASE_URL
)から取得するように設定を変更します。
config/prod.exs
config :hello_heroku, HelloHeroku.Repo, adapter: Ecto.Adapters.Postgres, url: System.get_env("DATABASE_URL")
さいごに
駆け足でDockerを使って、HerokuへPhoenixアプリをデプロイしてみました。Dockerを使う利点としては、
- Herokuと同じ実行環境で、ローカルでもアプリを実行できる。
- buildpackより、自由に実行環境を設定できる。
だと思います。Herokuを使っている、もしくは、興味ある方は、お試し下さい。