ConoHa VPS Debian9 からDjangoアプリをデプロイしてみた!!

この記事は、
ConoHa VPS の Debian OS に Djangoベースのサービスデプロイしてみた!!Debian9 に Python3系をインストールしてみた!の続編。前回は、

  1. ConoHa VPSで サーバー設置
  2. SSH接続の設定
  3. Pyhon3.6をソースコードのビルド&インストール

までを行なった。
今回は宣言通り、デプロイに必要なソフトのインストールから各種設定を行う第三弾!

  • git
  • Django
  • Apache2

ちなみに今回の開発環境は、Pythonの仮想環境上に構築することとする(※仮想環境の構築に関しては、こちらの記事を参照)。また開発リソースは全てGitによって管理する。以上から、サービス必須パッケージは全てGitリポジトリ経由で、デプロイ環境にインポートできることとする。

大きく3つの設定(Apache2の設定mod_wsgiの設定Djangoアプリの設定)が存在している為、当初は複雑に感じるが、一つずつ設定していくことでデプロイが完了した時には、全体像が見えるようになっていることを期待する。

環境紹介などのおさらいから…



環境

クライアント(手元)のPC

  • MacOSX 10.13.4

サーバー "ConoHa VPS"

  • Debian 9
  • Apache2.4.25(Debian)
  • Python 3.6.5
  • Django 2.0.2
  • pip3 9.0.1
[商品価格に関しましては、リンクが作成された時点と現時点で情報が変更されている場合がございます。]

将棋AIで学ぶディープラーニング [ 山岡忠夫 ]
価格:3434円(税込、送料無料) (2018/4/12時点)

前回のおさらい

STEP.1:ConoHa VPSで、[Debian9]ベースのサーバーを追加
STEP.2:サーバーの初期設定
STEP.3:Python3.6のインストールと設定

上記STEP1,2に関しては、こちらを参照
上記STEP3に関しては、こちらを参照

STEP.4:Djangoサービス デプロイの準備

  1. gitのインストール
    以下のコマンドでインストール完了。バージョン名が表示されればOK!

    # apt-get install git
    # git --version
    git version 2.11.0
  2. 外部リポジトリ(git)から、DjangoベースのサービスをPull

    # git clone https://github.com/YYYYYY/XXXXX.git
    # git branch -a
    * master
      remotes/origin/HEAD -> origin/master
      remotes/origin/master
    上の例ではmasterブランチに属していることがわかる。デプロイ環境では基本的にソースコードに手を加えないので、常にこのmasterブランチをデプロイ環境とすることで問題ない(※Tagをつけておくと管理しやすくなる)
    GitHub, BitBucketなどPublicのリポジトリからクローンするもよし、プライベートなGitサーバーからクローンするもよし。
  3. サービス動作必須モジュールのインストール(Django etc...)
    開発環境では、Python仮想環境上で環境構築をしたので、今回もそれにならって仮想環境を準備してその中に必須コンポーネントをインストールすることとする。

    # cd <gitリポジトリのパス>
    # 仮想環境の準備
    # python3.6 -m venv venv
    # source venv/bin/activate
    (venv) #

    上記手順によって、gitリポジトリをクローンしたフォルダ内にvenvフォルダが生成され、sourceコマンドで仮想環境を駆動すると、パス冒頭に(venv)が付与される。この状態で、pipを実装することで、venvフォルダ内に必須コンポーネントがインストールされる。仮想環境下ではなくOS直下にインストールすることでも問題ないが、Djangoアプリが依存しているコンポーネントの管理(見える化)の観点から、venv環境下に格納することがよいと考える。
    続いて、以下のpipコマンドでコンポーネントをインストールする。成功したらpip freezeコマンドでインストール済みコンポーネントを確認する

    (venv) # pip install -r requirements.txt
    (venv) # pip freeze
    certifi==2018.1.18
    chardet==3.0.4
    Django==2.0.2
    idna==2.6
    Pillow==5.0.0
    pytz==2018.3
    requests==2.18.4
    urllib3==1.22    
    以上から分かる通り、Django バージョン 2.0.2も含み必要コンポーネントのインストールが完了した!!


  4. apache2のインストール
    以下のコマンドでWEBサーバーコンポーネント"apache2"をインストールする

    # apt-get install apache2

    成功したら、サーバーのグローバルIPアドレスをブラウザのアドレス欄に入力。Apacheの初期画面が表示されればインストールと起動成功!
    apache初期画面

  5. mod_wsgiのインストール
    続いて、mod_wsgiのインストール。これはPythonで、WEBサーバー(ここではApache2)とWEBアプリを連結する為のモジュールで、DjangoアプリをApache上で駆動させるために必要である。

    # apt-get install libapache2-mod-wsgi-py3
  6. Apache設定の変更("mod_wsgi"との連携)
    Apache上で、mod_wsgiと連携するために設定ファイルを作成する

    # touch /etc/apache2/sites-available/python.conf

    ファイルに以下の情報を記載する。記述方法はdjango公式のここを参照

    LoadModule wsgi_module modules/mod_wsgi.so
    
    WSGIScriptAlias / /home/hoge/git/django_app/app/wsgi.py
    WSGIPythonHome /home/hoge/git/django_app/venv/
    WSGIPythonPath /home/hoge/git/django_app:/home/hoge/git/django_app/venv/lib/python3.6/site-packages
    
    <Directory /home/hoge/git/django_app/app>
    <Files wsgi.py>
    Require all granted
    </Files>
    </Directory>

    "WSGIScriptAlias"の最初の"/"は、ルートURLの設定。/mysiteとすると、http://hogehoge.net/mysite/がルートURLになる。
    "WSGIPythonHome"で、"mode_wsgi"に関連付けるPythonのパスを指定。今回はPython仮想環境を経由したので、そのパスを指定。ちなみにディレクトリを指定する点に注意!!
    "WSGIPythonPath"で、アプリのルートディレクトリ及び仮想環境のライブラリディレクトリを指定。
    下記コマンドで設定を反映させる
    "Directory"で、apacheへアクセス権を与えるディレクトリのパスを指定。Djangoアプリや静的ファイルを格納するディレクトリなどがそれにあたる。

    # a2ensite python.conf
    Enabling site python.
    To activate the new configuration, you need to run:
    systemctl reload apache2

    コメントに従って、apache2の再起動

    # systemctl reload apache2


  7. Django設定(settings.py)の変更
    Djangoアプリの設定ファイルapp/settings.pyを編集して、デプロイに向けた準備をする。
    まず下記通りに編集して、公開サイトのドメイン名を指定する。"*"は全て公開を意味する。制限したい場合、"www.hogehoge.com"などにして、直接指定も可!!

    ALLOWED_HOSTS = ['*']

    次に、"html"のテンプレートファイルを読み込めるように編集する

    EMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],  # ←ここを編集!
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
    ]
    これで、Djangoアプリ直下のtemplatesディレクトリ内に格納されたHTMLテンプレートファイルが読み込まれる


  8. staticファイルの読込み設定(Django, Apache双方への設定)
    画像ファイルやメディアファイル、CSSやjavascriptファイルなどの静的ファイルをWEBサーバー(Apache)から配信できるように設定を行う。最終的には、manage.py collectstaticコマンドを実行して、Djangoアプリ内で利用・参照するstaticファイルを所定のフォルダSTATIC_ROOTに集め、サーバーはそこをSTATIC_URLとして公開(配信)する形になる。
    下記をapp/settings.pyの最下部に追加した。各自Djangoアプリの構成に従って、修正する必要があるので、以下は一例と捉えてほしい。
    Django公式ドキュメントを一読することで、理解が深まる。今回も参照しながら設定した。

    STATIC_URL = '/statics/'
    STATIC_ROOT = os.path.join(BASE_DIR, "statics/")
    STATICFILES_DIRS = (
        os.path.join(BASE_DIR, "static"),
    )

    ポイント
    "collectstatic"コマンド実行時、任意の場所から収集させるためには以下に追記する。例えば、複数のディレクトリからファイルを集める場合には用いられる。今回の場合、プロジェクト直下の"static"ディレクトリ内にまとめて静的ファイルを格納する構成となっているため、この記述となっている。

    STATICFILES_DIRS = (
      # ここに任意のディレクトリを指定する
      # os.path.join(BASE_DIR, "static"),
    )


    更に、WEBサーバー(Apache)側の設定ファイル(/etc/apache2/sites-available/python.conf)にも修正を加える。

    Alias /statics/ /home/hoge/git/django_app/statics/
    
    <Directory /home/hoge/git/django_app/statics>
    Require all granted
    </Directory>

    ここまできたら、WEBサーバーの再起動

    # a2ensite python.conf
    # service apache2 restart

    ポイント
    静的ファイルの格納ディレクトリ(今回はstatics)が、Django側の設定app/settings.pyとapache側の設定/etc/apache2/sites-available/python.confで共通担っていること!!
    ここがずれていると、ブラウザヒョジの時に「staticファイルがないよ!」って、404エラーが吐き出されてしまう

    下記コマンドを実行して、静的ファイルをかき集める!!

    # cd <gitリポジトリのパス>
    # source venv/bin/activate
    (venv) # manage.py collectstatic
    216 static files copied to '/home/hoge/git/django_app/statics'.

    これで、216の静的ファイルがstaticsフォルダ内にかき集められる。

    ポイント
    Djangoアプリに依存したモジュールは、Python仮想環境からインストールしているので、まずはVirtualEnv環境を実行してから、manage.py collectstaticを実行する

  9. ブラウザで動作確認!!
    ここまでくれば、WEBサーバーからの配信準備が整っている。すなわち、既にデプロイされている!!
    なので、VPSのブローバルIPアドレスを適当なブラウザのアドレス欄に入力してほしい!すると…

    『ドン!!!』

    表示されたのではないだろうか!?!?

    もし何か不具合があっても大丈夫!!何か設定を見落としていたり、コンポーネントが不足しているだけだろう。具体的には、画面上にエラーメッセージが表示されていると思うので、それを参照して解決していく。これはローカル開発時にもDjangoがエラーメッセージを出力してくれていたので、その時を思い出しながら、トラブルシュートしていけばいい。
    ちなみに、Django側の問題だけとは限らない。WEBサーバーのエラーの場合、Apacheがエラーログをファイル出力しているので、そちらも確認することで、問題解決の糸口になる。ちなみにエラーログは、以下で確認できる。オプションに-fを付与するとログファイルの変更を検出して出力してくれるので、リアルタイムに監視する時に便利。

    # tail /var/log/apache2/error.log

STEP.5:正式デプロイ!最後の設定変更!!〜最重要〜

前項でブラウザに表示されたら、デプロイ完了!!
と言いたくなるが…最後のダメ押し、そして意外にも最も大事な設定変更を以下から行う。
Django設定ファイルapp/settings中のデバッグモードをOFFにする設定変更である。

DEBUG = False   # True を False に変更

これを行わないと、もしサイトに不備があった場合、その詳細エラーメッセージが誰にでも表示されてしまう。これは一般閲覧者にとって混乱を与えるとともに、セキュリティ上の不安も残す。よって、デバッグモードをOFFにして、再起動することがデプロイ最後の作業に欠かせない。

# service apache2 restart

これでデプロイ完了!!
ただし現時点では、グローバルIPアドレスでアクセスするだけとなるので、次回はDNSサーバーの設定を行なう予定。
そうすることでサーバーを移管してIグローバルIPアドレス変更にともなう問題を気にする必要もなくなるし、SEO対策には当然中の当然の対応になるので…