Introduction
This is a note for developing a web app which is used by Django(2.0) and mod_wsgi on a server(CentOS7) because I used to be stuck when I tried to publish my app using mod_wsgi. This was because I used the code python manage.py runserver
to build my app in the local. I hope this article will help you.
In short, you can create virtual environment and set python path on your server.
My develop environment
・ CentOS 7.2
・ Apache 2.4.6
・ Python 3.6.5
・ Django 2.0
To build develop environment on your server
The version from Django2 is subject to only Python3. So, if your server doesn't install Python3 yet, you should.
$ sudo yum install -y https://centos7.iuscommunity.org/ius-release.rpm
$ sudo yum install -y python36u python36u-devel python36u-libs
Symbolic link for Python should be changed to work for typing python3
$ which python3.6
/usr/bin/python3.6
$ sudo ln -s /usr/bin/python3.6 /usr/bin/python3
$ python3 -V
Python 3.6.5
To install pip.
$ sudo yum install epel-release
$ sudo yum install python-pip
To build the virtual environment.
$ pip install virtualenv
$ cd [project dir]
$ python3 -m venv [newenvname]
$ source [newenvname]/bin/activate
([newenvname])$ python -V
Python 3.6.5
When you want to escape from your virtual environment, you can just type deactivate
.
You can install some library you need through pip.
([newenvname])$ pip install django mod-wsgi
If you cannnot install "mod-wsgi", you should install the following library before you install mod-wsgi.
yum install httpd httpd-devel
Setting of apache
I recommend you to copy your default httpd.conf as a backup.
$ cp /etc/httpd/conf/httpd.conf /
$ vim /etc/httpd/conf/httpd.conf
Write the following code at the last line in httpd.conf.
IncludeOptional conf.d/*.conf
Make sure the path of wsgi_module.
$ mod_wsgi-express module-config
LoadModule wsgi_module "{mod_wsgi-py-path}"
WSGIPythonHome "{home-path}"
Create new .conf file.
$ vim /etc/httpd/conf.d/django.conf
Add this code.
NameVirtualHost *:80
LoadModule wsgi_module "{mod_wsgi-py-path}"
WSGISocketPrefix /var/run/wsgi
<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/html/xxx
WSGIDaemonProcess xxx python-home=/usr/{newenvname} python-path=/usr/xxx
WSGIProcessGroup xxx
WSGIScriptAlias / /usr/xxx/xxx/wsgi.py
Alias /static/ /var/www/html/xxx/static/
<Directory /var/www/html/xxx/static>
Require all granted
</Directory>
<Directory /usr/xxx/xxx>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
</VirtualHost>
※{newenvname} and "xxx" shoud be changed by depending on your environment.
Restart the apache on your server.
# make sure the condition of your server
systemctl status httpd.service
# restart the apache
systemctl restart httpd.service
# confirm log
tail -f /var/log/httpd/error_log
If you want your multi services run on your one server
You can copy and paste the following code to django.conf.
NameVirtualHost *:80
LoadModule wsgi_module "{mod_wsgi-py-path}"
WSGISocketPrefix /var/run/wsgi
<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/html/xxx
WSGIDaemonProcess xxx python-home=/usr/{newenvname} python-path=/usr/xxx
WSGIProcessGroup xxx
WSGIScriptAlias / /usr/xxx/xxx/wsgi.py
Alias /static/ /var/www/html/xxx/static/
<Directory /var/www/html/xxx/static>
Require all granted
</Directory>
<Directory /usr/xxx/xxx>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
</VirtualHost>
<VirtualHost *:80>
ServerName sample.com
DocumentRoot /var/www/html/yyy
WSGIDaemonProcess yyy python-home=/usr/{newenvname} python-path=/usr/yyy
WSGIProcessGroup yyy
WSGIScriptAlias / /usr/yyy/yyy/wsgi.py
Alias /static/ /var/www/html/yyy/static/
<Directory /var/www/html/yyy/static>
Require all granted
</Directory>
<Directory /usr/yyy/yyy>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
</VirtualHost>
The point is to separate WSGIDaemonProcess and WSGIProcessGroup.
Deal with error
When you encounter the following error, make sure if python-path
or python-home
is correct. Otherwise, you can check your file access permissions.
Error ImportError: No module named 'encodings'
or
ModuleNotFoundError: No module named 'myProject'
Refference
- [Japanese] To install Python3 and pip on CentOS7
- [Japanese] To manage venv by Python
- mod_wsgi - Official Docs
- Virtual Environments
- Error ImportError: No module named 'encodings' in virtual environment using pyenv
- Django ModuleNotFoundError: No module named 'myProject'
- How To Serve Django Applications with Apache and mod_wsgi on Ubuntu 16.04