Django

Ubuntu 環境へ Django で作った WEB アプリケーションをデプロイする ① 【ローカル > サーバ】

上記で構築した VPS に Django で作成したアプリケーションをデプロイしていきます。

【 ローカル 】ローカルの設定

SECRET_KEY の設定

settings.py に記載されている SECRET_KEY はアカウント情報を暗号化するためのものです。アカウント登録を行わないアプリケーションであれば飛ばしてもいい(はず)です。

SECRET_KEYは、セキュリティ系のtoken等の生成に使われています。
生成アルゴリズムはDjangoのコードを見ればわかってしまいます。
SECRET_KEY以外は、ある程度の短さや範囲内なので、SECRET_KEYがわかってしまうと、試すべきパターンがかなり減ってしまいます。

SECRET_KEY

そのため、SECRET_KEY が流出した場合はアプリの安全性が著しく損なわれてしまいます。GItHub にプッシュした場合は GitGuardian からメールが飛んできます。私はメールで気づきました。

私は今回テスト用のデプロイのためここを飛ばしました。
たぶん下記の記事の通りやればシークレットキーなどの機密情報を安全に扱えるはずです。

requirements.txt の作成

ローカルにインストールしているライブラリと全く同じものをサーバ側でもインストールする必要があります。

そのために freezeを利用してrequirements.txtを作成しておきます。

pip freeze > requirements.txt

サーバ側ではこれを読み込むことでローカルと全く同じライブラリを一括でインポートできます。

ただ、ここで PyTorch の問題が出てきます。

PyTorch の扱い

PyTorch は環境や CUDA の有無でインストール方法が変わります。

多くの場合、本番環境では上記のインストール方法になるかと思います。
変更があっても LTS に変えるくらいではないでしょうか。

そのため、PyTorch のインストールに関しては下記の選択肢がでてきます。

  1. ローカルで requirements.txt から PyTorch に関わるライブラリを削除しておき、サーバで手動でインストールする
  2. ローカルで requirements.txt を作らず、サーバ側で全て手動でインストールする
  3. ローカルをサーバと全く同じ環境にしておき、requirements.txt をそのまま使用する

インストールしているライブラリの数で判断するとよいかと思います。

私は3番で行っています。
学習は別の環境で CUDA を使って行い、Django は Windows に構築した Ubuntu 環境で上記の PyTorch をインストールして開発しています。
ローカルとサーバで環境が同じため、requirements.txt が共有できます。

【 ローカル → Git 】
プロジェクトを Git にアップする

ローカルにある Django のプロジェクトをそのままサーバに移す必要があります。
一旦 Git にプロジェクトをプッシュし、それをサーバ側でクローンします。

ここでは PyCharm でプッシュを行っていますが、当然他の手段でも構いません。
Git に上げられればそれでよいです。

PyCharm で Git を扱う

メニュー > VCS > VCS 連携を有効にする
をクリックします。

OK をクリックするとローカルに GIt リポジトリが作成されます。

.gitignore ファイルの作成

.gitignore ファイルは Git で例外処理を行うファイルやディレクトリを指定するためのファイルです。
このファイルに書き込んだものは Git から除外され、add や commit から弾かれるようになります。

今回は上記の gitignore.io を利用して .gitignore ファイルを作成します。

python と入力して作成すると .gitignore ファイルで記述する中身のコードが表示されます。

プッシュ

プッシュを行う際にリモートの定義を設定します。

GitHub で作成した URL を貼って OK をクリックします。

この後 GitHub でアカウントのログインが必要になります。
ログインが成功すればプッシュが開始されます。

ここでエラーが出る場合、100MB を超えるファイルが存在する可能性があります。

LFS のインストールと設定

Github には 100MB までのファイルしかアップできません。
例えば画像処理に関する機械学習の学習済みモデルは容量が 100MB を超えるものがほとんどです。

これを回避するために Large File Storage のインストールと設定を行います。

Windows へのインストール

上記のページから exe ファイルをダウンロードできるので、 Windows にインストールします。

Git へのインストール

Git へもインストールします。ユーザーアカウントごとに一度だけ実行する必要があります。

git lfs install

リポジトリを巻き戻す

既にエラーが発生してしまっている場合は一旦リポジトリを巻き戻す必要があります。

下記のどちらかでエラーが発生したファイルがステージングされていない状態まで戻します。

git reset --soft HEAD^
git reset --soft コミットID

これを行わないとプッシュの際に再度エラーが起きます。

パターンの登録

LFS はパターンを登録し、そのパターンにマッチしたファイルに関してのみ 100MB を超えた場合でもプッシュできるようになります。
そのため、まずはパターンを登録します。

下記は拡張子のパターンを登録する場合。

git lfs track "*.pth"

下記は特定のファイルのみを登録します。

git lfs track "hoge/huga.pth"

.gitattributes ファイルのプッシュ

パターンを登録すると.gitattributesファイルが作成/編集されます。
これをプッシュすることで LSF がパターンにマッチしているかをトラッキングします。

git add .gitattributes
git commit -m ".gitattributes の更新"
git push

この後であれば 100MB を超えてもトラッキングされていればプッシュができます。

【 Git → サーバ 】
Git からサーバにプロジェクトを落としてくる

Git に上がったプロジェクトをサーバに落としてきます。

Django プロジェクトを入れるフォルダを作成する

特に指定はありません。「DjangoTest」というフォルダに入れる場合は下記のコマンドです。

mkdir DjangoTest
cd DjangoTest

Git のインストール

サーバに Git をインストールします。

sudo apt install git

Git のバージョンを確認

git --version

これでバージョンが表示されればインストールが成功しています。

クローン

普段通り下記のコードでクローンができるようになっています。

git clone リポジトリのURL / SSH

任意の場所に入って上記のコードを入力します。

LFS のインストール

ローカルからプッシュする際、100 MB を超えるファイルをプッシュしている場合は Ubuntu でも LFS の設定が必要です。

LFS 用のプルを行うまで ファイルの実態はダウンロードされていません。
git lfs pullを行うことで初めて実態がダウンロードされます。

まず Git LFS を Ubuntu へインストールします。

sudo apt install git-lfs

次にリポジトリに入って下記のコマンドを実行します。リポジトリに LFS をインストールします。

git lfs install

最後にLFS 用のプルを行います。

git lfs pull

【 サーバ 】Python 環境の構築

ローカルと同じ環境をサーバに構築していきます。

pip のインストール

pip --version

ほとんどの場合デフォルトで pip が入っていないので pip のインストールから行います。

sudo apt-get install python3-pip

インストールが終わったら下記のコードでインポートされたモジュールを表示できます。

pip list

virtualenv のインストール

サーバーでもローカルと同様に仮想環境を作って管理します。
そのため virturalenv をインストールします。

sudo pip install virtualenv

必要であれば wrapper のインストールもしておきます。

sudo pip install virtualenvwrapper

Virtualenvwrapper の設定

Virtualenvwrapper を使用するには .bashrc を編集する必要があります。

sudo vi ~/.bashrc

.bashrc の一番下に下記の 3行を追加して保存します。

こちらの最後の方に vi エディタの操作について記載しているので参考にしてください。

export VIRTUALENVWRAPPER_PYTHON=`which python3`
export WORKON_HOME=~/venv/
source `which virtualenvwrapper.sh`

下記のようなディレクトリとファイルが作成されれば成功です。

virtualenvwrapper.user_scripts creating /home/user_name/venv/premkproject
virtualenvwrapper.user_scripts creating /home/user_name/venv/postmkproject
virtualenvwrapper.user_scripts creating /home/user_name/venv/initialize
virtualenvwrapper.user_scripts creating /home/user_name/venv/premkvirtualenv
virtualenvwrapper.user_scripts creating /home/user_name/venv/postmkvirtualenv
virtualenvwrapper.user_scripts creating /home/user_name/venv/prermvirtualenv
virtualenvwrapper.user_scripts creating /home/user_name/venv/postrmvirtualenv
virtualenvwrapper.user_scripts creating /home/user_name/venv/predeactivate
virtualenvwrapper.user_scripts creating /home/user_name/venv/postdeactivate
virtualenvwrapper.user_scripts creating /home/user_name/venv/preactivate
virtualenvwrapper.user_scripts creating /home/user_name/venv/postactivate
virtualenvwrapper.user_scripts creating /home/user_name/venv/get_env_details

仮想環境の構築

ローカルの時と同様に仮想環境を利用します。

ここでは先ほどインストールした Virturalenvwrapper を利用して環境を作っていきます。

こちらに venv を利用した環境構築も記載しています。

仮想環境の作成

mkvirtualenv 環境名 -p python3

仮想環境の確認

下記のコードで作成済みの仮想環境がリストで表示されます。

workon

環境を切り替える

workon 環境名

環境を抜ける

deactivate

ライブラリのインストール

ローカル環境と同じ環境をサーバに作っていきます。

requirements.txt を利用する

下記のコードでローカルに入れていたライブラリがすべてサーバにも入ります。

仮想環境に入っていない場合は仮想環境にはいってから行います。

workon 環境名
pip install -r requirements.txt

PyTorch のインストール

ローカルの項目でも説明しましたが、ローカルとサーバで環境が違う場合は PyTorch のインストール方法が違います。
サーバでは下記の設定で PyTorch をインストールします。

pip3 install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cpu

バージョンを指定してインストール

手動でひとつひとつインストールしていく際、場合によってはバージョンを指定する必要があります。

特に指定しない場合は下記のように書きます。最新のバージョンがインストールされます。

pip install Django

バージョンを指定する場合は次のように記載します。

pip install Django==3.2.8

ライブラリにどんなバージョンがあるかを確認するには下記のコードです。

pip install Django==

PyPI を見に行ってもいいと思います。

【 サーバ 】データベースの用意

ローカルでの Django は SQLite を使用していましたが、サーバでは MariaDB を利用します。
Python で MariaDB に接続するためのライブラリの mysqlclient と、それを使用するための mysqlclient-dev を追加でインストールしていきます。

データベースのインストール

使用するデータベースをインストールします。

MariaDB のインストール

sudo apt-get install mariadb-server
sudo apt-get install libmariadbd-dev

MySQL Client

MariaDB を Python で扱うライブラリをインストールします。

mysqlclient-dev

sudo apt-get install libmysqlclient-dev

mysqlclient

pip インストールのため、仮想環境に入っていない場合は仮想環境に入ってから行います。

workon 環境名
pip install mysqlclient
MariaDB の起動sudo mysql
ユーザとデータべースを指定してログインmysql -u ユーザ名 -p データベース名
ユーザを指定してログインmysql -u ユーザ名 -p
データベースを指定use データベース名;

データベースの初期化

sudo mysql_secure_installation

ここでできるのは下記の設定です。
対話式になっているため、y / n で答えていきます。

  • root ユーザーのパスワードの変更
  • VALIDATE PASSWORD プラグインのインストール
  • ポリシーに沿った root ユーザーパスワードの設定 (VALIDATE PASSWORD プラグインをインストールした場合)
  • anonymous ユーザーの削除
  • リモートホストから root ユーザーでログインするのを禁止する
  • testデータベースの削除 (存在する場合)

ログインユーザの作成

MariaDB にアクセスするためのユーザを作成します。

ユーザの作成create user 'ユーザー名'@'localhost' identified by 'パスワード';
ユーザの権限付与grant all privileges on . to 'ユーザー名'@'localhost';
権限のリロードflush privileges;
ユーザの一覧を表示するselect user, host from mysql.user;
ユーザー情報を確認するselect * from mysql.user where user='ユーザー名'¥G
ユーザの削除drop user ユーザー名@localhost;

既に作成済みの場合はそのユーザを使用します。

データベースの作成

Django プロジェクトで使用するデータベースを作成します。

データベースの作成create database データベース名 character set utf8;
作成済みのデータベースをリスト表示show databases;
使用しているデータベースを確認するselect database();
データベースのテーブルをリスト表示show tables;

【 サーバ 】Django の設定変更

settings.py の編集

vi エディタで settings.py を編集します。

DEBUG

DEBUG = False
TEMPLATE_DEBUG = DEBUG

DEBUG を False にするとデバッグ機能がでなくなります。
デバッグ機能が有効になっている場合、アプリでバグが発生した際に様々な情報が表示されてしうことでセキュリティが脆弱になってしまいます。

そのため開発環境では DEBUG を True、運用環境では False にしておきます。

ALLOWED_HOSTS

ALLOWED_HOSTS = ['借りているIPアドレス', 'localhost']

ALLOWED_HOTSTS には IP アドレスを入れていきます。
nn.nn.nn.nnnの形になっているはずです。これと'localhost'を入れます。

DATABASES

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'データベースの名前',
        'USER': 'ユーザー名',
        'PASSWORD': 'パスワード',
        'HOST': 'localhost',
    }
}

データベースに関する設定を記載します。
サーバ側で作成したデータベース名やユーザ名、パスワードを記載します。

上記のコードは MySQL ですが、ちゃんと MariaDB に接続されます。

STATIC_ROOT

STATIC_ROOT は静的ファイルの置き場所です。HTML や CSS ファイルなどを一カ所に集める必要があるんですが、その場所をSTATIC_ROOTで指定します。

運用時には、スタティックファイルはなるべくパフォーマンスが良くなるように、アプリケーションを介さずに ウェブサーバーから直接返すとか、あるいは CDN などの別サーバーから返すことなどが行われます。

スタティックファイルの利用 | Python入門

サーバ側の任意のパスを指定します。

STATIC_ROOT = '/home/hoge/fuga/'

あるいは下記のように記述することもできます。

import os
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')

テーブルの作成 | migrate

上記の設定で migrate を行い、テーブルを作成します。

python3 manage.py migrate

テーブルができているか確認します。

sudo mysql -u ユーザー名 -p データベース名

ユーザーとデータベースを指定してログインし、

show tables;

を行うことでデータベース内のテーブルが表示されます。

うまく表示されていない場合は下記を確認してください。

  • settings.py の DATABASES の部分を見直す
  • データベースがインストールされているか見直す
  • model の記述が正しいか見直す

superuser の作成

サーバ側では管理者もまだ作られていません。管理者権限を持つアカウントも作成しておきます。

python3 manage.py createsuperuser

静的ファイルの設置 | collectstatic

python3 manage.py collectstatic

STATIC_ROOT に設定したパスに admin フォルダが作成され、その中に静的ファイルが格納されていきます。

STATIC_ROOT = os.path.join(BASE_DIR, 'static/')としていた場合は manage.py と同じ階層に static フォルダが作られ、その中に静的ファイルが入っているはずです。

意図しない挙動をした場合は settings.py の STATIC_ROOT を確認してください。

② へ続く

関連ページ

-Django