パパエンジニアのポエム

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

Cloud SQLを構築してローカルからアクセスする

なにはともあれCloudSQLインスタンスを作成する

インスタンスを作成する  |  Cloud SQL for MySQL  |  Google Cloud
一番安いケチケチインスタンスにする

データベース フラグを設定する  |  Cloud SQL for MySQL  |  Google Cloud
MySQLのフラグは下記にした(説明省略)

character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
default_time_zone=+09:00
general_log=0
log_output=TABLE
slow_query_log=1
log_queries_not_using_indexes=1
long_query_time=0.5

Cloud SQL Proxy を使用してローカルから接続する

Cloud SQL Proxy を使用して MySQL クライアントを接続する  |  Cloud SQL for MySQL  |  Google Cloud

Cloud SQL Proxyインストール

任意のフォルダでインストールする

wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64
mv cloud_sql_proxy.linux.amd64 cloud_sql_proxy
chmod +x cloud_sql_proxy

サービス アカウントを作成する

役割でCloud SQL クライアントを選択
f:id:yuki-toida:20170922135542p:plain
[新しい秘密鍵の提供]にチェックを入れ、Cloud SQL Proxyインストールフォルダにダウンロード

プロキシを起動する

インスタンス名と秘密鍵を指定してプロキシを開始する
proxy.shのようなシェルスクリプトがあると便利

#!/bin/sh

PORT=3306
INSTANCE="instance-name"
CREDENTIAL="credential.json"

./cloud_sql_proxy -instances=$INSTANCE=tcp:$PORT -credential_file=$CREDENTIAL
Listening on 127.0.0.1:3306 for instance-name
Ready for new connections

この出力がされたらプロキシが開始されている
mysqlクライアントなりSequel Pro なりでアクセスすればおk

mysql -u <USERNAME> -p --host 127.0.0.1

GCEにDockerでRedisサーバを構築する

GCE作成

VM インスタンスの作成と起動  |  Compute Engine ドキュメント  |  Google Cloud

開発環境は一番やすいインスタンスを作ればよろし

マシンタイプ:f1-micro(vCPU x 1、メモリ 0.6 GB)
CPU プラットフォーム:Intel Broadwell
OS:debian-9
ゾーン:asia-northeast1-a

GCEにローカルからSSH接続

gcloud compute ssh [INSTANCE_NAME]

これだけという衝撃の楽さ!!!
秘密鍵:/Users/[user]/.ssh/google_compute_engine.
公開鍵:/Users/[user]/.ssh/google_compute_engine.pub.
が初回に作られるはず

GCEにDocker CEをインストール

当然SSH接続しているGCE内で行う
https://docs.docker.com/engine/installation/linux/docker-ce/debian/#install-using-the-repositorydocs.docker.com

古いDockerをアンインストール

sudo apt-get remove docker docker-engine docker.io

aptパッケージ更新

sudo apt-get update

HTTPS経由でリポジトリを使用できるように必要なパッケージをインストールする

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

公式GPGキーを追加

curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg | sudo apt-key add -

指紋9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88の最後の8文字を検索して、指紋のあるキーがあることを確認

sudo apt-key fingerprint 0EBFCD88

リポジトリ追加

sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \
   $(lsb_release -cs) \
   stable"

Docker CEをインストール

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

バージョン確認

docker -v

Docker version 17.06.2-ce, build cec0b72
こんな感じで出力されるはず、これでインストール完了

sudo コマンドなしで docker コマンドを実行できるようにする

https://docs.docker.com/engine/installation/linux/linux-postinstall/#manage-docker-as-a-non-root-userdocs.docker.com
docker グループ作成

sudo groupadd docker

docker グループにユーザー追加

sudo usermod -aG docker $USER

GCEからログアウトしてログインし直せばsudoコマンドなしでdockerコマンドが実行できるはず

Redisコンテナ起動

optにredisのデータをマウントするのが良さげ

cd /opt
docker run --name redis -d -p 6379:6379 -v /redis/data:/data redis redis-server --appendonly yes

こんだけ
latestバージョンのredisコンテナが、ポート6379にホスティングされ、/redis/dataにデータは永続化される
dockerはほんと便利

Redisコンテナの動作確認

redis-toolsをインストール

sudo apt-get install redis-tools

redisサーバーに ping 投げてみる

redis-cli ping

PONG を出力されたらおk
これでGCEへのRedisサーバー構築完了

GCPコトハジメ

何はともあれプロジェクト作成

任意のプロジェクト名とグローバルで一意なプロジェクトIDをつける
開発環境と本番環境で分けるのがベストプラクティスらしい

本番環境での Container Engine の準備  |  ソリューション  |  Google Cloud

プロジェクト名:sample-dev
プロジェクトID:sample-dev
こんな感じでよい

Google Cloud SDK セットアップ(ユーザーアカウント認証)

ユーザーアカウント認証は主にローカルでの使用に使われるはず

Mac OS X 用のクイックスタート  |  Cloud SDK のドキュメント  |  Google Cloud

初期化

gcloud init

アカウントとプロジェクトを選択

Choose the account you would like to use to perform operations for 
this configuration:
 [1] hoge@candee.co.jp
 [2] Log in with a new account
Please enter your numeric choice:  1    

You are logged in as: [yuki.toida@candee.co.jp].

Pick cloud project to use: 
 [1] sample-dev
 [2] Create a new project
Please enter numeric choice or text value (must exactly match list 
item):  1

GCEのデフォルトゾーン選択

Which Google Compute Engine zone would you like to use as project 
default?
If you do not specify a zone via a command line flag while working 
with Compute Engine resources, the default is assumed.
 [1] asia-east1-c
 [2] asia-east1-b
 [3] asia-east1-a
 [4] asia-northeast1-b
 [5] asia-northeast1-a
 [6] asia-northeast1-c
 [7] asia-southeast1-a
 [8] asia-southeast1-b
 [9] australia-southeast1-c
 [10] australia-southeast1-a
 [11] australia-southeast1-b
 [12] europe-west1-d
 [13] europe-west1-c
 [14] europe-west1-b
 [15] europe-west2-c
 [16] europe-west2-b
 [17] europe-west2-a
 [18] europe-west3-b
 [19] europe-west3-a
 [20] europe-west3-c
 [21] southamerica-east1-b
 [22] southamerica-east1-a
 [23] southamerica-east1-c
 [24] us-central1-c
 [25] us-central1-f
 [26] us-central1-a
 [27] us-central1-b
 [28] us-east1-b
 [29] us-east1-c
 [30] us-east1-d
 [31] us-east4-b
 [32] us-east4-a
 [33] us-east4-c
 [34] us-west1-a
 [35] us-west1-c
 [36] us-west1-b
 [37] Do not set default zone
Please enter numeric choice or text value (must exactly match list 

Config確認

gcloud config list

問題なければセットアップ完了

Google Cloud SDK セットアップ(サービスアカウント認証)

サービスアカウント認証は主にデプロイサーバ等で使われるはず

Cloud SDK ツールの承認  |  Cloud SDK のドキュメント  |  Google Cloud

Google Cloud Platform Console の [Service Accounts] ページに移動します。

[SERVICE ACCOUNTS] ページに移動
[Create service account] をクリックするか、既存のアカウントを選択します。
サービス アカウントの表の [Options] 列にある [More] ボタン 鍵ファイルを作成する をクリックし、[Create key] を選択して、JSON 形式の鍵ファイルを作成してダウンロードします。

鍵ファイルを作成する
必要に応じて、Cloud SDK ツールを承認するシステム上の場所に鍵ファイルを移動します。
gcloud auth activate-service-account を実行します。

gcloud auth activate-service-account --key-file [KEY_FILE]
システムから鍵ファイルを削除します。

これでローカルマシンとデプロイマシンからgcloudコマンドを発行できる

MacにHomebrewとGitとDockerとGitHubをセットアップ

まずは隠しファイル/フォルダを表示する。

defaults write com.apple.finder AppleShowAllFiles TRUE
killall Finder

表示されているか確認。

Homebrewインストール

公式サイトに沿ってインストール。

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
brew doctor

Your system is ready to brew.

と表示されればおk。

Gitインストール

brew install git

git config設定。

git config --global user.name "YukiToida"
git config --global user.email "yuki.toida@candee.co.jp"

Dockerインストール

docs.docker.com
公式に沿ってStableをインストール。
その後起動する。

GitHubセットアップ

.sshフォルダに鍵を作成する。

cd
mkdir .ssh
ssh-keygen -t rsa

作成した公開鍵をGitHubに登録する。
おしまい。

EC2にDockerでElixir-Phoenixをデプロイする

EC2にDockerを使ってデータを表示するPhoenixアプリをデプロイする。

Phoenixのconfig設定

Producrion用のconfigを書き換える。
ポート4000にロードし、nginxでリバースプロシキさせる。
config/prod.exsが以下。

config :stock_scraping, StockScraping.Endpoint,
  http: [port: 4000],
  url: [host: "example.com", port: 4000]

Dockerfile作成

Phoenixを起動するDockerfileを作成する。
さっそく中身。

FROM elixir
MAINTAINER yuki-toida

RUN apt-get update

# hex
RUN mix local.hex --force && \
    mix local.rebar --force && \
    mix hex.info

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

# node npm
RUN apt-get install -y nodejs npm
RUN npm cache clean && npm install n -g
RUN n stable && ln -sf /usr/local/bin/node /usr/bin/node
RUN apt-get purge -y nodejs npm

# inotify-tools
RUN apt-get install -y inotify-tools

EXPOSE 4000

# git repository
RUN git clone https://github.com/yuki-toida/stock_scraping.git root/stock_scraping
WORKDIR /root/stock_scraping
RUN chmod +x run.sh
ENTRYPOINT ["./run.sh"]
CMD ["dev"]

Elixirの公式イメージを使って公式サイトの手順でPhoenixをインストール。
node.jsとnpmをインストールし、古いパッケージをパージ。
エントリーポイントをrun.shとする。以下。

#!/bin/bash

git reset --hard HEAD
git pull origin master

mix deps.get

npm install

MIX_ENV=$1 mix compile
MIX_ENV=$1 mix phoenix.server

環境変数にprodを設定すると、mix compileが必須になるのがポイント。

EC2にログインしDockerイメージをプルする

docker pull yukitoida/stock_scraping

Dockerコンテナを起動させる

docker run --net="host" yukitoida/stock_scraping prod

これでlocalhost:4000にPhoenixアプリがロードされてるはず。
前回、nginxの設定は終わってるので、リバースプロシキされるはず。
実際のURLがこちら。株カレンダー
なんというクソUI、気が向いたらUIをちゃんと作る。

AWS EC2 に nginx をインストールしリバースプロシキさせる

EC2でPhoenixアプリをグローバルに公開するための設定。

port80を公開する

EC2に適用しているセキュリティグループのインバウンドルールに下記を追加。

タイプ プロトコル ポート範囲 送信元
HTTP TCP 80 0.0.0.0/0

これでポート80をグローバルに公開できる。

nginxのインストー

パッケージ情報確認。

sudo yum info nginx

読み込んだプラグイン:priorities, update-motd, upgrade-helper
利用可能なパッケージ
名前                : nginx
アーキテクチャー    : x86_64
エポック            : 1
バージョン          : 1.10.2
リリース            : 1.30.amzn1
容量                : 534 k
リポジトリー        : amzn-main/latest
要約                : A high performance web server and reverse proxy server
URL                 : http://nginx.org/
ライセンス          : BSD
説明                : Nginx is a web server and a reverse proxy server for HTTP, SMTP, POP3 and
                    : IMAP protocols, with a strong focus on high concurrency, performance and low
                    : memory usage.

↑のように表示されていれば利用可能なので、インストール。

sudo yum install nginx

インストールされたか確認。

nginx -V

built by gcc 4.8.3 20140911 (Red Hat 4.8.3-9) (GCC) 
built with OpenSSL 1.0.1k-fips 8 Jan 2015

nginx を起動する

sudo nginx

プロセスを確認。

ps -ef | grep nginx

root      9069     1  0 17:43 ?        00:00:00 nginx: master process nginx
nginx     9070  9069  0 17:43 ?        00:00:00 nginx: worker process
ec2-user  9072  8991  0 17:43 pts/0    00:00:00 grep --color=auto nginx

起動している。
EC2のパブリックIPでアクセスできるか確認する。
nginxのデフォルトページが表示されたらおk。

nginx 自動起動設定

sudo service nginx start
sudo chkconfig nginx on
sudo chkconfig --list nginx

nginx           0:off   1:off   2:on    3:on    4:on    5:on    6:off

これで自動起動設定完了。

nginx config 設定

Phoenixlocalhost:4000をリッスンしている。
それを[パブリックIP]:80でリバースプロシキ。
/etc/nginx/conf.d/local.confが以下。

upstream phoenix {
  server localhost:4000 max_fails=5 fail_timeout=5s;
}

server {
  listen 80;
  server_name [パブリックIP]

  location / {
    allow all;

    # Proxy Headers
    proxy_http_version 1.1;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-Cluster-Client-Ip $remote_addr;

    # The Important Websocket Bits!
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";

    proxy_pass http://phoenix;
  }
}

パブリックIP文字列が長すぎてハッシュ化出来ないと nginx に怒られたので、 /etc/nginx/nginx.confに下記追加。

server_names_hash_bucket_size 128;

これで準備完了。
あとはPhoenixをデプロイして、Dockerコンテナ内でlocalhost:4000でアプリをホストすればいけるはず。
次回やる。

AWS EC2 にcronを設定し定期的にDockerコンテナを実行する

東京株式市場は15時大引けなので毎日18時に実行するよう設定する。

EC2にDockerをインストー

# パッケージ更新
sudo yum update -y

# dockerインストール
sudo yum install -y docker

# dockerサービス起動
sudo service docker start

# ec2-user を dockerグループに追加しsudoなしで実行できるように
sudo usermod -a -G docker ec2-user

Dockerイメージをプル

イメージをプルして、コンテナ実行ファイルを作成する。

docker pull yukitoida/stock_scraping_batch

以下実行ファイル/home/ec2-user/docker/run-batch.sh

#!/bin/sh/

docker run --rm --net="host" yukitoida/stock_scraping_batch prod

cron を設定する

crontab -eコマンドを実行する。

MAILTO=""
DIR="/home/ec2-user/docker"
00 18 * * 1-5 /bin/bash $DIR/run-batch.sh > $DIR/logs/`date +\%Y\%m\%d_\%H\%M\%S`.log

MAILTO=""にすることで実行後メールを無効化する。
その代わりに、ファイル名を日付にしログを残す。
crontab -lで登録内容を確認する。

これで平日18時に株価をスクレイピングしてMySQLに保存できるようになる。