パパエンジニアのポエム

奥さんと娘ちゃんへの愛が止まらない

Dockerをインストール(Ubuntu)しGitHubと連携

公式サイトを参考にインストールする。

パッケージインストー

apt-getでDockerのインストールに必要なパッケージをインストール。

sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common

Docker公式GPG鍵追加

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

DockerのPPA追加

sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

Docker CE インストー

sudo apt-get update
sudo apt-get install docker-ce
sudo docker version

でversion確認すると↓のような出力。

Client:
 Version:      17.03.1-ce
 API version:  1.27
 Go version:   go1.7.5
 Git commit:   c6d412e
 Built:        Mon Mar 27 17:14:09 2017
 OS/Arch:      linux/amd64

Server:
 Version:      17.03.1-ce
 API version:  1.27 (minimum version 1.12)
 Go version:   go1.7.5
 Git commit:   c6d412e
 Built:        Mon Mar 27 17:14:09 2017
 OS/Arch:      linux/amd64
 Experimental: false

sudo 無しで docker を実行する

docker グループにユーザーを追加すればいい。
docker グループ存在確認。

cat /etc/group | grep docker

存在しなければ、作成。

sudo groupadd docker

現在のユーザーをdockerグループに追加する。

sudo gpasswd -a $USER docker

docker 再起動すればsudoなしでdockerコマンドを実行できる。
もし、permission deniedという警告が出たら下記実行。

sudo chown "$USER":"$USER" /home/"$USER"/.docker -R
sudo chmod g+rwx "/home/$USER/.docker" -R

docker-compose インストー

Releases · docker/compose · GitHub
ここで最新バージョンを確認し、下記実行。

sudo -i
curl -L "https://github.com/docker/compose/releases/download/1.14.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

バージョンを確認して完了。

docker-compose version

Docker Hub に登録して GitHubと連携させる

https://hub.docker.com/
Docker Hubにアカウントを新規作成し、DockerfileのAutomated Buildを設定する。
Automated Buildとは、Dockerイメージの元となるDockerfileをDocker Hubのビルドクラスターに読み込ませ、
Dockerイメージを作成、Docker Hubリポジトリで公開する仕組み。
これで対象のGitHubリポジトリが更新されたら自動でDockerイメージが作成される。
いまさら聞けないDocker入門(終):Docker Hubの使い方とGitHubからのDockerイメージ自動ビルド (2/2) - @IT

Dockerfile

力尽きたので次回。
Dockerでの環境構築が整ったら、EC2にデプロイする。

UbuntuでgitをセットアップしGitHubにプッシュする

さくっとGitHubにプッシュする。

最新のGitを使えるようにする

Ubuntuで最新のGitを使用できるようにするために、
git ppaリポジトリに追加する。

$ sudo add-apt-repository ppa:git-core/ppa
$ sudo apt-get update
$ sudo apt-get upgrade

これで最新のGitを使えるようになる。

Git Config設定

Gitの初期設定を行う。

git config --global user.name "YukiToida"
git config --global user.email "y.toidax@gmail.com"

Config確認。

git config --list
user.name=YukiToida
user.email=y.toidax@gmail.com

と表示されればおk。

SSH Key 作成

ssh-keygen

./ssh/id_rsa.pubが作成されるので github に登録する。

GitHubへプッシュ

いつも先にブラウザからリポジトリを作成してcloneする方法をとっている。
.gitignore の追加とか楽なので。
対象フォルダにcloneする。

git clone git@github.com:yuki-toida/stock_scraping.git

add して commit して push する。

git add .
git commit -m "initial commit"
git push -u origin master

GitHub - yuki-toida/stock_scraping
これで完了。

Elixir - Phoenixで株価を表示する(後編)

前回の続き。
今回は、Volume(日別出来高ランキング)ページを実装する。

VolumeController

引数に受けた文字列をDateにキャストする。
その値を使いDBからデータを取得する。
ポイントは where句ではピン演算子を使うこと。
んでそのままテンプレートに@itemsとして渡す。
web/controllers/volume_controller.exが以下。

defmodule StockScraping.VolumeController do
  use StockScraping.Web, :controller

  def index(conn, %{"date" => date}) do
    target_date = case Date.from_iso8601(date) do {:ok, value} -> value end
    items = StockScraping.YahooVolume |> where(date: ^target_date) |> Repo.all
    render conn, "index.html", items: items
  end
end

VolumeView

ヘルパーは今のところ使用していないので、デフォルトのまま。
web/views/volume_view.exが以下。

defmodule StockScraping.VolumeView do
  use StockScraping.Web, :view
end

VolumeTemplate

コントローラーから受け取った@itemsレンダリングする。
web/templates/volume/index.html.eexが以下。

<h3>出来高増加率ランキング</h3>
<ul>
  <%= for item <- @items do %>
    <li>
      <%= item.ranking %> - <%= item.name %>
    </li>
  <% end %>
</ui>

これで一旦表示出来た。
この時点で月別カレンダーと日別出来高ランキングが表示されるようになった。

Elixir - Phoenixで株価を表示する(前編)

MySQLに入っている株価データを表示する。
ページ構成としてはHome(月別カレンダー)とVolume(日別出来高ランキング)の2つ。
今回はHomeだけ。

Routing

ルーティングでのポイントは、HomeControllerへのルートは引数有り無しのに種類用意すること。
web/router.exが以下。

defmodule StockScraping.Router do
  use StockScraping.Web, :router

  pipeline :browser do
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_flash
    plug :protect_from_forgery
    plug :put_secure_browser_headers
  end

  scope "/", StockScraping do
    pipe_through :browser

    get "/", HomeController, :index
    get "/:date", HomeController, :index

    get "/volume/:date", VolumeController, :index
  end
end

HomeController

ここでは引数で受けた文字列をDateにキャストしている。
引数がない場合は、現在時刻を使用する。
(キャスト方法は本当にこれであってるんだろうか…)

render conn, "index.html", items: itemsとすることでテンプレートで@itemsを参照可能になる。
web/controllers/home_controller.exの最終形が以下。

defmodule StockScraping.HomeController do
  use StockScraping.Web, :controller

  def index(conn, params) do
    target_date = case params do
      %{"date" => date} -> case Date.from_iso8601(date) do {:ok, value} -> value end
      _ -> now()
    end

    items = Repo.all(StockScraping.YahooVolumeDate)
      |> Enum.filter(fn(x) ->
        x.date.year == target_date.year
        && x.date.month == target_date.month
      end)

    render conn, "index.html", items: items
  end
end

HomeView

ViewへはDateをstringに変換する関数を作成し、テンプレートから呼び出す。
あえてパターンマッチングで実装してみた。
web/views/home_view.exが以下。

defmodule StockScraping.HomeView do
  use StockScraping.Web, :view

  def convert(date) do
    case Timex.format(date, "{YYYY}-{0M}-{D}") do {:ok, value} -> value end
  end
end

HomeTemplete

UIおいといてとりあえず表示させる。
ポイントはvolume_path(@conn, :index, convert(item.date))
VolumeControllerのIndexアクションへのURLをクエスパラメータ付きでレンダリングする処理。
Routingのget "/volume/:date", VolumeController, :indexでルートを追加しないと例外でる。

<h3>カレンダー</h3>
<ul>
  <%= for item <- @items do %>
    <li>
      <a href="<%= volume_path(@conn, :index, convert(item.date)) %>"><%= item.date %></a>
    </li>
  <% end %>
</ul>

これで一旦株価を更新した日付の一覧を表示できた。

Elixir - Phoenixでページを作成する

今回はページを作成していく。
Routing Action View Templateを理解する。

Routing

web/router.exHomeControllerを追加する。

defmodule StockScraping.Router do
  use StockScraping.Web, :router

  pipeline :browser do
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_flash
    plug :protect_from_forgery
    plug :put_secure_browser_headers
  end

  scope "/", StockScraping do
    pipe_through :browser
    get "/", HomeController, :index
  end
end

Action

HomeControllerを追加する。
web/controllers/home_controller.exを新規作成。

defmodule StockScraping.HomeController do
  use StockScraping.Web, :controller

  # connはPlug.Conn構造体
  def index(conn, _params) do
    render conn, "index.html"
  end
end

View

Viewはヘルパー関数みたいなものらしい。
web/views/home_view.exを追加する。

defmodule StockScraping.HomeView do
  use StockScraping.Web :view

  def title do
    "株出来高増加率ランキング"
  end
end

あえてtitleという関数を定義している。
これでテンプレートで使用可能となる。

Template

HTMLテンプレートのこと。
web/templates/home/index.html.eexを新規追加。
HomeViewに追加したtitle/0を呼び出す。

<p><%= title %></p>

webサーバーを起動させる。

mix phoenix.server

http://localhost:4000 にアクセスするとtitleのみが表示される。

Elixir - Phoenixのセットアップ

このブログで書いたように、
Elixir習得のために作り始めた株価スクレイピングアプリは当初データ収集のみの想定だった。
でも思いの外気合のみで作れてしまい、まるで言語を習得できていないのでWebアプリにしようと思う。
定期的にデータをスクレイピングし、それをHTMLで表示するアプリをAWSで運用する。

ElixirでWebアプリといったら Phoenix らしい。
にしても作者完全にFF好きだな、ElixirPhoenixて。

Phoenix のインストー

Installation · Phoenix

Hex のインストー

mix local.hex

Phoenix のインストー

mix archive.install https://github.com/phoenixframework/archives/raw/master/phoenix_new.ez

node と npm のインストー

sudo apt-get install -y nodejs npm

sudo npm cache clean
sudo npm install n -g

sudo n stable
sudo ln -sf /usr/local/bin/node /usr/bin/node

# 古いnodejs npm削除
sudo apt-get purge -y nodejs npm

inotify-tools のインストー

Linuxのみ inotify-tools をインストールする必要があるらしい。

sudo apt-get install inotify-tools

MySQL の設定

Using MySQL · Phoenix
databaseオプションをmysqlにしphoenixプロジェクト作成。

mix phoenix.new stock_scraping --database mysql

configファイルを編集

config/dev.exsconfig/test.exsconfig/prod.secret.exsを、
自分のMySQLの環境に合わせて修正する。

config :stock_scraping, StockScraping.Repo,
  adapter: Ecto.Adapters.MySQL,
  database: "stock_scraping",
  username: "ytoida",
  password: "",
  hostname: "localhost",
  port: 3306,
  pool_size: 10

Repo の作成

コンパイルして、StockScraping.Repoを作る。

mix do deps.get, compile
mix ecto.create

Webサーバー起動

ここまできたらWebサーバーを起動できるはず。
起動してみる。

mix phoenix.server

すると、

[info] Running StockScraping.Endpoint with Cowboy using http://localhost:4000
12 Jun 17:20:46 - info: compiled 6 files into 2 files, copied 3 in 3.8 sec

と出力された。
どうやら http://localhost:4000 でアクセス出来るらしい。
Chromeからアクセスして、Welcomeページ出たらOK牧場

MySQL(Local)をエクスポートしMySQL(AWS)にインポートする

環境が整ったので、LocalのあるMySQLのデータをAWSに移行する。

MySQL(Local)エクスポート

mysqldumpコマンドを実行すると実行ディレクトリにエクスポートファイルが作成される。
さっそくコマンドを実行。

mysqldump -u[ユーザー名] -p[パスワード] -r [バックアップファイル名] --single-transaction [データベース名]

エクスポートファイルをEC2に転送

scpコマンドで転送する。
これでルートディレクトリにエクスポートファイルが転送される。

chmod 400 ec2.pem

scp -i ec2.pem [ファイル名] [EC2ユーザー]@[EC2ホスト]:~

MySQLAWS)インポート

さきほど転送されたエクスポートファイルをインポートする。

mysql -u[ユーザー名] -p[パスワード] -h[ホスト] [データベース名] < [エクスポートファイル名]

あとはMySQLにログインして対象データベースがインポートされているか確認してみる。