GAE(+CloudSQL)環境にElixir+Phoenixをデプロイして動かしてみるまで。


はじめに

Qiitaは読む専門でしたが、投稿してみることにしました。よろしくお願い致します。

会社で開発合宿があり、GCPについて初めて触れる機会がありました。
折角なので、GoogleAppEngine+CloudSQL環境にElixir+Phoenixをデプロイしてみようと思います。

私と同様に、以下のような方を対象としています。
 ・Elixir+Phoenixを使い始めた!
 ・GCPという響きにあこがれている!!
 ・とりあえず、GCPのアカウントは作成している!!!

では、やっていきましょう!!!

GCPの新規プロジェクトを作成

・GCPのダッシュボードから「新しいプロジェクト」を押します。

・プロジェクト名を決めて、作成ボタンを押します。

これだけでプロジェクトは作成出来ます!簡単ですね!!

GoogleCloudSDKのインストール・初期化

 デプロイ等に利用します!!
 https://cloud.google.com/sdk/docs/?hl=ja
 公式サイトをみてインストールします。

CloudSQLのインスタンス作成

・ダッシュボードのハンバーガメニューからSQLを選びます。

・インスタンス作成を押して、データベースを選びます。

・インスタンスIDを決めて、作成ボタンを押します。

これだけでインスタンスは作成出来ます!超簡単ですね!!

ローカルからCloudSQLProxyを利用してCloudSQLに接続

ローカルから接続出来るって夢ですよね!

https://cloud.google.com/sql/docs/postgres/connect-admin-proxy?hl=ja
公式サイトをみてプロキシをインストールと設定を行います
※プロキシ開始は、TCPかUNIXソケットとありますが、今回はUNIXを利用します。

・プロキシ開始

sudo mkdir /cloudsql; sudo chmod 777 /cloudsql
./cloud_sql_proxy -dir=/cloudsql -instances=<INSTANCE_CONNECTION_NAME> -credential_file=<PATH_TO_KEY_FILE> &

・プロキシ接続

psql "sslmode=disable host=/cloudsql/<INSTANCE_CONNECTION_NAME> user=<USERNAME>"

・接続出来ることを確認します。

Password for user postgres:
psql (11.1, server 9.6.6)
Type "help" for help.

postgres=>

おお・・・ローカルからも接続出来ることが確認できました。

Elixirプロジェクト作成

・Elixirプロジェクトを作成していきます。

mix phx.new gae_cloudsql_ex_phx --no-brunch

config/dev.exs config/prod.secret.exsを修正します。※passwordとsocket_dir

config :gae_cloudsql_ex_phx, GaeCloudsqlExPhx.Repo,
  adapter: Ecto.Adapters.Postgres,
  username: "postgres",
  password: ※CloudSQLのユーザパスワード, 
  database: "gae_cloudsql_ex_phx_dev",
  socket_dir: "/cloudsql/<INSTANCE_CONNECTION_NAME>",
  pool_size: 10

・CloudSQLとの接続が確認できれば良いので、簡単にAPI作成します。

mix phx.gen.json Api Test tests subject:text

・実行後のメッセージに従って、 lib/gae_cloudsql_ex_phx_web/router.ex を編集します。

<略>
  scope "/", GaeCloudsqlExPhxWeb do
    pipe_through :browser # Use the default browser stack

    get "/", PageController, :index
    resources "/tests", TestController, except: [:new, :edit] # <- 追加
  end
<略>

・Migrateを実行し、CloudSQL上にDatabaseが作成されているか確認します。

mix ecto.migrate
Compiling 12 files (.ex)
Generated gae_cloudsql_ex_phx app
[info] == Running GaeCloudsqlExPhx.Repo.Migrations.CreateTests.change/0 forward
[info] create table tests
[info] == Migrated in 0.3s

・GCPの画面を確認

DataBaseが作成されていますね!

/templates/page/index.html.eexを修正し、DB登録・参照だけ実装します。
※DB接続が確認できればよいので、実装内容は自由です。

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
<div id="app">
  <h1>GetData</h1>
  <div v-for="result in results">
    <div>subject: {{ result.subject }}</div>
  </div>
  <h1>PostData</h1>
  <div>
    <input type="text" v-model="subject">
    <button v-on:click="onCreate">追加</button>
  </div>
</div>
<script>
  new Vue({
    el:'#app',
    data: {results: [], subject: ''},
    mounted() {
      this.getData()
    },
    methods: {
      getData: function() {axios.get('/tests').then( res => {this.results = res.data.data})},
      onCreate: async function() {await axios.post('/tests', {'test': {"subject": this.subject}})}
    }
  })
</script>

さぁ、次はデプロイしましょう!!

デプロイ準備

コミュニティチュートリアルを参考にしながら進めて行きます。
https://cloud.google.com/community/tutorials/elixir-phoenix-on-google-app-engine?hl=ja

・Distilleryを追加し、コマンド実行
mix.exs

<略>
  defp deps do
    [
      {:phoenix, "~> 1.3.4"},
      {:phoenix_pubsub, "~> 1.0"},
      {:phoenix_ecto, "~> 3.2"},
      {:postgrex, ">= 0.0.0"},
      {:phoenix_html, "~> 2.10"},
      {:phoenix_live_reload, "~> 1.0", only: :dev},
      {:gettext, "~> 0.11"},
      {:cowboy, "~> 1.0"},
      {:plug_cowboy, "~> 1.0"},
      {:distillery, "~> 1.5"} #<- 追加
    ]
  end
<略>
mix do deps.get, deps.compile
mix release.init

・構成ファイルも合わせて修正。
config/prod.exs

config :gae_cloudsql_ex_phx, GaeCloudsqlExPhxWeb.Endpoint,
  load_from_system_env: true,
  http: [port: System.get_env("PORT")],
  check_origin: false,
  server: true,
  root: ".",
  cache_static_manifest: "priv/static/cache_manifest.json"

・以下コマンドを入力しリリース準備します (一気にできる方法が知りたい)

MIX_ENV=prod mix ecto.create
MIX_ENV=prod mix ecto.migrate
MIX_ENV=prod mix release --env=prod

デプロイ

app.yaml を作成

env: flex
runtime: gs://elixir-runtime/elixir.yaml
runtime_config:
  release_app: <YOUR_APP_NAME>

beta_settings:
  cloud_sql_instances: <INSTANCE_CONNECTION_NAME>

・デプロイコマンド実行

gcloud app deploy
※ デプロイ対象プロジェクトを選ぶ場合は以下。
gcloud app deploy --project=<PROJECT>

・しばらく時間がかかるので、コーヒーでも飲みつつ、以下がでるまでまったりします。

Updating service [default] (this may take several minutes)...done.                                                                                                                                                          
Setting traffic split for service [default]...done.                                                                                                                                                                         
Deployed service [default] to [https://<YOUR_APP_NAME>.appspot.com]

You can stream logs from the command line by running:
  $ gcloud app logs tail -s default

To view your application in the web browser run:
  $ gcloud app browse --project=<YOUR_APP_NAME>

確認

・URLに接続します。

・適当にポストしてみます。

無事、登録出来ることが確認できました!!!

まとめ

今まで環境周りのことって難しい印象でいたんですが、
・GAE+CloudSQLの環境構築が簡単
・CloudSQLProxyでの接続が簡単
・デプロイもコマンド実行で簡単 ※時間かかるけど

GCPの場合だと、結構簡単に作れてしまうので、とても身近になった気がしました。