Docker×Python×Oracle-CloudでLINE Botを作ってみた。 #2

## はじめに
Flask×PythonでBotのアルゴリズムを作り、dockerの乗せてリモートサーバ稼働させる流れをまとめたものです。

[第1回(前回)](https://qiita.com/kuroneko-hornet/private/3743d9f83ed19b745a0c)は、
python3の記述までの内容を扱いました。

今回は、
Dockerfileの作成からリモートサーバでのデプロイまでの内容を扱います。

<a id="index"></a>  
## 目次
- [目次](#index)
- [実装環境と条件](#anchor1)
- [Docker](#anchor2)
- [リモートサーバ](#anchor3)
- [Webhookの設定](#anchor4)
- [tmux](#anchor5)

<a id="anchor1"></a>
## 実装環境</a>
**環境**

- MacOS X 10.13.6 (local)
- Docker 18.09.2

<a id="anchor2"></a>
## Docker</a>
`{$PWD}/Dockerfile`を作成します。

```Dockerfile:Dockerfile
# ベースとなるイメージを指定する
FROM ubuntu:latest

# コンテナ上のワーキングディレクトリを指定する
WORKDIR /usr/src/

# ディレクトリやファイルをコピーする
# 左側がホストのディレクトリ、右側がコンテナ上のディレクトリ
COPY ./src /usr/src
COPY ./startup.sh /startup.sh

# "docker build"時に実行される処理
RUN apt-get update
RUN apt-get install python3 python3-pip -y
RUN pip3 install flask
RUN pip3 install line-bot-sdk
RUN pip3 install python-dotenv
RUN chmod 744 /startup.sh
RUN echo "building..."

# "docker run"実行時に実行される処理
CMD /startup.sh
```

また、docker runでstartup.shを実行しますが、内容はこんな感じです。

```bash:startup.sh
# 日本語扱えるようにする
export LC_CTYPE=C.UTF-8
# flask run!!
python3 /usr/src/app.py
```

<a id="anchor3"></a>
## リモートサーバ
以下のコマンドを実行します。
これからはリモートサーバでの作業になります。

```bash:
$ scp . user@server:~/
$ ssh user@server:~/docker-bot

$ (sudo) docker build -t bot .
# 割と時間かかる
```

これで、dockerの準備は完了です。
あとはLINEサーバとの接続と docker run すればbotが動きそうです。

<a id="anchor4"></a>
## Webhootの設定
LINEサーバとの接続をするためには、Webhookの設定をする必要がありますが、https通信以外は弾かれてしまいます。
その打開策として、今回は**ngrok**を使います。
参考: [ngrokが便利すぎる](https://qiita.com/mininobu/items/b45dbc70faedf30f484e)

ngrokを実行(`{ngrok directory}/ngrok http {port}`)すると以下のような画面が表示されます。
Forwardingのhttpsのアドレス(この場合は`ad19992.a.ngrok.io`)をあとで使います。
また、このアドレスはngrokを実行するたびに**ランダムで変更**されます。

```sh:ngrok
ngrok by @inconshreveable                      (Ctrl+C to quit)
                                                               
Session Status                online                           
Session Expires               7 hours, 59 minutes              
Version                       2.3.34                           
Region                        United States (us)               
Web Interface                 http://127.0.0.1:4040            
Forwarding                    http://ad19992a.ngrok.io -> http:
Forwarding                    https://ad19992a.ngrok.io -> http
                                                               
Connections                   ttl     opn     rt1     rt5     p
                              0       0       0.00    0.00    0
```                                                        

<a id="anchor5"></a>
## tmux
サーバ上ではdockerとngrokをマルチに開いておく必要があるので、今回は**tmux**を採用します。
参考: [tmuxを必要最低限で入門して使う](https://qiita.com/nl0_blu/items/9d207a70ccc8467f7bab)

```:tmuxで実現するイメージ
server
├ docker-run
└ ngrok
```

```bash:server
$ tmux new -s docker-run
$ (sudo) docker run -it --rm -p 8000:8000 bot

# ウィンドウからデタッチ
ctrl + b, d

$ tmux new -s ngrok
$ {ngrok directory}/ngrok http 8000
# line devloperの設定を行う
ctrl + b, d

# サーバからログアウトしてもdocker-run, ngrokは停止しない。
$ exit
```

LINE Devloperの
`「TOP > プロバイダーリスト > {プロバイダー名} > {botのアカウント名} > チャネル基本設定」`で、
メッセージ送受信設定の「Webhook送信」を「利用する」に変更した後、
Forwardingのhttpsのアドレスをコピーして、「Webhook URL」に貼り付けます。
最終的には Webhook URL が`https://ad19992.a.ngrok.io/callback`になるようにします。

以上で、botにラインを送った時の返信が変更されます。

## おわりに
ngrokとflaskはdocker-composeでまとめられそうだけど、docker-compose分からないので、その辺りは追々学ぼうと思いました。


# 参考
- [Dockerfileを書いてみる](https://qiita.com/nl0_blu/items/1de829288db2670276e8)
- [ngrokが便利すぎる](https://qiita.com/mininobu/items/b45dbc70faedf30f484e)
- [tmuxを必要最低限で入門して使う](https://qiita.com/nl0_blu/items/9d207a70ccc8467f7bab)