Blow Up by Black Swan

エックスサーバに簡単なDashアプリをデプロイしてみる

今回は、エックスサーバでPythonのWEBアプリケーションフレームワークDashで作った簡単なアプリをデプロイする方法をまとめています。以前作成したPUSH通知型の大数の法則アプリのデプロイについては現在目下挑戦中ですので、そちらもうまくいけばまとめたいと思います。

ローカル環境で利用するのとは若干異なる点があるので、その点も記載しています。Dashの使い方については、以前まとめましたので、参考にして頂ければ幸いです。

1. ベース環境と全体の流れ

前提となる環境は以下になりますが、構築方法は省略しているので、代わりに参考サイトと注意点を記載しています。なお、2018年12月現在の状況ですので、将来的にサーバ環境や各種状況が変わることで記載の方法が役に立たないことも考えられますので、その点は注意頂ければと思います。

今回の構築の流れは以下になります。単元ごとの流れとその単元内の実行手順のを記載していますので、流れがわかりにくくなった場合は参照頂ければと思います。

  1. 必要なパッケージをインストール
    • インストールパッケージ: dash, dash-core-components, dash-html-componens, dash-renderer
    • 実行手順: (1)dash関連パッケージの確認 -> (2)condaでdashアプリの検索 -> (3)他のチャンネルでdash関連パッケージの検索 -> (4) チャンネルの追加 -> (5)dash関連パッケージのインストール
  2. dashアプリのデプロイ
    • 実行手順: (1)テストフォルダの作成 -> (2)3つのデプロイファイルの作成 -> (3)URLにアクセス

2. 必要なパッケージをanaconda環境にインストール

まずは、dashアプリをデプロイするための環境を構築していきます。以下のパッケージをインストールしていきます。

  • dash(0.30.0)
  • dash-core-components(0.38.0)
  • dash-html-components(0.13.2)
  • dash-renerer(0.15.1)

anacondaのデフォルトフォルダにdash関連パッケージが入っていないことは既にわかっているのですが、実際に私が行なった流れに沿ってまとめていますので、確認の方法から記載しています。

2-1. dash関連パッケージの確認

まず、dash関連パッケージがanacondaにインストールされているか確認します。

$ conda list

このコマンドを実行すると、インストールされているパッケージの一覧が表示されます。この一覧に該当するパッケージはない場合、dash関連パッケージがインストールされていないことを意味します。

2-2. condaでdashアプリの検索

dash関連パッケージがcondaで指定されたチャンネルからインストールできるか確認します。

$ conda search dash

戻り値

PackagesNotFoundError: The following packages are not available from current channels:

(デフォルトで指定されたチャンネル群)

上記のエラーは、デフォルトで指定されているチャンネルの中には、dash関連パッケージがないことを示しています。anacondaのチャンネルは一般的に言うリポジトリとほぼ同じものだと言えそうですが、anacondaでの呼称に沿ってチャンネルと呼んでいます。anacondaのパッケージ管理関連の構造については、この章の最後に記載していますので、そちらを確認頂けるとわかりやすいかなと思います。

2-3. 他のチャンネルでdash関連パッケージの検索

デフォルトのチャンネルではdash関連パッケージが存在しないため、dash関連パッケージを持っているチャンネルを確認します。

$ anaconda search -t conda dash

上記コマンドは、「condaタイプのdashパッケージがanaconda cloudにあるか検索する」という意味です。-tはパッケージタイプを指定するオプションです。以下は、上記コマンドの実行結果の一部になります。

Using Anaconda API: https://api.anaconda.org
Packages:
     Name                      |  Version | Package Types   | Platforms       | Builds    
     ------------------------- |   ------ | --------------- | --------------- | ----------
     IzODA/jupyter-dashboards  |    0.6.1 | conda           | zos-z           | py36_0    
     IzODA/jupyter-dashboards-bundlers |    0.8.1 | conda           | zos-z           | py36_0    
     ODSP-TEST/jupyter-dashboards |    0.6.1 | conda           | zos-z           | py37_0, py36_0
     ODSP-TEST/jupyter-dashboards-bundlers |    0.8.1 | conda           | zos-z           | py37_0, py36_0
     anaconda/jupyter_dashboards_bundlers |    0.9.1 | conda           | linux-ppc64le, linux-64, win-32, osx-64, linux-32, win-64 | py37_1, py27_1, py34_0, py36_1, py36_0, py27_0, py35_0
                                          : An add-on for Jupyter Notebook
     auto/asdoc2dash           |    0.1.1 | conda           | linux-64, linux-32 | py27_0    
                                          : https://github.com/ton1517/asdoc2dash
     auto/cartodb_dashboard    |    0.2.2 | conda           | linux-32        | py27_0    
                                          : Provides access to the cartodb dashboard
     auto/dashboardmods        |      1.0 | conda           | linux-64, linux-32 | py27_0    
                                          : https://github.com/callowayproject/dashboardmods

・・・(省略)・・・

     auto/psdash               |    0.1.0 | conda           | linux-64        | py27_0    
                                          : https://github.com/Jahaja/psdash
     auto/python-dash          |    0.0.1 | conda           | linux-64        | py27_0    
                                          : https://github.com/tony-zh/python-dash
     auto/python-graphite-dashgen |    0.1.1 | conda           | linux-64        | py27_0    
                                          : https://github.com/ClockworkNet/graphite-dashgen
     conda-forge/dash          |   0.30.0 | conda           | noarch          | py_0, py_1
                                          : A Python framework for building reactive web-apps.
     conda-forge/dash-core-components |   0.38.1 | conda           | noarch          | py_0, py_1
                                          : Dash UI core component suite
     conda-forge/dash-html-components |   0.13.2 | conda           | noarch          | py_0      
                                          : Dash UI HTML component suite
     conda-forge/dash-renderer |   0.15.1 | conda           | noarch          | py_0, py_1
                                          : Front-end component renderer for dash
     conda-forge/doc2dash      |    2.2.0 | conda           | noarch          | py_0      
                                          : Convert docs to Dash.app
     conda-forge/fludashboard  |    0.4.0 | conda           | linux-64, win-32, win-64, osx-64 | py36_1, py36_0, py35_0, py35_1
                                          : Interactive dashboard for exploring influenza incidence data

・・・(省略)・・・

     travis/emdash             |    2.2b5 | conda           | linux-64        | py27_0    
                                          : http://blake.grid.bcm.edu/emanwiki/EMEN2/
Found 54 packages

Run 'anaconda show ' to get installation details

この実行結果から、dash関連パッケージが、「conda-forge」というチャンネルに存在することがわかります。

2-4. チャンネルの追加

次は、このcondaがパッケージを検索するチャンネル群の中に、この「conda-forge」チャンネルを追加します。

$ conda config --append channels conda-forge   #conda-forgeチャンネルを追加

チャンネルが追加されているか確認

$ conda config --get channels

戻り値

--add channels 'conda-forge'   # lowest priority
--add channels 'defaults'   # highest priority

上記の結果から「conda-forge」チャンネルがcondaのチャンネルに追加されたことがわかります。highestとlowestは、検索の優先順位を表しており、デフォルのチャンネルから検索し、パッケージがない場合はconda-forgeを検索するということを意味します。

2-5. dash関連パッケージのインストール

最後にdash関連パッケージをインストールします。

$ conda install -y dash
$ conda install -y dash-core-components
$ conda install -y dash-html-components
$ conda install -y dash-renderer

これで必要なパッケージのインストールが完了し、dashアプリ実行の環境が整いました。

(参考) anacondaのパッケージ管理関連の構造

ここでは、参考までにanacondaのパッケージ管理関連の構造について、軽くまとめています。構造は、linuxのパッケージ管理モジュールyumやaptなどとほとんど同じと言えそうです。

デフォルトのリポジトリに基本的なパッケージを格納し、その他のサードパーティモジュールなどは、他のリポジトリに格納され、そのリポジトリをyumやaptコマンドなどの検索対象に追加することによって、サードパーティモジュールが入手できるようになるような構造です。

condaの利用イメージ

画像を見てもらえるとわかりやすいと思いますが、anacondaのパッケージ構造とその特徴は、以下のようになります。

  • パッケージ(モジュールやメソッドなどを格納)
  • チャンネル(様々なパッケージを格納するところ。リポジトリとほぼ同じ)
  • condaにはデフォルトのチャンネルが存在するが、新たにチャンネルを追加することもできる
  • 新たなチャンネルはサードパーティなどによって作られる
  • そのチャンネルがアップされる場所がanaconda cloud

このanaconda cloudを利用することによって、大体のモジュールはcondaを使ってインストールできるようです。エックスサーバの場合、通常のpipコマンドでは管理権限がないため利用できず、コードを一部書き換える必要があるようですが、anacondaを入れてしまえば、pipに頼らずに環境構築ができるのでかなり便利ではないかと思います。

参考までにanaconda cloundのリンクを貼っておきます。このサイトからもパッケージが格納されたチャンネルを調べることができます。

3. エックスサーバでのdashアプリの実行

以上で、簡単なdashアプリをデプロイするための環境が構築できました。次は、エックスサーバでdashアプリを実行していきます。

3-1. テストフォルダの作成

まず、実行用のテストフォルダを作成します。今回は、public_htmlの配下に以下の/dash/testフォルダを作成し利用しています。フォルダ作成後、そのフォルダに移動します。

$ mkdir ~/ユーザID.com/public_html/dash/test
$ cd ~/ユーザID.com/public_html/dash/test

3-2. 3つのデプロイファイルの作成

次にdashアプリの実行に必要な3つのファイルを作成します。

  • testDash.py
  • testDash.cgi
  • .htaccess
$ touch testDash.py testDash.cgi .htaccess

それぞれのファイルの記載内容は以下になります。

①testDash.py

import dash
import dash_html_components as html

app = dash.Dash(__name__)  #dashオブジェクト
server = app.server  #flaskオブジェクト

app.config.update({
    'routes_pathname_prefix': '',
    'requests_pathname_prefix': ''
})

app.layout=html.Div(children='Hello World!')

if __name__=='__main__':
    app.run_server(debug=False)

Dashではwebアプリケーションの基礎部分にflaskを利用しています。そのためサーバを構築するためにflaskオブジェクトを生成しています(server = app.server部分)。

しかし、このflaskとdashの2つのオブジェクトが成り立つ環境下では、flaskオブジェクト(実際にはその内部で利用されるwebサーバを取り扱うwsgirefモジュールと思われる)とdashオブジェクトでURL情報の理解に相違があり、ルーティングがうまく行かないため、URLパスの前提を揃える作業が必要なようです。

それが、app.config.update()処理の部分で、これがないとError loading layoutという表示がブラウザに出ます。ローカルホストでの実行では不要ですが、サーバへのデプロイでは必要なようです。この点については、以下のページを参考にしています。

②testDash.cgi
今回の簡単なアプリでは、cgiを利用するので、cgiファイルを作成します。

 #!/home/ユーザID/.pyenv/versions/anaconda3-5.0.0/bin/python
from wsgiref.handlers import CGIHandler
from testDash import server  #testDash.pyファイルで作成したflaskオブジェクトのこと

CGIHandler().run(server)

このcgiファイルには実行権限を付与する必要があります。

$ chmod 755 testDash.cgi

③.htaccess
最後に、URLのリライトを司るファイル.htaccessファイルを作成します。

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /dash/test/testDash.cgi/$1 [L]

3-3. 実行

以上で、デプロイが完了しました。これでhttps://ドメイン/dash/testにアクセすることで下記のような表示がなされると思います。

dashフレームワークの実行イメージ

4. まとめ

以上が、今回の内容です。現在、PUSH通知型のアプリのデプロイに挑戦中ですので、うまくいったらまたまとめ記事をあげたいと思います。今回も主にdashとflaskの公式ドキュメントを参考にしていますので、不明点があればそちらも確認して頂ければと思います。

参考になりましたら、幸いです。読んで頂き、ありがとうございます。