- Djangoアプリをデプロイする手順とは?
- NginxとGunicornの使い方とは?
本記事ではこのような疑問を解決します。
Djangoアプリをデプロイする際に、簡単にできるのはHerokuなどのPaaS(Platform as a Service)を利用する方法です。
しかし、このようなPaaSでは機能や拡張性、利用用途などが限られてしまいます。
一方、VPSなどのroot権限が付与されたサーバー(主にLinuxサーバー)であれば様々なDjangoアプリに対応可能です。
そこで今回はDjangoアプリをLinuxサーバーへデプロイする方法をわかりやすく解説していきます。
なお、本記事ではデプロイ方法にスポットライトを当てるため、Djangoアプリの作成やレンタルサーバー(VPS等)の導入方法については省略いたします。
まだレンタルサーバーの導入が済んでいない方はこちらの3つの中から選択するのが無難です。
・お名前.com VPS
・カゴヤ VPS
・ConoHa VPS
それでは早速Linuxサーバーへのデプロイ方法を確認していきましょう!
エンジニアが副業を始めるには?エンジニアの副業にはどんな種類がある? 本記事ではこのような疑問を解決します。副業がブームになっている昨今、エンジニアほど副業をやりやすい職業はないでしょう。副業に関心があったり、副業をしてみたいと思っ[…]
①Djangoの設定ファイルを編集する
まずは開発環境から本番環境へ移行するためにDjangoの設定ファイル(settings.py)を編集します。
settings.pyの重要値をdjango-environを使って管理する
本番環境ではセキュリティ面を考慮してSECRET_KEYなどの重要値を環境変数で管理するのが好ましいです。
つまり、ファイルに重要値を直接記述するのではなく、隠して変数で引っ張ってくるということです。
そして、Djangoでの環境変数の管理はdjango-environを利用します。
$ pip install django-environ
※こちらは後ほど本番環境でインストールする
$ touch .env
※manage.pyと同じディレクトリ階層に作成する
.envに以下の記述をします。
SECRET_KEY=xxxxxxxxxxxxxxxx
ALLOWED_HOSTS=xxx.xxx.xxx.xxx,yourdomain.com
#その他必要な場合はパスワード等の値を記述してください。
※上記の値はsettings.pyで扱います。
DEBUGの条件によって読み込むコードを場合分けする
次に開発環境(DEBUG=True)と本番環境(DEBUG=False)で読み込むコードを場合分けします。
settings.pyに以下のようにコードを追加しましょう。(あくまで一例)
#django-environをインポートする。
import environ
#BASE_DIRを指定する。(environのところで必要なため記述)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
#environの設定をする
env = environ.Env()
env.read_env(os.path.join(BASE_DIR, '.env'))
#シークレットキーを環境変数から引っ張ります。
SECRET_KEY = env('SECRET_KEY')
#本番環境用にFasleに変更します。
DEBUG = Fasle
#本番環境での条件を最後の行に記述します。静的データの場所も指定する。
if not DEBUG:
ALLOWED_HOSTS = env.list('ALLOWED_HOSTS')
STATIC_ROOT = '/usr/share/nginx/html/static'
MEDIA_ROOT = '/usr/share/nginx/html/media'
STATIC_ROOTとMEDIA_ROOTをNginxのディレクトリに設定しています。
※こちらのディレクトリは後で作成する
②ソースコード管理システムにDjangoプロジェクトをプッシュする
次にデプロイするDjangoプロジェクトをGitHubなどのソースコード管理システムにプッシュします。
今回は利用するのはGitHubです。
ソースコードをGitHubへプッシュする場合、一般的にはSSH接続で行います。
SSH接続でGitHubを扱うにはローカルでSSHキーの発行が必要です。
GitHubとのSSHキーでの連携はこちらの記事で解説していますのでご参考ください。
”Cloud9”となっていますが、他のIDE(統合開発環境)などでも基本的な流れは同じです!
Cloud9とGitHubを連携させるには?Cloud9上のソースコードをGitHubに保存するには? 本記事ではこのような疑問を解決します。AWSのCloud9上のソースコードをGitHubに保存しようとして、通常の方法でやってみ[…]
※数分で終わる簡単な操作です!
GitHubとの連携が完了したら、プッシュしたいディレクトリに移動し、以下のコマンドを実行してソースコードをプッシュしましょう。
$ git init
→.gitフォルダを作成する
$ git add -A
→Git管理上にすべてのファイルを追加する
$ git commit -m “first commit”
→Git管理上に先ほど追加したファイルを保存する(“first commit”部分は何でもOK)
$ git remote add origin git@github.com:アカウント名/リポジトリ名.git
→新しいリモートリポジトリの設定をする
$ git push origin master
→ソースコードをプッシュする
③サーバーへ各種ツールをインストールする
ここからはDjangoプロジェクトをデプロイするサーバーの中での操作になります。
全体の流れとしてはSSHでサーバーにアクセスし、そこで各種ツールをインストールしていきます。
なお、今回はubuntuで作業を進めていきます。
SSHでサーバーにアクセスする
まずはSSHでデプロイ先のサーバーへアクセスします。
具体的な手順としては各VPSやEC2(AWS)などの管理画面でキーペアを発行し、ダウンロードしたpemファイルを用いてターミナル等でコマンドを打ち込みます。
操作についてはこちらの記事で解説していますのでご参考ください。
LinuxサーバーへSSH接続する方法とは?EC2や各VPSなどへSSH接続する方法とは? 本記事ではこのような疑問を解決します。ソフトウェアのインストールやデプロイ作業の際に必要になってくるのがSSH接続です。SSH接続とはサーバ[…]
※初めてだと難しく感じますが、数分で終わる簡単な操作です!
pipをインストールする
Pythonパッケージの管理ツールであるpipをインストールします。
$ sudo apt install pip
なお、インストールできない場合は必要に応じてパッケージリストを更新してみましょう。
$ sudo apt update
Nginxをインストールする
今回使用するWebサーバーのNginxをインストールします。
$ sudo apt install nginx
※デフォルトでインストールされている場合は必要なし
Vitualenvをインストールする
先ほどインストールしたpipを使って、Python仮想環境を利用できるVitualenvをインストールします。
$ sudo pip install virtualenv
④DjangoプロジェクトをGitHubからクローンする
デプロイ先のサーバーへGitHubにプッシュしたDjangoプロジェクトをクローンします。
今回クローンするディレクトリは/home/ubuntu内です。
$ git clone
エラーが起きる場合はルートユーザーとして実行すると上手くいきます!
→git cloneに関してはsudoコマンドではなくルートユーザーとしてコマンドを実行する
(これに気づかずに先に進めなかった経験アリ、、、。)
⑤Python仮想環境を構築する
クローンしたDjangoプロジェクトのディレクトリ(manage.pyがあるディレクトリ)に移動し、Python仮想環境を構築します。
VitualenvでPython仮想環境を構築する
先ほどpipでインストールしたVitualenvを使ってPython仮想環境を構築します。
$ cd Djangoプロジェクト名
$ virtualenv 任意の仮想環境名
Python仮想環境を実行する
sourceコマンドを実行してPython仮想環境の中に入ります。
$ source 任意の仮想環境名/bin/activate
必要なPythonパッケージをインストールする
Python仮想環境の中で、必要なPythonパッケージをインストールします。
ここでは以下の4つをインストールします。
(env)$ pip install django, gunicorn, django-environ
gunicornはWebサーバーとDjangoをつなぐWSGIサーバー(詳しくは後述)のことです。
その他必要なパッケージあれば、pipでインストールしておいてください。
マイグレートする
ここでマイグレートもしておきます。
(env)$ python3 manage.py migrate
ここまで終わったら一旦仮想環境を抜けます。
(env)$ deactivate
フリーランスエンジニアが案件獲得方法とは?自ら営業せずに案件を獲得するには?実務経験1年未満でも大丈夫なの? 本記事ではこのような疑問を解決します。これからフリーランスエンジニアとして独立したい方は、兎にも角にも案件の獲得が急務です[…]
⑥Gunicornの設定をする
GunicornはWebサーバーであるNginxとDjangoを連携させる役割を担うWSGI(Web Server Gateway Interface)サーバーです。
また、Linuxサーバーでは「Systemed」というシステム管理を行う仕組みがあり、「systemctlコマンド」でSystemedのコントロールを行います。
そのためGunicornをsystemctlコマンドに登録して運用していきます。
なお、Gunicornはsystemctlに登録された時点で、Daemon(バックグラウンドで動くプログラム)で起動します。
以上の設定を行うために作成するファイルは以下の2つです。
・socketファイル
→Nginxとの接続設定を行うための設定ファイル
・serviceファイル
→Djangoとの接続設定を行うための設定ファイル
socketファイルを作成する
まずはtouchコマンドで以下のディレクトリにsocketファイルを作成しましょう。
ファイル名はDjangoプロジェクト名にしておくとわかりやすいです。
$ touch /etc/systemd/system/Djangoプロジェクト名.socket
socketファイルの中身を以下のように記述します。
[Unit]
Description=gunicorn socket
※socketファイルの説明
[Socket]
ListenStream=/home/ubuntu/Djangoプロジェクト名/Djangoプロジェクト名.sock
※serviceファイルのポート番号を指定(今回はsockファイルを指定)
[Install]
WantedBy=sockets.target
※必ず「sockets.target」を指定
sockファイルはNginxと連携させるためのもので、socketファイルを作成し、Gunicornを起動すると自動生成されます。
serviceファイルを作成する
こちらも同じくtouchコマンドでserviceファイルを作成します。
$ touch /etc/systemd/system/Djangoプロジェクト名.service
serviceファイルの中身を以下のように記述します。
[Unit]
Description=gunicorn daemon
※serviceファイルの説明
Requires=Djangoプロジェクト名.socket
※serviceファイルの起動時に、socketファイルの起動を要求
After=network.target
※必ず「network.target」を指定
[Service]
WorkingDirectory=/home/ubuntu/Djangoプロジェクト名
※Djangoプロジェクトを指定(manage.pyがあるディレクトリ)
ExecStart=/home/ubuntu/Djangoプロジェクト名/Python仮想環境名/bin/gunicorn --workers 3 --bind /home/ubuntu/Djangoプロジェクト名/Djangoプロジェクト名.sock Djangoプロジェクト名.wsgi:application
※通信開始時に起動するコマンドを設定
[Install]
WantedBy=multi-user.target
※必ず「multi-user.target」を指定
Gunicornの操作コマンド
Gunicornは以下のコマンドで操作します。
Gunicornの操作前に、こちらのコマンドでDaemonの再読み込みが毎回必要です。
$ sudo systemctl daemon-reload
Gunicornの起動コマンド
$ sudo systemctl start Djangoプロジェクト名.service
Gunicornの再起動コマンド
$ sudo systemctl restart Djangoプロジェクト名.service
Gunicornの停止コマンド
$ sudo systemctl stop Djangoプロジェクト名.service
Gunicornのステータス確認コマンド
$ sudo systemctl status Djangoプロジェクト名.service
※Djangoプロジェクト名.serviceの「.service」は省略できます。
⑦Nginxの設定をする
次にWebサーバーであるNginxの設定を行います。
ここでやるべきことは以下の2つです。
・Nginxのファイルを作成する
→Gunicornと連携させてDjangoアプリと紐づける
・Nginx用に静的フォルダを設定する
→本番環境用に静的フォルダ(CSSや画像など)を設定する
Nginxのファイルを作成する
Nginxの設定では、既存のNginxファイルに新しく作成する独自Nginxファイルを読み込ませるという流れで作業を進めていきます。
既存のNginxファイルは以下の通りです。
$ cat /etc/nginx/nginx.conf
中身を確認すると、下記の記述があります。
include /etc/nginx/conf.d/*.conf;
これはconf.dディレクトリの中にある設定ファイル「*.conf」を読み込むという意味です。
つまり、conf.dディレクトリの中の〇〇.confと付くファイルをnginx.confで読み込むということです。
そして、このnginx.confに読み込ませる〇〇.confがこれから作成する独自Nginxファイルになります。
それではtouchコマンドで独自Nginxファイルを新しく作成します。
$ touch /etc/nginx/conf.d/Djangoプロジェクト名.conf
そして、このファイルを以下のように編集します。
server {
listen 80;
server_name xxx.xxx.xxx.xxx; #IPアドレスorドメイン名
location /static {
alias /usr/share/nginx/html/static;
}
location /media {
alias /usr/share/nginx/html/media;
}
location / {
proxy_pass http://unix:/home/ubuntu/Djangoプロジェクト名/Djangoプロジェクト名.sock;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
「proxy_pass」にsockファイルを指定して、NginxとDjangoプロジェクトを関連付けさせます。
Nginxの操作コマンド
Nginxは以下のコマンドで操作します。
Nginxを編集した際はこちらのコマンドで内容のチェックを行います。
$ sudo nginx -t
※「ok」「successful」の文言が出れば大丈夫です!
Nginxの起動コマンド
$ sudo systemctl start nginx
Nginxの再起動コマンド
$ sudo systemctl restart nginx
Nginxの停止コマンド
$ sudo systemctl stop nginx
Nginxのステータス確認コマンド
$ sudo systemctl status nginx
Nginx用に静的フォルダを設定する
開発環境ではDjangoプロジェクトのディレクトリ配下に静的フォルダ(staticとmedia)を置き、CSSやJS、画像等を読み込んでいました。
一方、本番環境ではWebサーバー(今回はNginx)が静的フォルダを取り扱います。
①でDjangoのsettings.pyに記述した「STATIC_ROOT」と「MEDIA_ROOT」のディレクトリを実際にmkdirコマンドで作成しましょう。
$ mkdir /usr/share/nginx/html/static
$ mkdir /usr/share/nginx/html/media
次に再度Python仮想環境に入ります。
$ source 任意の仮想環境名/bin/activate
下記のコマンドを実行してDjangoプロジェクトのディレクトリ配下にある静的データを上で作成したフォルダに集めます。
(env)$ python3 manage.py collectstatic
実行したら”yes”を入力して完了すると、本番環境でも静的データが使えるようになります。
ちなみに、上記のcollectstaticコマンドは静的ファイルを編集する度に実行する必要があるので注意しましょう。
⑧SSL化をする
最後にSSL化をして「https」でアクセスできるようにします。
今回のSSL化には「Let’s Encrypt」というSSL化を無料で簡単に行えるツールを使います。
本記事では詳しい説明を省略しますが、Let’s Encryptについてはググると様々な記事で出てくるので、仕組みまで理解したい方はそちらを参考にしてみてください。
Let’s Encryptをインストールする
まずはNginxを一度停止させます。
$ sudo systemctl stop nginx
次にletsencryptをインストールします。
$ sudo apt-get install letsencrypt
こちらでSSL化に必要な証明書を取得します。
$ sudo certbot certonly –standalone -d yourdomain.com
※「yourdomain.com」の部分は自分のものに変えてください。
「Congratulations!」の文言が出れば成功です!
下記のコマンドを実行してキーファイル(pem形式)があることを確認しましょう。
$ cd /etc/letsencrypt/live/ドメイン名
$ ls
fullchain.pemとprivkey.pemがあればOKです。
Nginxのファイルを編集する
最後にNginxファイルを編集していきます。
先ほど作成したNginxファイルは”http”用であるため、”https”用に中身を編集します。
なお、httpでアクセスされた場合にhttpsへリダイレクトさせる記述も追加します。
server {
listen 80;
server_name example.com; #ドメイン名
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name example.com; #ドメイン名
ssl_certificate /etc/letsencrypt/live/ドメイン名/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ドメイン名/privkey.pem;
location /static {
alias /usr/share/nginx/html/static;
}
location /media {
alias /usr/share/nginx/html/media;
}
location / {
proxy_pass http://unix:/home/ubuntu/Djangoプロジェクト名/Djangoプロジェクト名.sock;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Nginxファイルの編集が完了したら、Nginxを再度起動させましょう。
$ sudo systemctl start nginx
ここまで完了すれば「https://ドメイン名」でアクセスできるはずです!
SSL証明書の自動更新設定をする
SSL証明書は90日で期限が切れてしまうため、自動更新設定をする必要があります。
自動更新には、cronという定期的にプログラムを実行するようスケジュールできる機能を利用します。
cronを利用するために以下のcrontabコマンドを実行しましょう。
$ sudo crontab -e
そして、ファイルに下記を追加します。
00 05 01 ** sudo systemctl stop nginx; sudo letsencrypt renew; sudo systemctl start nginx
#"00 05 01"は「毎月1日の5時00分に実行する」という意味
エラーなどで上手くいかない時に確認すべきこと
こちらではエラーなどで上手くいかない時に確認すべきことをまとめました。
初めてのデプロイ作業で詰まりやすいと個人的に感じる点などが中心です。
・ディレクトリやファイルの権限を確認する
→必要に応じてchmodコマンドで権限を変更する
・管理者権限コマンドでの実行を要する処理がたくさんある
→suコマンドでユーザー変更するか、sudoコマンドで実行する
・変更内容が反映されているかどうか確認する
→NginxやGunicornを再起動してみる
・Djangoのセッション管理方法を確認する
→開発環境と本番環境でセッションの管理方法を変えてみる
・全角スペースがないか確認する
→全角スペースが1つでもある場合エラーになるため、半角スペースに直す
まとめ
以上がDjangoアプリをNginxとGunicornを使ってLinuxサーバーへデプロイする方法になります。
デプロイ環境によっては本記事の方法でアプリが正常に動いてくれない可能性もあるかと思います。
私も初めてデプロイした際は複数のデプロイ方法を参考に試行錯誤しました。
ただ1つ言えることは、根気強くググってトライ&エラーを試していけばゴールに辿り着きます。
最後まで諦めずにがんばってください!