LoginSignup
2

More than 5 years have passed since last update.

Phoenixを使ってChatをHerokuにたててみた

Last updated at Posted at 2018-09-03

sing-up! https://chat.syui.cf, @syui@syui.cf

status : https://cachet.mybluemix.net

introduction

この前、chat(チャット)立てたいという話を耳にしたので、1,2時間ほどでherokuのほうに立ててみました。ちょっと調べたりしました。

$ git clone https://github.com/dwyl/phoenix-chat-example

$ cd !$:t

$ heroku create $APP_NAME

$ rm -rf .git

$ heroku git:remote -a $APP_NAME 

$ echo "erlang_version=20.1
elixir_version=1.6.0
always_rebuild=false
runtime_path=/app
" >> elixir_buildpack.config

$ echo "web: MIX_ENV=prod POOL_SIZE=2 mix ecto.migrate && mix phx.server" >> Procfile

$ vim config/prod.exs
config :chat, ChatWeb.Endpoint,
  load_from_system_env: true,
  url: [scheme: "https", host: "syui-chat.herokuapp.com", port: 443],
  force_ssl: [rewrite_on: [:x_forwarded_proto]],
  cache_static_manifest: "priv/static/cache_manifest.json",
  secret_key_base: Map.fetch!(System.get_env(), "SECRET_KEY_BASE")

$ mix deps.get
$ mix phx.gen.secret
XXX
$ heroku config:set SECRET_KEY_BASE="XXX" -a $APP_NAME
$ heroku addons:create heroku-postgresql:hobby-dev -a $APP_NAME
$ heroku buildpacks:set https://github.com/HashNuke/heroku-buildpack-elixir.git -a $APP_NAME
$ heroku buildpacks:add --index 2 https://github.com/gjaldon/heroku-buildpack-phoenix-static.git -a $APP_NAME

$ echo mix.lock >> .gitignore
$ git add .
$ git commit -m "first"
$ git push heroku master

参考 :

phx:exchat

今度は、login機能をつけたり、notifyとしてmail通知を実装したりしてみました。

少し機能多めのchatでもと思ってherokuにたててみました。

これは、tony612/exchatを使いますが、login機能が付きます。あくまでexampleっぽいsrcになっていますね。(多分、example-chatの略, slackを参考)

iconの取得はmailからgravatar.comを使ってるんじゃないですかね(知りませんが)。コード読めという話ですね。

さて、ではrepoのcloneからいきましょー。今回もexample-chatみたいな感じのやつです。

$ git clone https://github.com/tony612/exchat

$ cd !$:t

$ cat ./elixir_buildpack.config
erlang_version=20.1
elixir_version=1.6.0
always_rebuild=true
config_vars_to_export=(DATABASE_URL JWT_SECRET)

$ cat ./Procfile
web: MIX_ENV=prod POOL_SIZE=2 mix ecto.migrate && mix phoenix.server


$ heroku buildpacks:set https://github.com/HashNuke/heroku-buildpack-elixir.git -a $APP_NAME
# npm i
$ heroku buildpacks:add --index 2 https://github.com/gjaldon/heroku-buildpack-phoenix-static.git -a $APP_NAME

見た感じ、front-endには、react, redux, bootstrapを使っていて、割としっかりしている印象です。

heroku config:setには、DATABASE_URL, JWT_SECRET, SECRET_KEY_BASEを入れてください。と言っても、DATABASE_URL, PORTはpostgresを入れれば勝手に生成されると思うので、JWTとKEYですね。値は、$ mix phx.gen.sercetの結果になります。

$ mix phx.gen.sercet
123
$ heroku config:set JWT_SECRET=123 -a $APP_NAME
$ heroku config:set SECRET_KEY_BASE=123 -a $APP_NAME

notify:mail

通知の手段は色々あるんですけど、mailが簡単そうなので、まずは簡単そうなものから。

mix.exs
applications: [:bamboo]

defp deps do
  [{:phoenix, "~> 1.3.3"},
   {:bamboo, "~> 1.0.0"},
   {:bamboo_smtp, "~> 1.5.0"}
  ]
config/prod.ex

config :exchat, Exchat.Mailer,
       adapter: Bamboo.SMTPAdapter,
       server: "smtp.gmail.com",
       port: 587,
       username: System.get_env("GMAIL"),
       password: System.get_env("GMAIL_APP_PASS"),
       tls: :if_available, # can be `:always` or `:never`
       ssl: false, # can be `true`
       retries: 1

これに関しては、mailgunとかを使うのが通常なんだけど、demoなのでgmailで。

lib/mailer.ex
defmodule Exchat.Mailer do
  use Bamboo.Mailer, otp_app: :exchat
end
lib/mail.ex
defmodule Exchat.Email do
  use Bamboo.Phoenix, view: Exchat.EmailView

  def hello_email(email) do
    new_email
    |> to(email)
    |> from("support@xxx.herokuapp.com")
    |> subject("login")
    |> text_body(".")
  end
end

userがloginしたらmailを送信するようにする。これによって、管理者は送信メールが出るので、それを通知すればいいかな。

web/controllers/api_auth.ex

  def login_by_email_pass(conn, email, pass, opts) do
    repo = Keyword.fetch!(opts, :repo)
    user = repo.get_by(User, email: email)

    cond do
      user && checkpw(pass, user.password_hash) ->
    Exchat.Email.hello_email(user.email) |> Exchat.Mailer.deliver_now
        {:ok, login(conn, user)}
      user ->
        {:error, :unauthorized, conn}
      true ->
        dummy_checkpw()
        {:error, :not_found, conn}
    end
  end

実際、loginしてみてmailをcheckしてみる。確認できたなら、コードを変更。

DMやmessageが来た時も通知したければこんな感じでやってくとよさそう。

というかメールの通知は色々とつらい。普通はやらないと思うので、ravenx / slackとか使うのがいいんでしょうか。

notify:mailgun

一応、mailgunの書き方も掲載しておきます。

mailgun: 使用する上での注意点としては、freeの場合は、sandboxでしかapi/v3からmailの送信はできません。しかも、認証済みのmail addressにしか送れず、よって、lib/mail.exを書き換えて、to:verify-email, from:sandbox.domain, text_body:emailというようにしなければなりません。つまり、login userに送信(通知)するのではなく誰かがloginした時に管理者に通知する役割しか担えませんので注意です。freeでない場合はapiから普通に送れますので大丈夫ですが。

# In config/config.exs, or config.prod.exs, etc.
config :my_app, MyApp.Mailer,
  adapter: Bamboo.MailgunAdapter,
  api_key: "my_api_key",
  domain: "your.domain"

mailgun(MailgunAdapter)を使う場合のnew_emailの値はこちらを参考に。

$ curl -s --user 'api:YOUR_API_KEY' \
    https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages \
    -F from='Excited User <mailgun@YOUR_DOMAIN_NAME>' \
    -F to=YOU@YOUR_DOMAIN_NAME \
    -F to=bar@example.com \
    -F subject='Hello' \
    -F text='Testing some Mailgun awesomeness!'

frontend

今度は、exchatのfrontendの内容になります。

heorkuでは、通常、/app, /webにわけられdeployされます。

なので、phxのようなbackendの成否とreactのようなfrontendの成否は基本的に別々になっています。

つまり、phxのdeployは正常に成功したけど、webpackが失敗して、/webがうまく表示できないなんてこともありえます。

exchatは、backendをelixir(phoenix)で構成し、frontendは、react, reduxなどで構成しているようです。

ここで、frontend(js)のpreview, build, convertなどには、webpack, babelなどを使用しているようです。

buildされたものは、./priv/static/app.jsに置かれるようですね。しかし、.gitignoreに書かれていますので、pushしません。

$ cat webpack.config.js

$ mix deps.get

$ npm i

$ webpack

$ cat ./priv/static/app.js

$ mix phx.server

layoutを変えるには、./web/templates/layoutからhtml:headより上をいじることもできますが、基本的には、./client/以下を触ります。これらは、webpackを使ってbuildされます。

./config/dev.exsを見ることで、どのようにpreviewされるのかわかります。

riotを触ってた頃、たまたまwebpackも使ってた気がするんですけど、もう忘れてる。

なお、cloudflare, herokuとかを利用してる場合、cacheなどが効いてるので、今回生成されるようなapp.jsみたいな一箇所に詰め込まれたファイルというのは、特に、なかなか反映されないことがあります。これは、purgeをするとか、もしくはherokuapp.comで確認するとかしたほうがいいわけですが、それでも反映するまでにしばらく時間がかかることが多いです。browserのprivate windowを利用しても同じ。frontendはこのあたり、大変ですね。あくまで初見の印象ですが。

$ heroku plugins:install heroku-repo
$ heroku repo:purge_cache

previewは、$ bash ./compileしたあとに、$ mix phx.serverします。-> localhost:4000

色々なパッケージをupdateしてみました。

詳しくはこちらの記事を読んでください。

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
2