Djangoでサイトを作成しようとした際に、デプロイやstaticファイル(CSS/js)の反映あたりで色々詰まったのですが、一元化されている情報源がなかなか見つかりませんでした。
そこでCentOS7の設定〜Djangoチュートリアルのサイトをデプロイし、staticファイルを反映させるまでの手順をまとめてみました。
※ Djangoチュートリアルサイトで作成するサンプルアプリ(pollsアプリ)をデプロイするので、このチュートリアルをこなしていることを前提としています。
※ 普段はWebを書く人では無いので、おかしな点などご指摘頂けると幸いです。
環境
- MacOS X 10.11.6
- CentOS 7 (さくらVPS)
- Apache 2.4.6
- Python 3.6
- Django 2.0
CentOSの設定
基本的な設定はCentOS7.x 基本設定メモを参考にしました。
- 作業用ユーザの作成
[root@hogehoge ~]# useradd username
[root@hogehoge ~]# passwd username
- 作成したユーザをwheelグループに追加し、sudoコマンドを許可
[root@hogehoge ~]# usermod -G wheel username
[root@hogehoge ~]# visudo
## Same thing without a password
# %wheel ALL=(ALL) NOPASSWD: ALL
ここの行の#を外す
[root@hogehoge ~]# vi /etc/pam.d/su
#auth required pam_wheel.so use_uid
ここの行の#を外す
作成したusernameユーザでログインし、sudo su
コマンド等が使える様に。
- sshの設定
先にディレクトリを作成。
[username@hogehoge ~]$ mkdir /home/username/.ssh
[username@hogehoge ~]$ chmod 700 /home/username/.ssh
mac側での鍵を作成。今回は/Users/usename/.ssh/id_rsa_djangoに指定しました。
$ ssh-keygen -C 'for_django'
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/username/.ssh/id_rsa): /Users/username/.ssh/id_rsa_django
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
...
VPSに公開鍵持って行く
$ scp ~/.ssh/id_rsa_django.pub username@[VPSのIPアドレス]:/home/username/.ssh
VPSで公開鍵を設定
[username@hogehoge ~]$ cd /home/username/.ssh
[username@hogehoge .ssh]$ cat id_rsa_django.pub >> authorized_keys
[username@hogehoge .ssh]$ chmod 600 authorized_keys
Mac側でssh接続が可能に。
(sshの接続は/Users/username/.ssh/configに設定を記述しておくと楽ですね。)
$ ssh -i id_rsa_django username@[VPSのIPアドレス]
余談ですが、この時、サーバの設定で詰まった際に何度もCentOS7をインストールし直したりしてると
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
...略
みたいなエラーが出ることが。ssh-keygen -R 123.456.789.33(ホストIP)
で解決する模様。
→参照:SSH接続で WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! って言われて接続を拒否られるとき
- sshdの設定
[username@hogehoge ~]$ sudo vi /etc/ssh/sshd_config
# 以下変更点
# ポート番号を変更
Port 22(任意の数字)
# rootログイン不可
PermitRootLogin no
# pass無し不許可
PermitEmptyPasswords no
# 鍵認証許可
PubkeyAuthentication yes
# pass認証不可
PasswordAuthentication no
# 設定を反映
[username@hogehoge ~]$ sudo systemctl restart sshd.service
- firewallの設定変更
firewallの起動と自動起動設定
[root@hogehoge ~]# systemctl start firewalld.service
[root@hogehoge ~]# systemctl enable firewalld
[root@hogehoge ~]# systemctl status firewalld
http, https, sshでの外部アクセスの許可
[root@hogehoge ~]# firewall-cmd --permanent --add-service=http
[root@hogehoge ~]# firewall-cmd --permanent --add-service=https
[root@hogehoge ~]# firewall-cmd --permanent --add-port=1234(任意のポート番号)/tcp
[root@hogehoge ~]# systemctl restart firewalld
SELinuxを有効にする場合はそちらでも別途設定が必要な様です。
→参照:CentOS7でsshdのポート番号を変更する方法
基礎的ですがひとまずサーバ設定はこんな感じで。
CentOSにPython、Djangoを入れる
- Python3とDjangoのインストール
CentOSにPythonをインストールします。今回はpython3.6を使用する前提で進めます。
→参照:Python3をCentOS7にyumでインストールする手順
[username@hogehoge ~]$ sudo yum install -y https://centos7.iuscommunity.org/ius-release.rpm
[username@hogehoge ~]$ sudo yum search python36
[username@hogehoge ~]$ sudo yum install python36u
- venv仮想環境作成
[username@hogehoge ~]$ python3.6 -m venv venv
# activate
[username@hogehoge ~]$ cd venv/bin
[username@hogehoge ~]$ . activate
(venv)[username@hogehoge ~]$
- Django2.0のインストール
(venv)[username@hogehoge ~]$ pip install Django==2.0
デプロイ
ここではDjango公式サイトのチュートリアルで作成できるpollsアプリをデプロイします。
- 必要なライブラリをインストール
[username@hogehoge ~]$ sudo yum install httpd-devel
[username@hogehoge ~]$ sudo yum install python36u-mod_wsgi
Django2.0のチュートリアルでは↓の様なフォルダ構成になっているかと思います。
sample
├── db.sqlite3
├── manage.py
├── mysite
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── polls
├── __init__.py
├── admin.py
├── apps.py
├── models.py
├── static
├── templates
├── tests.py
├── urls.py
└── views.py
settings.pyのALLOW_HOSTSにIPを指定(*では全て許可)。公開するサイトのドメイン名www.example.com等でも可能
ALLOWED_HOSTS = ['*']
VPS側でdjango_sampleディレクトリを作り、このsampleディレクトリを配置します。今回はGitHubにあげてgit clone
しています。
[username@hogehoge ~]$ mkdir django_sample
[username@hogehoge ~]$ cd django_sample
[username@hogehoge django_sample]$ git clone https://github.com/userid/sample.git(仮)
# この様なディレクトリ構造になる。
username
├── django_sample
└── sample
├── db.sqlite3
.
.
- DjangoのApache用の設定
公式サイトのDjangoをApacheとmod_wsgiとともに使うには?を参考に設定していきます。
まずは/etc/httpd/conf.d/django.confを作成、内容は↓
WSGIScriptAlias / /home/username/django_sample/sample/mysite/wsgi.py
WSGIPythonPath /home/username/django_sample/sample:/home/username/venv/lib/python3.6/site-packages
<Directory /home/username/django_sample/sample/mysite>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
WSGIScriptAliasの最初の/は、ルートURLの設定です。
/mysiteとかにするとhttp://123.456.789.33(仮)/mysite/ がルートURLになります。
WSGIPythonPathでアプリのルートディレクトリ及び仮想環境のライブラリディレクトリを指定しています。
今回はユーザーディレクトリにアプリを置いているので、/etc/httpd/conf.d/userdir.conf ファイルを編集します。
→参照:CentOS7にPython3をインストールしてDjangoを動かす
<IfModule mod_userdir.c>
#
# UserDir is disabled by default since it can confirm the presence
# of a username on the system (depending on home directory
# permissions).
#
UserDir enable
#
# To enable requests to /~user/ to serve the user's public_html
# directory, remove the "UserDir disabled" line above, and uncomment
# the following line instead:
#
#UserDir public_html
</IfModule>
ユーザーディレクトリの権限を変更
[username@hogehoge ~]$ cd /home
[username@hogehoge home]$ sudo chmod 755 username
httpdをリスタート
[username@hogehoge ~]$ sudo service httpd restart
これでルートURL http://123.456.789.33(仮) 等へアクセスすると動作が確認出来る様になるかと思います。
DBへのアクセス権限
このままではadminページへ入る際等に、DBファイルへのアクセスが出来ないというエラーが出るのでdb.sqlite3への権限を変更する必要があります。
色々試して、結局以下の様にその他に権限を与えて何とかしていますが、あまりよろしくない様やり方かと思うので、他のやり方等ご存知の方いましたらご指摘頂けると助かります…。
[username@hogehoge ~]$ cd django_sample
[username@hogehoge django_sample]$ sudo chmod 757 sample
[username@hogehoge django_sample]$ cd sample
[username@hogehoge sample]$ sudo chmod 756 db.sqlite3
[username@hogehoge ~]$ sudo service httpd restart
staticファイルの反映
また、adminページも含め、CSSやjavascriptが反映されていないかと思いますので、Apache等Webサーバからstaticファイルを配信する様設定する必要があります。
manage.py collectstatic
コマンドを使って静的ファイルをSTATIC_ROOTに集め、WebサーバがSTATIC_ROOTをSTATIC_URLの場所で公開する様に設定する形になります。
Django公式サイトのファイルを配信するを参考に設定していきます。まずはsettings.pyの編集。最下部に以下を記述。
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
次に/etc/httpd/conf.d/django.confに以下を追記。
http://123.456.789.33(仮)/static/ 等でstaticファイルにアクセス出来る様になる。
Alias /static/ /home/username/django_sample/sample/static/
<Directory /home/username/django_sample/sample/static>
Require all granted
</Directory>
settings.pyのDEBUGをFalseに変更します。
DEBUG = False
以上の設定を行い、collectstaticコマンドを使うと、/home/django_sample/sample/static下にstaticファイルが集められ、反映されると思います。
(venv) [username@hogehoge sample]$ ./manage.py collectstatic
(venv) [username@hogehoge sample]$ sudo service httpd restart
以上でチュートリアルのpollsアプリがstaticファイルが反映された状態で動作確認出来るかと思います。
補足:複数のアプリで共通のstaticファイルがある場合
例えばcommon下のstaticファイルをpolls/polls2/polls3アプリで利用している場合。
sample
├── db.sqlite3
├── manage.py
├── mysite
│ ├── __init__.py
│ ...
├── polls
├── polls2
├── polls3
└── common
└── static
├── css
├── js
├── images
settings.pyに次の様にSTATICFILES_DIRSを記述します。
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'common/static/'),
)
{% load static %}
<script src="{% static 'js/common.js' %}"></script>
の様な形で共通のstaticファイルを利用することができます。