Django rest API deploy on apache - django

I have created a django application and deployed it on the server.I have run the application through :-
python manage.py runserver 8000 &
and handle the requests on the apache server through proxy
ProxyPass "/" "http://www.example.com/"
ProxyPassReverse "/" "http://www.example.com/".
But there is a issue that I am facing while testing the api through JMeter, when i am running a test case for 10 users my python service over the server gets killed automatically.
What i am doing wrong or what i have to do more to resolve the above test scenario,please suggest?

First of all you need to deploy it on other server like apache. Below I am sharing how as usual configuration of apache2 to deploy a python django project.
Considering virtual environment is created else see how to create
virtual environment
Apache installation:
You need to install apache if not installed yet. Here I am showing the apache2 installation and some other installation which we need.
sudo apt-get update
sudo apt-get install apache2
sudo a2enmod wsgi
sudo apt-get install python3-pip apache2 libapache2-mod-wsgi-py3
configuration of 000-default.conf file : Generally the apache2 is located on linux m at path /etc/apache2/sites-available/000-default.conf. And the configuration file may like that.
<VirtualHost *:80>
ServerName www.something.com
# this is the document root of your project
DocumentRoot /path/to/my-project
# The directory which you can access with base path EX: www.something.com/static/images/image.png
Alias /static /path/to/my-project/static
<Directory /path/to/my-project/static>
Require all granted
</Directory>
<Directory /path/to/my-project/my-project>
<Files wsgi.py>
Header set Access-Control-Allow-Origin "*"
Require all granted
</Files>
</Directory>
WSGIDaemonProcess my-project python-home=/path/to/my_env python-path=/path/to/my-project
WSGIProcessGroup my-project
WSGIScriptAlias / /path/to/my-project/my-project/wsgi.py
ErrorLog /path/to/my-project/logs/error.log
CustomLog /path/to/my-project/logs/access.log combined3
</VirtualHost>
Django project wsgi.py : The django project you created there have a wsgy.py and this file may look like.
python_home = '/path/to/my_env'
import sys
import site
sys.path.append('/path/to/my-project')
sys.path.append('/path/to/my_env/bin')
sys.path.append('/path/to/my_env/lib/python3.6/site-packages')
# Calculate path to site-packages directory.
python_version = '.'.join(map(str, sys.version_info[:2]))
site_packages = python_home + '/lib/python%s/site-packages' % python_version
# Add the site-packages directory.
site.addsitedir(site_packages)
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my-project.settings")
application = get_wsgi_application()
After that you can start you apache2 sever sudo service apache2 start
Also you need to give the permission of you project directory sudo chmod -R 777 /path/to/my-project
This is the basic configuration of apache2 with python django project. Hope this will help to configure any linux machine with your python django project

You cannot using python manage.py runserver 8000 on a server, it's for development ONLY.
You can see the documentation here https://docs.djangoproject.com/en/2.1/howto/deployment/wsgi/
A basic conf for Apache would be :
<VirtualHost *:80>
ServerName yoursite.com
ServerAdmin your#site.com
Alias /media/ /path/to/django-app/media/
<Directory /path/to/django-app/media/>
Require all granted
</Directory>
WSGIScriptAlias / /path/to/django-app/conf/wsgi.py
<Directory /path/to/django-app/conf/>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
</VirtualHost>
You need to adapt this for your project.
If you need to install mod_wsgi : https://modwsgi.readthedocs.io/en/develop/user-guides/quick-installation-guide.html
For me i would use https://docs.djangoproject.com/en/2.1/howto/deployment/wsgi/uwsgi/ it's more convenient (pip install uwsgi)

Related

Django files not found when served with Apache

I deployed my Django project on a Linux server using Linode. When I run it by the python manage.py runserver command on port 8000 everything looks fine. However, when I use apache2 I get the following error when loading the website:
FileNotFoundError at /
[Errno 2] No such file or directory: 'research_files/data.xlsx'
Request Method: GET
Request URL: http://453.33.13.202/
Django Version: 3.1.5
Exception Type: FileNotFoundError
Exception Value:
[Errno 2] No such file or directory: 'research_files/data.xlsx'
In /etc/apache2/sites-available I've created a django_project.conf file which has the following instructions:
Alias /research_files/ /home/alexa/django_project/research_files/
<Directory /home/alexa/django_project/django_project/research_files>
Require all granted
</Directory>
<Directory /home/alexa/django_project/django_project>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
WSGIScriptAlias / /home/alexa/django_project/django_project/wsgi.py>
WSGIDaemonProcess django_app python-path=/home/alexa/django_project python-home=/home/alexa/django_project/venv
WSGIProcessGroup django_app
Then I've enabled that file by running sudo a2ensite django_project and also given access to the folder by running:
sudo chown :www-data django_project/research_files
sudo chmod 664 django_project/research_files
What may be causing this error?
Maybe is the extra / in the first line after research_files, so instead /research_files/ it would be /research_files. This could be a guide also https://stackoverflow.com/a/5684257/15020017

Deploying multiple django sites with mod_wsgi apache linux

I wish to deploy multiple Django sites (say 2 for now - www.example.com, www.example2.com) using apache2 mod_wsgi. Here are the steps I followed in a fresh Ubuntu 16.04 installations.
I've set alias python=python3 in my .bashrc as I am working in python3
packages installed:
apache2 - sudo apt-get install apache2
mod_wsgi - sudo apt-get install libapache2-mod-wsgi-py3
Django(V1.11) - sudo apt-get install python3-django
Then I've created two projects inside
/var/www/
django-admin startproject example
django-admin startproject example2
then I did the followings for both the projects (I've mentioned only one, the other one is exactly the same except replacing example with example2)
/var/www/example/example/settings.py
ALLOWED_HOSTS = ['example.com', 'www.example.com']
/var/www/example/example/wsgi.py
#os.environ.setdefault("DJANGO_SETTINGS_MODULE", "example.settings")
os.environ["DJANGO_SETTINGS_MODULE"] = "example.settings"
/etc/apache2/sites-available/example.conf
<VirtualHost *:80>
ServerName www.example.com
ServerAlias example.com
ServerAdmin admin#example.com
DocumentRoot /var/www/example
WSGIScriptAlias / /var/www/example/example/wsgi.py
ErrorLog /var/www/example/error.log
</VirtualHost>
Also, I've added
/etc/apache2/apache2.conf
WSGIPythonPath /var/www/example
I've called a2ensite for both example.conf and example2.conf
Once I restart apache I could now access www.example.com successfully, but www.example2.com gives an internal server error(500). I thought that's because I've only included one path for WSGIPythonPath in apache2.conf and changed it as
/etc/apache2/apache2.conf
WSGIPythonPath /var/www/example:/var/www/example2
But however, I now get an internal server error(500) for both.
in both cases, the error message is ImportError: No module named example
This is my first deployment by the way. Hense I have no prior experience.
Please direct me what I should do to get both sites up and running.

Django Apache and Virtualenv ImportError: No module named site

The error from apache after a 504 page
[info] mod_wsgi (pid=): Python home /var/venv/mybox.
[info] mod_wsgi (pid=): Initializing Python.
ImportError: No module named site
This is with a barely configured app.
<IfModule mod_wsgi.c>
WSGIDaemonProcess myapp python-home=/var/venv/mybox
WSGIProcessGroup myapp
WSGIScriptAlias / /var/www/html/web/myapp/wsgi.py
WSGISocketPrefix /var/run/wsgi
<Directory /var/www/html/web>
<Files wsgi.py>
Order deny,allow
Allow from all
</Files>
</Directory>
</IfModule>
Followed every post and tutorial I can. I am on CENTOS6 . using virutal env python 2.7 the default system env is 2.6
$ ldd /etc/httpd/modules/mod_wsgi.so
linux-vdso.so.1 => (0x00007ffc06174000)
mywsgi.py
import os,sys
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myapp.settings")
sys.path.insert(0,'/var/www/html/web')
activate_this = '/var/venv/mybox/bin/activate_this.py'
execfile(activate_this, dict(__file__=activate_this))
application = get_wsgi_application()
PYHTONHOME is not set
The documentation for using virtual environments with mod_wsgi can be found at:
http://modwsgi.readthedocs.io/en/develop/user-guides/virtual-environments.html
Most important in your case is the section:
Virtual Environment and Python Version
In that section it states:
When using a Python virtual environment with mod_wsgi, it is very important that it has been created using the same Python installation that mod_wsgi was originally compiled for. It is not possible to use a Python virtual environment to force mod_wsgi to use a different Python version, or even a different Python installation.
You cannot for example force mod_wsgi to use a Python virtual environment created using Python 3.5 when mod_wsgi was originally compiled for Python 2.7. This is because the Python library for the Python installation it was originally compiled against is linked directly into the mod_wsgi module.
So most likely what is happening is that mod_wsgi is compiled for Python 2.6. You cannot in this case force it to use a Python virtual environment created from Python 2.7. When you do this, you will get the error you see about site module being missing.
You will need to uninstall that mod_wsgi from system packages and install mod_wsgi from source code, compiling it against Python 2.7. The easiest way to do this might be to use the pip install method as described in:
https://pypi.python.org/pypi/mod_wsgi
Run pip install to install it in your virtual environment and then follow instructions in section 'Connecting into Apache installation' about configuring Apache to use it.
Solved in CentOS 7 with Apache 2.4.6
My whole server uses Python 2.7, but I've already installed Python 3.6 and my virtualenv is using Python 3.6.
After configured djang.conf (/etc/httpd/conf.d/django.conf) with this code:
<VirtualHost *:80>
WSGIDaemonProcess myProj python-home=/home/user/django-site/env python-path=/home/user/django-site
WSGIProcessGroup myProj
WSGIScriptAlias /myProj /home/user/django-site/my-project/wsgi.py
Alias /static /home/user/django-site/static
<Directory /home/user/django-site/static>
Require all granted
</Directory>
<Directory /home/user/django-site/my-project>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
</VirtualHost>
And restarted my apache
sudo systemctl restart httpd
I got this error a thousand lines (/var/log/httpd/error_log)
ImportError: No module named site
ImportError: No module named site
ImportError: No module named site
ImportError: No module named site
The solution
First:
sudo grep wsgi /var/log/httpd/error_log
I got this:
[mpm_prefork:notice] [pid 62324] AH00163: Apache/2.4.6 (CentOS) PHP/7.0.33 mod_wsgi/3.4 Python/2.7.5 configured -- resuming normal operations
Note the Python version (2.7.5). What I did to get mod_wsgi according to my Python 3.6 is using:
yum list *mod_wsgi*
Installed packages
mod_wsgi.x86_64 3.4-18.el7 #base
Disponible packages
python35u-mod_wsgi.x86_64 4.6.2-1.ius.centos7 ius
python36u-mod_wsgi.x86_64 4.6.2-1.ius.centos7 ius
and then I installed the package python36u-mod_wsgi.x86_64:
sudo yum install python36u-mod_wsgi.x86_64
Then I restarted Apache service:
sudo systemctl restart httpd
And got this new line from logs:
[Fri Mar 29 12:33:26.788716 2019] [mpm_prefork:notice] [pid 76317] AH00163: Apache/2.4.6 (CentOS) PHP/7.0.33 mod_wsgi/4.6.2 Python/3.6 configured -- resuming normal operations
And everything works! :-)
Hope it helps you. C ya!
this is taken fron the Documentation
write this:
WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.py
WSGIPythonPath /path/to/mysite.com
<Directory /path/to/mysite.com/mysite>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
and this is specifically for the virtual env, you need to write the path to the site packeges of your python virtual env:
WSGIPythonPath /path/to/mysite.com:/path/to/your/venv/lib/python3.X/site-packages
the problem may also be in the -
PYTHONHOME
Change the location of the standard Python libraries. By default, the
libraries are searched in prefix/lib/pythonversion and
exec_prefix/lib/pythonversion, where prefix and exec_prefix are
installation-dependent directories, both defaulting to /usr/local.
When PYTHONHOME is set to a single directory, its value replaces both
prefix and exec_prefix. To specify different values for these, set
PYTHONHOME to prefix:exec_prefix.
Try to clean up your PYTHONHOME:
user$ export PYTHONHOME=
On Ubuntu, if you want to use python3, you will have to uninstall libapache2-mod-wsgi-py and install libapache2-mod-wsgi-py3 instead if you obtained your mod_wsgi from the repository.
I was on centos6.X with python 2.7, reinstall of mod_wsgi has fixed the issue for me.
yum remove mod_wsgi.x86_64
yum install mod_wsgi.x86_64
/etc/init.d/httpd restart

Django project not working with Apache and mod-wsgi

I created a droplet(cloud server) on DigitalOcean and with no-ip.com I gave it the hostname - project.ddns.net.By ssh(ing) into the droplet I installed pip and virtualenv.
Inside /var/www/ I created a virtualenv and cloned the repository from github of my project.The directory struture is -
project_revamped (root of the project)
->requirements
->base.txt
->dev.txt
->project (django project)
->static
->media
->apps (folder which contains apps)
->manage.py
->project
->urls.py
->settings
->base.py
->dev.py
I installed apache2 and mod_wsgi using -
sudo apt-get install apache2
sudo apt-get install libapache2-mod-wsgi
I then installed mysql,created a database and installed all requirements
pip install -r base.txt
I created a virtualhost project.conf on the path -
/etc/apache2/sites-available/project.conf
the content of file is this -
<VirtualHost *:80>
ServerAdmin example#gmail.com
ServerName project.ddns.net
ServerName www.project.ddns.net
WSGIScriptAlias / /var/www/project_revamped/project/project/wsgi.py
<Directory /var/www/project_revamped/project/project>
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
Then I gave this command to activate this conf file -
a2ensite project.conf
The content of my wsgi.py in my django project is -
import os
import sys
import site
#Add the site-packages of the chosen virtualenv to work with
site.addsitedir('/var/www/.virtualenvs/projectenv/local/lib/python2.7/site-packages')
#Add the app's directory to the python path
sys.path.append('/var/www/project_revamped/project')
sys.path.append('/var/www/project_revamped/project/project')
os.environ['DJANGO_SETTINGS_MODULE'] = 'project.settings.dev'
#Activate your virtualenv
activate_env = os.path.expanduser('/var/www/.virtualenvs/projectenv/bin/activate_this.py' )
execfile(activate_env, dict(__file__=activate_env))
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
After changing the files I finally gave the commands -
service apache2 reload
service apache2 restart
However after doing these things right the corresponding ip says there is some problem the server and sends 500 error.I guess the problem is somewhere in my configuration because apache server was responding working fine.After I include django project with it the problem starts.
Can anybody please help me here in the configuration? I am stuck in this for past 2 days and every different article on the internet tells the different story.
Have a look at the official documentation. I think you're missing the WSGIPythonPath-directive.
As #BurhanKhalid stated, this linked tutorial is complete and tested and should nearly exactly match your setup.

Django LSB scripts

I have a Django app running under CentOS 6. I want now to add an LSB script to make it running on startup. I googled the topic and didn't really find any intersting stuff.
Do you have some recommendations? some samples? some docs? best practices?
Regards
Apache way:
Setup apache (sudo yum install httpd mod_wsgi)
Configure apache to use your wsgi.py as described in the DJango docs
/sbin/service httpd restart
chkconfig httpd on #this causes apache to start on boot
modify settings.py to put static files in /var/www/html/static and serve them as /static
mkdir /var/www/html/static
sudo python manage.py collectstatic; sudo chown -R apache:apache /var/www/html/static
make sure your wsgi.py etc. is readable by apache
point web browser at http://yourserver.com/
Exampel django.conf to go in /etc/httpd/conf.d
Alias /static/ /var/www/html/static/
WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.py
WSGIPythonPath /path/to/mysite.com
<Directory /path/to/mysite.com/mysite>
<Files wsgi.py>
Require all granted
</Files>
</Directory>