[Azure][django] Azure Virtual machine で Djangoサーバーを立てる

とりあえず、AzureにDjangoサーバーを立ててみたい、という記事です。
Githubを使ってデプロイする予定です。

# Djangoプロジェクトの作成
[Djangoを最速でマスターする part1](https://qiita.com/gragragrao/items/373057783ba8856124f3)
こちらの記事を参考に作成できます。「Django基礎」まででOKです。

# 仮想マシンを作る

次に、Azure Virtual machineを作成します。
ここでは、既にAzureアカウントがある事を前提とします。

#### リソースグループの作成
はじめに、リソースグループを作成します。
Azureポータルのサイドバーにある「リソースグループ」をクリック > 左上にある「追加」ボタンをクリックしてください。
作成画面が開くはずです。
「リソースグループ」にこのリソースグループの名前を入力した後、「確認及び作成」ボタンを押して作成しましょう。

#### 仮想マシンの作成

次に、仮想マシンを作成します。
はじめに、Azureポータルのサイドバーにある「Virtual Machines」をクリック > 左上にある「追加」ボタンをクリックしてください。
作成画面が開くはずです。
各種項目を以下の様に入力して、仮想マシンを作成しましょう。
今回はUbuntuサーバーを作ります。

```
サブスクリプション：使用するサブスクリプションを選択（ご自由に）
リソースグループ：今作成したリソースグループ
仮想マシン名：この仮想マシンの名前（ご自由に）
地域：インスタンスを立てる地域（ご自由に）
可用性オプション：デフォルトでOK
イメージ：Ubuntu Server 16.04 LTS
サイズ：B1S
認証の種類：SSH
ユーザー名：この仮想マシンのユーザー名（ご自由に）
SSh公開キー：このUbuntuに接続するためのSSH公開キー（作成方法は以下の通り）
Azure Active Directoryでログインする：オフ
パブリック受信ポート：選択したポートを許可する
受信ポートを選択：HTTP、SSH
```

---
##### SSHキーの作成方法
1. ターミナルを開きます。
2. SSHキーを作成したいディレクトリに移動します。
3. 「ssh-keygen」と打ちます。
4. 「キー名は何にしますか？」と聞かれるので、好きなキー名を入力します。
5. その後、「パスフレーズは何にしますか？」などと2回質問されますが、どちらも何も入力せずにエンターを押します。
6. このディレクトリの中にキーが作成されました。「ls」コマンドや「dir」コマンドで確認してみましょう。「○○」と「○○.pub」の2種類が作成されているはずです。（○○はキー名です。）

「○○」はSSH秘密キー、「○○.pub」はSSH公開キーです。
「○○.pub」の中身をAzureの「SSH公開キー」の入力欄にコピーしましょう。
ターミナル上で「cat ○○.pub」（Windowsなら「type ○○.pub」）と入力してください。
ファイルの中身が表示されるはずです。
表示されたテキストをコピーして、Azureの「SSH公開キー」の入力欄に張り付けましょう。

---

これらの値を入力した後、右下にある「確認及び作成」ボタンを押して作成しましょう。
（「次: ディスク>」ボタン以降の設定はデフォルトのままでOKなので、ここでは省略します。）

次に、このサーバーのDNS名を登録します。

画面左側のサイドバーにある「Virtual Machines」を押してください。
その後、表示される仮想マシン一覧の中にある今作成したマシンをクリックしてください。

仮想マシンの詳細ページが開かれるはずです。

いくつかの項目と値が表示されています。
その中にある「DNS名」という項目の右にある「構成」というボタンを押してください。
開かれるページの中にある「DNS名ラベル（オプション）」という項目に好きなDNS名を入力してください。
その後、画面上にある「保存」ボタンをクリックしてください。
これでDNS名の登録が完了しました。

以上で仮想マシンの作成は完了です。

# Djangoの設定

Azure上で動かすための設定をしていきます。

はじめに、wsgi.pyに以下を追記します。
元々書かれている```application = get_wsgi_application()```という行よりも上に追記してください。
また、```【仮想マシンのユーザー名】```は、先程仮想マシンを作成した時に登録したユーザー名に置き換えてください。
```【プロジェクト名】```は、このDjangoプロジェクトのプロジェクト名に置き換えてください。

```python:wsgi.py
import sys
sys.path.append('/home/【仮想マシンのユーザー名】/【プロジェクト名】')

# これよりも上に記入
application = get_wsgi_application()
```

次に、settings.pyを編集します。
まず、以下の様に変数を変更してください。

```python:settings.py
# LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'ja'

# TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Tokyo'

# ALLOWED_HOSTS = []
ALLOWED_HOSTS = ['*']
```

また、以下も追記してください。

```python:settings.py
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
```

次に、このプロジェクトで使用するPythonパッケージを設定します。
manage.pyがある階層に、以下のファイルを追加してください。

```txt:requirements.txt
Django
jinja2
```

また、.gitignoreファイルも同階層に追加してください。

```txt:.gitignore
.DS_Store

*.log
*.pot
*.pyc
__pycache__/
local_settings.py
db.sqlite3
media
```

以上でDjangoの設定が出来ました。

Githubのremoteレポジトリにアップしておきましょう。

参考：[AzureのApp ServiceにDjango@Python3.6.4で作ったWebアプリをデプロイする](https://qiita.com/yoshieya/items/438f8b2571aa9cae3e82#%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AB%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4%E3%81%97%E3%81%BE%E3%81%99)

# 仮想マシンにログイン

それでは仮想マシン上に移動しましょう。
sshでログインします。

```bash:ローカルのターミナル
ssh -i 【SSH秘密キーのパス】 【仮想マシンのユーザー名】@【仮想マシンのパブリックIPアドレス（もしくはDNS名）】

# 【ssh-keyのパス】は、仮想マシンに登録したSSH公開キーに対応するSSH秘密キーへのパスで置き換えてください。
# 【仮想マシンのユーザー名】は、仮想マシンの作成時に登録したユーザー名で置き換えてください。
# 【仮想マシンのパブリックIPアドレス（もしくはDNS名）】は、Azureポータルの仮想マシンの詳細ページに書かれている値で置き換えてください。

# 例：ssh -i path/to/.ssh/id_rsa MyUser@1.1.1.1
```

ログインしたら、仮想マシン上で使用するパッケージをインストールしておきましょう。

```bash:仮想マシンのターミナル
sudo apt install -y python3 python3-pip python3-setuptools python3-wheel python3-dev apache2 apache2-dev libapache2-mod-wsgi-py3 git
```

参考：[[Python] Linux(Apache2) で Djangoアプリを公開する](https://qiita.com/okoppe8/items/0f67753706cdc11ff1cd#%EF%BC%91%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)

# Git clone

続いて、Githubのremoteレポジトリより先程作成したDjangoプロジェクトをクローンします。

##### SSHの設定

まず初めに、Githubに接続出来るようにSSHの設定をします。

以下のコマンドを入力し、sshキーを作成してください。

```bash:仮想マシンのターミナル
cd ~/.ssh
ssh-keygen # キー名はご自由に
```

次に、公開キーをGithubに登録します。
以下のコマンドで公開キーの中身が表示されるはずです。
コピーしてください。

```bash:仮想マシンのターミナル
cat 【キー名】.pub
```

次に、この[GithubのSSH公開キー登録ページ](https://github.com/settings/keys)にキーを登録します。
Githubにサインインした後、このページを開いてください。
右上の「New SSH key」ボタンを押し、Titleに好きなタイトルを、Keyに先程コピーしたものを入力して「Add SSH key」ボタンを押すと、Githubに公開キーが登録されます。

さらに、SSH設定ファイルを作成します。

```bash:仮想マシンのターミナル
sudo vi config
```

viが開くので、以下を入力してください。
【仮想マシンのユーザー名】は置き換えてください。

```
Host github.com
  User 【仮想マシンのユーザー名】
  HostName github.com
  IdentityFile ~/.ssh/id_rsa
  IdentitiesOnly yes
```

以上でSSH設定は完了です。

##### クローン

いよいよクローンです。
以下のコマンドでクローンしましょう。
【リポジトリのURL】はGithubのレポジトリのトップページにある「Clone or download」ボタンを押すと表示される```git@github.com:～```というものです。（```https://github.com/～```と表示される場合は、右上の「Use SSH」というボタンを押すとSSH用のURLに切り替わるはずです。）

```bash:仮想マシンのターミナル
cd ..
git clone 【リポジトリのURL(ssh用の方)】
```

クローンが完了したら、requirements.txtに書いたPythonパッケージをインストールします。

```bash:仮想マシンのターミナル
python3 -m pip install --upgrade -r requirements.txt
```

さらに、以下のコマンドを打ってください。

```bash:仮想マシンのターミナル
sudo cp -pR /home/g-user/.local/lib/python3.5/site-packages/* /usr/local/lib/python3.5/dist-packages
```

このコマンドでは、先程インストールしたパッケージを他のディレクトリにコピーしています。
これにより、この仮想マシンに元々入っているmod_wsgiが、実行時にパッケージを参照できるようになります。
（mod_wsgiとは、「Pythonプログラム」と、この後登場する「Apache」というwebサーバーソフトウェアをつないでくれるモジュールの事です。詳細はここでは省略します。おまじないだと思って唱えてください。）

参考: [gitのssh接続に使用する~/.ssh/configの設定について](https://qiita.com/kawahara_hiroyuki/items/3ad35c548d1007c12109)

# Apacheの設定

次にApacheの設定をしていきます。
以下のコマンドでconfファイルを開いてください。

```bash:仮想マシンのターミナル
sudo vi /etc/apache2/sites-available/000-default.conf
```

そして、中身を全て以下に置き換えてください。
【この仮想マシンのユーザー名】と【プロジェクト名】は置き換えてください。

```conf:000-default.conf
<VirtualHost *:80>
        # The ServerName directive sets the request scheme, hostname and port that
        # the server uses to identify itself. This is used when creating
        # redirection URLs. In the context of virtual hosts, the ServerName
        # specifies what hostname must appear in the request's Host: header to
        # match this virtual host. For the default virtual host (this file) this
        # value is not decisive as it is used as a last resort host regardless.
        # However, you must set it for any further virtual host explicitly.
        #ServerName www.example.com

        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html

        # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
        # error, crit, alert, emerg.
        # It is also possible to configure the loglevel for particular
        # modules, e.g.
        #LogLevel info ssl:warn

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        # For most configuration files from conf-available/, which are
        # enabled or disabled at a global level, it is possible to
        # include a line for only one particular virtual host. For example the
        # following line enables the CGI configuration for this host only
        # after it has been globally disabled with "a2disconf".
        #Include conf-available/serve-cgi-bin.conf

        Alias /static /home/【この仮想マシンのユーザー名】/【プロジェクト名】/static
        <Directory /home/【この仮想マシンのユーザー名】/【プロジェクト名】/static>
                Require all granted
        </Directory>

        <Directory /home/【この仮想マシンのユーザー名】/【プロジェクト名】/【プロジェクト名】>
                <Files wsgi.py>
                        Require all granted
                </Files>
        </Directory>

        WSGIDaemonProcess 【プロジェクト名】 python-path=/usr/local/lib/python3.5/dist-packages
        WSGIProcessGroup 【プロジェクト名】
        WSGIScriptAlias / /home/【この仮想マシンのユーザー名】/【プロジェクト名】/【プロジェクト名】/wsgi.py
</VirtualHost>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
```

次に、以下のコマンドで権限を変更してください。

```bash:仮想マシンのターミナル
chmod 664 ~/【プロジェクト名】/db.sqlite3
sudo chown :www-data ~/【プロジェクト名】/db.sqlite3
sudo chown :www-data ~/【プロジェクト名】
```

最後にapacheサーバーを再起動して設定は完了です。

```bash:仮想マシンのターミナル
sudo service apache2 restart
```

参考: [Azure上のUbuntu VMにDjangoプロジェクトをデプロイする](https://qiita.com/jachelt/items/eb8e6736f5590df6a6ce)

---

以上でサーバーの作成は完了です！
ブラウザのURLバーに仮想マシンの IPアドレス or DNS名 を入力してみましょう。
Djangoの画面が表示されるはずです。

# deploy時

仮想マシンのターミナル上で以下のコマンドを入力してください。

```bash:仮想マシンのターミナル
git pull

# requirements.txtをいじってたら
python3 -m pip install --upgrade -r requirements.txt # パッケージをインストール
sudo cp -pR /home/g-user/.local/lib/python3.5/site-packages/* /usr/local/lib/python3.5/dist-packages # 今インストールしたパッケージをwsgi_modが参照する場所に移動

# 静的ファイルをいじっていたら
sudo /usr/bin/python3 manage.py collectstatic --noinput # 静的ファイルのあるフォルダを更新する（noinputは「今あるファイルを上書きしてもOK?」の質問が出ないようにするため）

sudo service apache2 restart 
```

また、jenkinsでデプロイする場合は、以下のコマンドをビルド手順の「シェルで実行」に張り付けてください。
【プロジェクト名】と【仮想マシンのユーザー名】は置き換えてください。

```bash:jenkinsの「シェルで実行」
ssh -i ~/.ssh/production_rsa g-user@40.115.185.174 'cd 【プロジェクト名】 && git pull origin master'
ssh -i ~/.ssh/production_rsa g-user@40.115.185.174 'sudo python3 -m pip install --upgrade -r 【プロジェクト名】/requirements.txt'
ssh -i ~/.ssh/production_rsa g-user@40.115.185.174 'sudo /usr/bin/python3 【プロジェクト名】/manage.py collectstatic --noinput'
ssh -i ~/.ssh/production_rsa g-user@40.115.185.174 'sudo cp -pR /home/【仮想マシンのユーザー名】/.local/lib/python3.5/site-packages/* /usr/local/lib/python3.5/dist-packages'
ssh -i ~/.ssh/production_rsa g-user@40.115.185.174 'sudo service apache2 restart'
```

# 修正
2019/5/2
settings.pyのSTATIC_ROOTの値を修正しました。
（プロジェクトフォルダ直下に作成されるように修正しました。）

```python:settings.py
# 前
STATIC_ROOT 'static'

# 後
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
```