XserverにDjangoアプリケーションをDeployする

この記事は [Django Advent Calendar 2022](https://qiita.com/advent-calendar/2022/django) の最終日の記事です。


# はじめに
はじめまして。

今年の [Django Advent Calendar 2022](https://qiita.com/advent-calendar/2022/django) も楽しく拝見させて頂きました。

さて、今年のWebアプリケーション開発界隈で注目された大きなニュースといえば
 **「Herokuの無料プラン廃止」** ではないでしょうか？

私自身もHerokuの無料プランを使用して Django アプリケーションを運用していたので対応に追われました。

そこで、今年は Django アプリケーションを Xserver に deploy する方法について書いていこうと思います。

この記事が Django のより一層の普及に少しでも貢献できれば幸いです。

# はじめに
Heroku の無料プランの代替として数多くのサーバーサービスがありますが、
**「なぜ Xserver なのか」** というところについてはこれといった理由はありません。

ただ単に私が Xserver を既に契約していたため、ランニングコストが最も低い選択肢が Xserver だったからです。

たしかに Xserver には以下のような理由で都合が良い点もあります。

- 1サーバー契約してしまえば複数のドメインを紐づけることができる
- ある程度のアクセスを捌くことができる
- SSH 接続ができる

ただし、これはおまけみたいなものであくまで「既に契約している」ことが大きかったです。

新たにサーバーを契約するくらいなら Heroku の有料プランに切り替えた方が金銭的にも労力的にもコストが低いと思います。

また、今回の方法では対象のアプリケーションが以下のような場合には移行が難しいかもしれません。
（これらの理由で私はいくつかのアプリケーションの移行を諦めました）

- Bootstrap などの他のフレームワークも使用している
- OpenCV などの複雑な環境を要するサードパーティライブラリを使用している

加えて、当然ながら Heroku Scheduler や Cloudinary などの Heroku Add-ons を使用している場合は代替方法を考慮する必要があります。

これらを前提として以降、行うべき作業を順番に記載していきます。

# 独自ドメインと Xserver を紐づける

まずは Heroku と紐付けていた独自ドメインを Xserver と紐付けましょう。

ここら辺はブラウザで簡単に設定できます。

Xserver のサーバーパネルにログインして、
[ドメイン設定] > [ドメイン設定追加] から対象ドメインを入力すれば OK です。


なお、ドメインサービス側でもネームサーバーを変更する必要があります。

こちらはドメインサービスによって設定手順は異なりますが、
基本的には Heroku のネームサーバーを設定していた箇所を Xserver のネームサーバーに置き換えれば良いはずです。


# Xserver に ssh 接続できるようにする

Xserver には自由に使える Python 環境が入っていません。

そのため、アプリケーションを動かすために Python 環境を構築する必要があります。

そこで Xserver に SSH 接続できるようにしてコマンドを実行できるようにします。

いくつかの STEP が必要なので順番に解説します。

## 1. Xserver の SSH 機能を ON にする

Xserver のサーバーパネルにログインして、[SSH設定] から [ONにする] を選択します。


## 2. 公開鍵認証用鍵ペアの生成

Xserver のサーバーパネルにログインして、
[SSH設定] > [公開鍵認証用鍵ペアの生成] から任意のパスフレーズを決めて鍵ペアを生成します。

生成に成功すると秘密鍵がダウンロードされます。SSH 接続に必要となるので保管しておきましょう。


## 3. Xserver にログインする

ここまでで接続の準備は完了しているので、Xserver に SSH 接続していきましょう。

まず秘密鍵のファイル名とパーミッションを変更します。

```bash
mv [サーバー名.key] id_rsa
chmod 600 id_rsa
```

そして秘密鍵のある階層で以下のコマンドを実行して Xserver に SSH ログインします。

```bash
ssh -l [サーバー名] -i id_rsa [サーバー名].xsrv.jp -p10022
```

これで Xserver に SSH でログインできました。

以降の作業は SSH ログインした状態で行っていきます。


# Xserver に Django アプリケーションを動かすための環境を構築する

Xserver には基本的に何も入っていないので必要なものを順番にインストールしていきます。

## 1. Python をインストールする

まずは Python をインストールします。

実は Xserver にはデフォルトで Python が入っているのですが、既存の Python 環境に手を入れるための root 権限が与えられていません。
（Xserver は共用サーバーなので）

そこで pip などで任意のライブラリを入れるための Python を新たにインストールする必要があります。

Python のインストールには Anaconda を使うのをオススメします。

もちろん Anaconda を使わずに直接 Python を入れることもできるのですが、
Xserver の仕様に合わせて Linuxbrew を入れたり Python PTAH を通したりするのがとてもややこしいです。

Anaconda を使うことでそこらへんをまるっとお任せできるので便利でした。

私自身、普段は Anaconda を使わない派ですが Xserver への Python インストールは結局 Anaconda を使用しました。

以下のコマンドで Anaconda をインストール & 有効化することができます。

```bash
# 公式のリポジトリから Anaconda をダウンロード
wget https://repo.anaconda.com/archive/Anaconda3-2021.11-Linux-x86_64.sh

# Anaconda をインストール
bash Anaconda3-2021.11-Linux-x86_64.sh

# Anaconda をアクティベート
source ~/.bashrc
```

## 2. Django をインストールする

新たに入れた Python に Django をインストールしましょう。
Anaconda が有効化されていれば pip を使えるはずです。

```bash
pip install django
```

# Xserver 上に Django Project を Deploy する

ここまでの手順で環境は整っているので、いよいよ Django Project を Deploy していきます。

ここからの作業は Xserver に仕様を踏まえたものとなります。
**（個人的には一番ハマりました）**


## 1. Xserver 上に Django Project と Django app を作成する

Xserver の仕様(?)で Django プロジェクトをアップロードする前に、
一度 Django Project と Django app を作成しないとなぜかアプリケーションがうまく動きません。

そこで、まず Xserver 上で Django Project と Django app を作成します。

```bash
# 作業ディレクトリに移動する
cd 独自ドメイン名
cd public_html

# PJ の作成
django-admin startproject [Project 名]

# app の作成
cd [Project 名]
django-admin startapp [App 名]
```

## 2. Django Project を Xserver にアップロードして作成した Project と入れ替える

ブラウザまたはコマンドで deploy 対象の Django Project を Xserver にアップロードします。

そして先ほど作成した Project の配下をアップロードした Project のものとそっくりそのまま入れ替えます。


## 3. .htaccess, index.cgi を作成する

Xserver で Django アプリケーションを動かすために必要なファイルを作成します。

### .htaccess
.htaccess は対象のドメインにアクセスした際の挙動を定義するファイルです。

今回は以下のように記述します。

```text
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /index.cgi/$1 [QSA,L]
```

対象ドメインへのアクセスを受けたら index.cgi を叩くようにしています。


### index.cgi
index.cgi は .htaccess から呼び出される実行ファイルです。

以下のように記述します。

```python
#!/home/[サーバーID]/anaconda3/bin/python
# encoding: utf-8

import sys, os

sys.path.append("/home/[サーバーID]/[独自ドメイン名]/public_html/[Project 名]/")

os.environ['DJANGO_SETTINGS_MODULE'] = "[Project 名].settings"

from wsgiref.handlers import CGIHandler
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
CGIHandler().run(application)
```

今回は Django アプリケーションを起動するコードになっています。

上記コードの [サーバーID], [独自ドメイン名], [Project 名] は全て自分の環境に置き換えて下さい。


## 4. static ディレクトリの階層を移動する

Xserver の独自の仕様により Django Project の static ディレクトリを正しく読み込むことができない場合があります。

そこで 静的ファイルを正しく読み込むために static ディレクトリを適切な場所に移動します。

本来、Django アプリケーションの static ディレクトリは以下のような構成になっていることが多いと思います。

- [Project 名]/[App 名]/static

この static ディレクトリを Xserver 上では public_html 直下に移動します。

- /home/[独自ドメイン名]/public_html/static
 


# さいごに

最後まで読んで下さり、ありがとうございます。

年々 新たなフレームワークや技術要素が登場し、
Django Advent Calendar の勢いも落ちつつ悲しい限りですが、
シンプルかつ強力な Django は個人的には好きです。

これまでにも Django に関する記事をいくつか書いているので良かったらご覧いただけると幸いです。

 - [Djangoの個人的Tips](https://qiita.com/pythonista/items/3a0e6256db22d5e64a68)
 - [Pythonさえ分かればDjangoでWebアプリは作れる](https://qiita.com/pythonista/items/19613663ef7bb3c57d4f)

それでは来年も良いDjangoライフを！