Prerequisites
- Django version: 2.1.7
- Python version: 3.6.7
- CentOS 7 (virtualbox)
Install Nginx
Add the following repository:
$ sudo rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
Then install nginx.
$ sudo yum update
$ sudo yum install -y nginx
Start and enable nginx.
$ sudo systemctl start nginx
$ sudo systemctl enable nginx
Install Python3
Enable IUS repository:
$ sudo yum install -y https://centos7.iuscommunity.org/ius-release.rpm
Install Python3.6 modules:
$ sudo yum install -y python36u python36u-libs python36u-devel python36u-pip python-pip gcc
To check if Python 3.6 is successfully installed, do the following commands:
$ sudo python3.6 -V
$ sudo which python3.6
SELinux
SELinux interrupts Apache for security reasons. I think it is better to disable SELinux permanently in the development environment.
$ sudo setenforce 0
And open the "/etc/selinux/config" file and set the SELinux to disabled:
$ sudo vi /etc/selinux/config
And change it like this:
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=disabled #Change HERE!!!!!
# SELINUXTYPE= can take one of three two values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=targeted
Use venv of Python3
Go to your directory and use the venv:
$ cd /vagrant
$ python3.6 -m venv django-test
$ cd ./django-test
$ source bin/activate
And you will have a separated environment of your Python. In the virtual environment, you can use different version of Python and modules from the ones in the host machine.
Please note that you can exit the virtual environment as follows (but don't exit yet):
$ deactivate
Upgrade your pip of python3 just in case:
$ python3.6 -m pip install --upgrade pip
Install Django
Install Django as follows:
$ cd /vagrant/django-test
$ python3.6 -m pip install Django
$ django-admin.py startproject mysite
$ cd mysite
Add allowed host
Add "192.168.33.10" to "Allowed_Hosts" in the following file:
$ sudo vi /vagrant/django-test/mysite/mysite/settings.py
Change the allowed hosts as follows:
How to use vi editor is here:
Press a on your keyboard to be insert mode and you can edit the file. Press escape key to stop the insert mode. After stopping the insert mode, press Shift + g to go to the lowest row. :wq or Shift + zz to save and close the file. You can go to command mode by pressing : on your keyboard. To exit the file without saving the file, input :q! and enter. To search a word, press ? then write a word what you want to search. For example, if you write ?aaa and press enter, "aaa" is searched and highlighted in the file. Press n to jump to next match.)
Check if Django properly works by its built-in server:
$ cd /vagrant/django-test/mysite
$ python3.6 manage.py runserver 0.0.0:8000
And you should see django's install success message on this URL: http://192.168.33.10:8000/
Stop the built-in server by pressing
CTRL + c
once you check the install worked successfully.Install uWSGI
Install uwsgi:
$ cd /vagrant/django-test/mysite
$ python3.6 -m pip install uwsgi
Check the version:
$ uwsgi --version
2.0.18
Hello World
views.py
Add a top-level module as follows:
$ cd /vagrant/django-test/mysite
$ python3.6 manage.py startapp mywebsite
Then open the 'views.py':
$ sudo vi /vagrant/django-test/mysite/mywebsite/views.py
and write as follows:
from django.shortcuts import render
# Create your views here.
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world Django!!!!")
urls.py (mywebsite)
Now create a file named as
urls.py
:$ sudo vi /vagrant/django-test/mysite/mywebsite/urls.py
Then write as follows inside so that it will call
index
function from views.py
when accessed the root path:from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]
urls.py (mysite)
Change
urls.py
file of mysite
too.$ sudo vi /vagrant/django-test/mysite/mysite/urls.py
Change it as follows. Make sure you import
include
from django.urls
:from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('mywebsite/', include('mywebsite.urls')),
path('admin/', admin.site.urls),
]
Check if it works
Check if Django properly works by its built-in server:
$ cd /vagrant/django-test/mysite
$ python3.6 manage.py runserver 0.0.0:8000
Go to http://192.168.33.10:8000/mywebsite/ and you will see the message you defined in index function.
Check if uWSGI can connect to Django
Check if uWSGI can connect to Django by the following command:
$ cd /vagrant/django-test/mysite/mysite
$ uwsgi --http :8000 --module mysite.wsgi
Go to http://192.168.33.10:8000/mywebsite/ and you will see the message you defined in index function.
Use Nginx and uWSGI together
Create
mysite_nginx.conf
:$ sudo vi /vagrant/django-test/mysite
/mysite/mysite_nginx.conf
And write as follows and save it:
# mysite_nginx.conf
# the upstream component nginx needs to connect to
upstream django {
# server unix:///path/to/your/sockfile.sock; # for a file socket
server 127.0.0.1:8001; # for a web port socket (we'll use this first)
}
# configuration of the server
server {
# the port your site will be served on
listen 8000;
# the domain name it will serve for
server_name 192.168.33.10; # substitute your machine's IP address or FQDN
charset utf-8;
# max upload size
client_max_body_size 75M; # adjust to taste
# Django media
location /media {
alias /vagrant/django-test/mysite/media; # your Django project's media files - amend as required
}
location /static {
alias /vagrant/django-test/mysite/static; # your Django project's static files - amend as required
}
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_pass django;
include /etc/nginx/uwsgi_params; # the uwsgi_params file you installed
}
}
Create a symlink so that Nginx can see the conf:
$ sudo ln -s /vagrant/django-test/mysite/mysite/mysite_nginx.conf /etc/nginx/conf.d/
Restart Nginx:
$ sudo systemctl restart nginx
Start uWSGI:
$ cd /vagrant/django-test/mysite/mysite
$ uwsgi --socket :8001 --module mysite.wsgi
You can see your django app is working on http://192.168.33.10:8000/mywebsite/ without the build-in server because it is using Nginx now. Stop the uWSGI by pressing
CTRL+c
.Deploying static files
Open the following file:
$ sudo vi /vagrant/django-test/mysite/mysite/settings.py
Add the following:
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
as follows:
And run:
$ cd /vagrant/django-test/mysite/mysite
$ python3.6 manage.py collectstatic
Use Unix sockets instead of ports
Edit
mysite_nginx.conf
and change the upstream django
:upstream django {
server unix:/var/run/mysite.sock; # for a file socket
# server 127.0.0.1:8001; # for a web port socket (we'll use this first)
}
Restart Nginx:
$ sudo systemctl restart nginx
Run uWSGI:
$ sudo /vagrant/django-test/bin/uwsgi --socket /var/run/mysite.sock --module mysite.wsgi --chmod-socket=666
Check if it works: http://192.168.33.10:8000/mywebsite/.
You can deamonize the uwsgi:
$ sudo /vagrant/django-test/bin/uwsgi --socket /var/run/mysite.sock --module mysite.wsgi --chmod-socket=666 --daemonize /var/log/uwsgi.log
To check nginx error log:
$ sudo less /var/log/nginx/error.log
Note
- You can not put the socket file in /tmp directory because the files in /tmp might not be seen by Nginx. (/tmp can cause no such file or directory error.)
References
- Setting up Django and your web server with uWSGI and nginx - uWSGI
- Nginx no such file or directory error - stackoverflow