VPSを契約してからCentOS + Nginx + uWSGI でDjangoアプリをデプロイするまで
はじめに
Djangoで作っていたアプリを、VPS借りて動かしたいと思ったときにいろいろ躓いたのでメモ。
前提
- CentOS 7.6
- VPSは契約済(この記事ではConohaVPS)。
構成
イメージとしては下記のようになる
Web Browser <--> Nginx <--> socket <--> uWSGI <--> Djnago <--> SQLite
リポジトリを作成
下記コマンドでリポジトリを作成する
# yum install -y https://centos7.iuscommunity.org/ius-release.rpm
きちんと作成されているか確認
# yum install -y https://centos7.iuscommunity.org/ius-release.rpm
Pythonをインストールする
Pythonをインストールし、エイリアスを登録しておく
# yum install -y python36u python36u-libs python36u-devel python36u-pip
# alias puthon3='python3.6'
SSH、firewallの設定
SSHのポート番号が22というのは広く知れ渡っているため、悪意のあるロボットの「無作為IPアドレス+22番ポート」
攻撃から身を守る必要がある。そのため、ポートを変えたほうが良いとのこと。
まず、firewallの起動と自動起動設定を行う。
# systemctl start firewalld.service
# systemctl enable firewalld
# systemctl status firewalld
次に、http、https、sshでの外部アクセスを許可する。また、80も空けておく。
# firewall-cmd --permanent --add-service=http
# firewall-cmd --permanent --add-service=https
# firewall-cmd --permanent --add-port=xxxxx(任意のポート番号)/tcp
# firewall-cmd --permanent --zone=public --add-port=80/tcp
# systemctl restart firewalld
/etc/ssh/sshd_configファイルを編集する。
# vi /etc/ssh/sshd_config
...略...
#Port 22 ← デフォルトはポート番号22
Port 54321 ←【例】任意の空きポート番号を指定する
...略...
設定反映を行う。
# service sshd restart
設定したポートでSSHで接続できるか確認する。
SQLiteの最新化
後でDjangoを入れて、サーバーを起動すると、SQLiteのバージョンが古いとエラーが発生する。
django.core.exceptions.ImproperlyConfigured: SQLite 3.8.3 or later is required (found 3.7.17).
そのため、新しいSQLiteを入れてあげる必要がある。
まず、最初はCのコンパイラが入ってないので入れてあげる。
# yum -y install gcc
SQLiteのソースを取得、ビルドしてインストールまで行う。
# wget https://www.sqlite.org/2019/sqlite-autoconf-3290000.tar.gz
# tar zxvf ./sqlite-autoconf-3290000.tar.gz
# cd ./sqlite-autoconf-3290000
# ./configure --prefix=/usr/local
# make
# make install
# find /usr/ -name sqlite3
不要なファイルを削除する。
# cd ..
# rm -rf ./sqlite-autoconf-3290000 ./sqlite-autoconf-3290000.tar.gz
新しいSQLiteを適用する。
# mv /usr/bin/sqlite3 /usr/bin/sqlite3_old
# ln -s /usr/local/bin/sqlite3 /usr/bin/sqlite3
# echo 'export LD_LIBRARY_PATH="/usr/local/lib"' >> ~/.bashrc
# source ~/.bashrc
下記でバージョンを確認すると、新しくなっていることが確認できる。
# sqlite3 --version
nginxを入れる
下記コマンドでインストールする。
# rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
# yum install nginx -y
デプロイ先ディレクトリ、仮想環境の作成
今回は/var/www/配下にいろいろ作っていきます。
// デプロイ先ディレクトリ作成
# mkdir -p /var/www/test_mysite
// 仮想環境の作成
# cd /var/www/test_mysite
# python3 -m venv myvenv
// 仮想環境を有効化
# source myvenv/bin/activate
パッケージをインストール
pipで必要なパッケージをインストールする。
// pipを更新
(myvenv)# pip install --upgrade pip
// 仮想環境にDjangoをインストール
(myvenv)# pip install django
// 仮想環境にuWSGIをインストール
(myvenv)# pip install uwsgi
Djangoプロジェクトも作成しておく。
(myvenv)# django-admin startproject mysite
// 一旦仮想環境を無効にする
(myvenv)# deactivate
uWSGIの設定
socketファイルとpidファイルを格納するディレクトリを作成し、所有者や権限を変更する。
// ディレクトリ作成
# mkdir -p /var/run/uwsgi
// 所有者変更
# chown root:nginx /var/run/uwsgi
// 権限変更
# chmod +w /var/run/uwsgi
先ほど作成した仮想環境myvenv配下にuWSGIのための変数を定義するファイルuwsgi_paramsを作成する。
// 移動
# cd /var/www/test_mysite/myvenv
// ファイル作成
# vi uwsgi_params
uwsgi_param QUERY_STRING $query_string;
uwsgi_param REQUEST_METHOD $request_method;
uwsgi_param CONTENT_TYPE $content_type;
uwsgi_param CONTENT_LENGTH $content_length;
uwsgi_param REQUEST_URI $request_uri;
uwsgi_param PATH_INFO $document_uri;
uwsgi_param DOCUMENT_ROOT $document_root;
uwsgi_param SERVER_PROTOCOL $server_protocol;
uwsgi_param REQUEST_SCHEME $scheme;
uwsgi_param HTTPS $https if_not_empty;
uwsgi_param REMOTE_ADDR $remote_addr;
uwsgi_param REMOTE_PORT $remote_port;
uwsgi_param SERVER_PORT $server_port;
uwsgi_param SERVER_NAME $server_name;
同じくmyvenv配下にuwsgi.iniファイルを作成する。
// 移動
# cd /var/www/test_mysite/myvenv
// ファイル作成
# vi uwsgi.ini
[uwsgi]
uid = nginx
gid = nginx
# 作成したDjangoアプリのルートを指定する
chdir = /var/www/test_mysite/mysite
# wsgi.pyの場所を指定する
# (Djangoのプロジェクト名を「mysite」にするとmysite/配下にwsgi.pyがあるはず)
module = mysite.wsgi
# 仮想環境の場所を指定する
home = /var/www/test_mysite/myvenv
master = true
processes = 2
threads = 1
# 先ほど作成したsocketとpidファイルの作成場所を指定する
socket = /var/run/uwsgi/master.sock
pidfile = /var/run/uwsgi/master.pid
chmod-socket = 666
vacuum = true
thunder-lock = true
max-requests = 6000
max-requests-delta = 300
# log
logto = /var/log/uwsgi/uwsgi.log
deamonize = /var/log/uwsgi/uwsgi-@(exec://date +%Y-%m-%d).log
log-reopen = true
iniファイルの文法はこちらを参考にさせていただきました。
サーバーを再起動したときにuWSGIが自動で起動するように[/etc/systemd/system/]配下にuwsgi.serviceを作成する。
// 移動
# cd /etc/systemd/system
// ファイル作成
# vi uwsgi.service
# uwsgi.service
[Unit]
Description=uWSGI
After=syslog.target
[Service]
ExecStartPre=/bin/bash -c 'mkdir -p /var/run/uwsgi; chown root:nginx /var/run/uwsgi; chmod g+w /var/run/uwsgi;'
# 自分が作成した仮想環境配下のactivateとuwsgi.iniファイルを指定する。
ExecStart=/bin/bash -c 'source /var/www/test_mysite/myvenv/bin/activate; uwsgi --ini /var/www/test_mysite/myvenv/uwsgi.ini'
#Restart=always
Restart=on-failure
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all
[Install]
WantedBy=multi-user.target
サービスの自動起動をONにする。
// サービスの停止
# systemctl stop uwsgi
// サービスの自動起動の有効化
# systemctl enable uwsgi
// サービスの開始
# systemctl start uwsgi
nginxの設定
こちらを参考にさせていただきました。
同一サーバーで複数のアプリケーションを運用することも想定し、バーチャルホストの設定を行う。
まず、[/etc/nginx/sites-available]と[/etc/nginx/sites-enabled]を作成する。
// 設定ファイルを格納するディレクトリを作成する。
# mkdir /etc/nginx/sites-available
// 有効にしたいバーチャルホストの設定ファイルへのシンボリックリンクを格納するディレクトリ
# mkdir /etc/nginx/sites-enabled
[/etc/nginx/sites-available]配下に設定ファイルを作成する。
// 移動
# cd /etc/nginx/sites-available
// ファイル作成(名前は任意)
# vi test_mysite
# Djangoの設定
upstream django {
# 上記で設定したソケットファイルの場所を指定する。
server unix:///var/run/uwsgi/master.sock;
}
# サーバの設定
server {
# ポート番号
listen 80;
# VPSのIPアドレスを入力する
server_name [IPアドレス];
charset utf-8;
# Djangoの静的ファイルの設定
location /static {
# staticディレクトリが存在する場所を指定する。
# python manage.py collectstaticをするとプロジェクト直下のstaticに集約されるので、プロジェクト直下を指定しておく。
root /var/www/test_mysite/mysite;
}
location / {
uwsgi_pass django;
# 上記で設定したuwsgi_paramsの場所を指定する
include /var/www/test_mysite/myvenv/uwsgi_params;
}
}
nginxが起動したときに[/etc/nginx/sites-enabled]配下を読み込むようにして、[/etc/nginx/sites-enabled]配下では[/etc/nginx/sites-available]の設定ファイルへのシンポリックリンクを張ったり削除することで、バーチャルホストの設定を有効にしたり、無効にしたりし、管理を楽にする。
上記で作成した設定ファイルのシンボリックリンクを[/etc/nginx/sites-enabled]に貼る。
// 有効にしたいバーチャルホストの設定ファイルへリンクを張る。
# ln -s /etc/nginx/sites-available/test_mysite /etc/nginx/sites-enabled/test_mysite
[/etc/nginx/]配下にあるnginx.confを修正し、[/etc/nginx/sites-enabled]を見るようにする。
http {
...
#gzip on;
+ include /etc/nginx/sites-enabled/*;
include /etc/nginx/conf.d/*.conf;
...
}
OSを再起動してもnginxを自動で起動するようにする。[/etc/systemd/system/]配下にnginx.serviceを作成する。
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
サービスの自動起動をONにする。
// サービスの停止
# systemctl stop nginx
// サービスの自動起動の有効化
# systemctl enable nginx
// サービスの開始
# systemctl start nginx
Djangoの設定
Djangoのマイグレーション等を行う
# cd /var/www/test_mysite
# source myvenv/bin/activate
(myvenv)# cd mysite
// マイグレーションを行う
# python3 manage.py makemigrations
# python3 manage.py migrate
また、Djangoの設定ファイルを編集する。まずはsetting.pyのALLOWED_HOSTSを編集する。
・・・略・・・
ALLOWED_HOSTS = ['IPアドレスまたはドメイン']
・・・略・・・
静的ファイルを下記コマンドで集める
(myvenv)# python3 manage.py collectstatic
これでアクセスできるようになるはず
VPSのIPアドレスで接続すれば、Djangoのページが出てくるはず。
もし、エラーが出た場合は、nginxのログファイル(/var/log/nginx/error.log)やuWSGIのログファイル(/var/log/uwsgi/uwsgi.log)を確認してみる。
Djangoのデバッグエラー画面が出てきたときのメモ
setting.pyにてDEBUGモードをTrueにしたままだったので、何も問題が発生しなければFalseにするべきだが、いくつかエラーが発生したので、その解決方法をメモしておく。
unable to open database file と出てくるとき
SQLiteが開けないと怒られるエラー。SQLiteは、データベースファイルへの書き込み権限だけでは無く、ディレクトリにも書き込み権限が無いとダメらしい。
そのため、権限を見直すと解決する。
SQLite 3.8.3 or later is requiredと出てくるとき
上でSQLiteを新しくして、python manage.py runserverでは普通に動くのに、ブラウザからアクセスすると上記のエラーで怒られた。
原因はさっぱりわからなかったので、怒られてる該当箇所を書き換えた。趣味レベルだったらこれでいいかなと。
怒られてるファイル(/var/www/test_mysite/myvenv/lib64/python3.6/site-packages/django/db/backends/sqlite3/base.py)を編集する。
・・・略・・・
def check_sqlite_version():
# if Database.sqlite_version_info < (3, 8, 3):
if Database.sqlite_version_info < (3, x, x):
raise ImproperlyConfigured('SQLite 3.8.3 or later is required (found %s).' % Database.sqlite_version)
・・・略・・・
Author And Source
この問題について(VPSを契約してからCentOS + Nginx + uWSGI でDjangoアプリをデプロイするまで), 我々は、より多くの情報をここで見つけました https://qiita.com/watchmen-r/items/9a6c8447c1a03ea3c842著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .