Django blog development tutorial 14 – deploying Django blogs with nginx and gunicorn

Time:2020-3-28

The basic functions of our blog have been basically developed. Although there are many places to improve, we still hope to deploy the blog to the server early so that others can access it through the Internet. As for the areas that need to be improved, we can iterate and improve a little bit after deployment. Now let’s deploy the blog to the server!

Note: each step of this article is verified in the real environment. Unless you know what you’re doing, we recommend that you follow the tutorial’s instructions at every step to ensure your deployment is successful.

Preparation before deployment

We will use the popular nginx + gunicorn method to deploy the blog developed by Django to our own server, so that others can access your blog through the domain name. As for what nginx and gunicorn are temporarily put aside, you will know their functions and usage after reading this tutorial.

In order to deploy our blog, we need to meet the following two conditions:

  1. There is a server that can be accessed through the Internet.

  2. There is a domain name.

If you have met the above conditions, you can directly jump to the build server section. Here is a brief introduction to the way I know to meet the above two conditions at the lowest cost.

Purchase server

If you are a student, you are recommended to purchase Alibaba cloud server. The student discount is 9.9 yuan / month, and the server performance is relatively high. Purchase address: Alibaba cloud server student zone. The specific purchase steps will not be described here. According to the guidance of the website, I believe that you can purchase successfully. It’s just important to select the server typePublic mirroring, so the system is relatively pure. Recommended operating systemUbuntu 14.04 64 bit, which is the server environment used in this tutorial.

If you are not a student, it is recommended to buy VPS. At present, the cheapest one is $19.9/year. The disadvantage is that the server performance is not as high as Alibaba cloud, but the advantage is that it can be used as a ladder by the way. It is not a dream to visit Google and Youtube from then on (based on shadowlocks, you can build your own ladder server in a few steps). In the same way, the purchase process will not be described in detail. There are super detailed guidelines on VPS. It is only recommended to install the operating systemUbuntu 14.04 64 bit, which is the server environment used in this tutorial.

If you don’t need that money, choose a cloud server provider to buy a cloud server at will.

Purchase domain name

There are many domain name service providers. I use the alicloud domain name registration system here. Domain name is the doorplate of the website. If you plan to operate the website for a long time, you should consider more and choose an appropriate domain name. If it’s just for testing, just register a domain name at will. Some domain names with very common suffixes are very cheap, usually 10 yuan / year. However, it should be noted that according to the regulations of the Ministry of industry and information technology, the following suffix domain names can only be used after real name authentication:

. CN /. COM /. Net /. Top /. XYZ /. VIP /. Club /. Ren /. Wang /. Shop /. Xin /. China /. Information /. Company /. Network /. Guangdong /. Foshan

If you buy the domain name with the suffix above, it means that you need to submit the real name authentication of personal identity data before normal use, which usually takes several days. So if it’s only for testing and learning deployment, it’s best to avoid the domain names with the above suffixes.

Set up the server

The local environment used in this tutorial is windows 10, and the server environment is Ubuntu 14.04 (64 bit).If there is a difference between your environment and mine that makes some commands unable to be executed, just convert these commands to the command execution of your environment.

###Remote login to server

The server is usually located in the cloud. You need to use the remote login tool to log in before you can operate the server. I use the X shell, which can be downloaded and installed under windows. The software is free for school and individual users.

How to log in to the server remotely is not covered here. I believe you can log in smoothly by referring to some online tutorials. If you use xshell like me, here’s a very detailed tutorial for you: how to use xshell to connect to Linux server remotely.

Installation software

Successfully connected to the remote server. If it’s a new server, we usually log in as root. It is not safe to deploy the code under root. It is better to create a new user (you can skip this step if you are already logged in as a non root user). Some of the following column commands create a new user with super Rights:

#Run this command under root to create a new user. Yangxg is the user name
#Because my name is Yang Xueguang, my user name is yangxg
#Choose a user name you like. It doesn't have to be the same as mine
[email protected]:~# useradd -m -s /bin/bash yangxg

#Add the newly created user to the super permission group
[email protected]:~# usermod -a -G sudo yangxg

#Set password for new users
#Note that there will be no character display when inputting the password. Don't think the keyboard is broken. Just input it normally
[email protected]:~# passwd yangxg

#Switch to the new user created
[email protected]:~# su - yangxg

#The switch is successful. The @ symbol is preceded by a new user name instead of root
[email protected]:~$

New user created and switched successfully. If it’s a new server, it’s better to update the system first to avoid the trouble of later software installation due to the old version. Run the following two commands:

[email protected]:~$ sudo apt-get update
[email protected]:~$ sudo apt-get upgrade

Next, you can install the necessary software. The software we need here are nginx, pytohn3, GIT, PIP and virtualenv.

[email protected]:~$ sudo apt-get install nginx
[email protected]:~$ sudo apt-get install git python3 python3-pip
[email protected]:~$ sudo pip3 install virtualenv

Resolve domain name to server IP address

After binding the domain name with the IP address of the server, the user can access the server by entering the domain name in the browser.

All major domain name service providers provide domain name resolution services, but their configuration interfaces are different. Please complete domain name resolution according to their guidelines. Here is the alicloud domain name resolution page I used.

Django blog development tutorial 14 - deploying Django blogs with nginx and gunicorn

Start nginx service

Nginx is used to process static file requests. For example, when we visit a blog post details page, the server will receive the following two requests:

  • Display the detailed information of the article, which is usually saved in the database, so you need to call the database to get the data.

  • Pictures, CSS, JS and other static files exist in a folder of the server.

For the former request, the blog post data needs to be obtained from the database by Django. If nginx can’t handle it, it will forward the request to Django for Django to handle. For the latter kind of static file request, you only need to go to the folder where these static files are located to get them, and nginx will handle it instead, without bothering Django.

Using Django to get static files is very time-consuming, but nginx can handle it efficiently, which is why we need to use nginx (of course, its functions are far more than that).

Through the previous steps, we have installed nginx and bound the domain name and server IP. Run the following command to start the nginx service:

[email protected]:~$ sudo service nginx start

Enter the domain name in the browser, and see the following page to indicate that nginx is started successfully.

Django blog development tutorial 14 - deploying Django blogs with nginx and gunicorn

Deployment code

Project configuration before deployment

There will be some static files such as CSS and JavaScript in Django project. In order to facilitate nginx to handle the requests of these static files, we collect all the static files in the project into a unified directory, which is usually located in the root directory of Django project and named static. In order to complete these tasks, you need to do some necessary configuration in the configuration file of the project:

blogproject/settings.py

#More configuration

STATIC_URL = '/static/'
#Add the following configuration
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

Static? Root indicates the collection directory of static files, which is the static folder under the project root directory (base? DIR).

For safety reasons, it needs to be shut down in the production environmentDEBUGOptions and set the domain name that is allowed to access. Open the settings.py file and findDEBUGandALLOWED_HOSTSThese two options are set to the following values:

blogproject/settings.py

DEBUG = False
ALLOWED_HOSTS = ['127.0.0.1', 'localhost ', '.zmrenwu.com']

ALLOWED_HOSTSIs the list of domain names allowed to access. 127.0.0.1 and localhost are the domain names for local access. Zmrenwu.com is the domain name of the access server(Change to your own domain name) Add a dot before the domain name to indicate that you are allowed to access the subdomain under the domain name, such as www.zmrenwu.com, test.zmrenwu.com and other secondary domain names. Only zmrenwu.com can be accessed without the preceding points.

The project also relies on some third-party Python libraries. To facilitate one-time installation on the server, we will write all the dependencies to a text file called requirements.txt. activationlocalIf you use the virtual environment, go to the root directory of the project and runpip freeze > requirements.txtOrder:

(blogproject_env) C:\Users\yangxg\Workspace\blogproject>
pip freeze > requirements.txt

At this time, a text file of requirements.txt will be generated under the root directory of the project, whose contents record all the dependencies of the project.

Upload code to GitHub

Upload the code to GitHub and other code hosting platforms, so that we can easily pull the code to the server. I’m sure you are familiar with the use of GIT and GitHub, so I won’t go over the process here. If you don’t know how to use the land, you can do Baidu related tutorials by yourself.

Do not upload the database file!

Set server directory structure

Next you need to upload the code to the server. The directory structure for storing code on my server is generally as follows:

/home/yangxg/
    sites/
        demo.zmrenwu.com/
            env/
            django-blog-tutorial/

A server may deploy multiple websites, and all website codes are placed in the sites / directory. Demo.zmrenwu.com/ this folder is named after the domain name of the website, which is easy to distinguish. Env / is the python virtual environment directory. Django blog tutorial / is the Django blog project directory.

So first create the directory structure,Note that the directory name should be replaced with your own domain name. In the future, where demo.zmrenwu.com is involved, you usually need to replace your own domain name, which will not be pointed out later, run the following command,

[email protected]:~$ mkdir -p ~/sites/demo.zmrenwu.com

Here ~ represents the home directory of the current user, that is, / home / yangxg /.

Next, create a virtual environment, first enter the demo.zmrenwu.com directory, and then run the virtualenv command to create a virtual environment:

[email protected]:~$ cd ~/sites/demo.zmrenwu.com
[email protected]:~/sites/demo.zmrenwu.com$ virtualenv --python=python3 env

Note that — python = python3 is used here to specify the environment in which to clone Python 3. Because Python 2 is installed by default on Ubuntu system, if not specified, virtual env will clone the environment of Python 2 by default.

Check whether the virtual environment is created successfully. Run LS command to list the files and folders in the current directory. See Env, which means the virtual environment is created successfully.

[email protected]:~/sites/demo.zmrenwu.com$ ls
env

Then pull the project code from the code warehouse,Change the address after git clone to your own GitHub warehouse address!

[email protected]:~/sites/demo.zmrenwu.com$ git clone https://github.com/zmrenwu/django-blog-tutorial.git

Run the LS command to check whether the pull is successful:

[email protected]:~/sites/demo.zmrenwu.com$ ls
django-blog-tutorial  env

There are more Django blog tutorial folders (the folder name is determined by your GitHub warehouse name), indicating that the pull is successful.

Installation project dependency

Activate the virtual environment, and then enter the root directory of the project, which is the directory where requirements.txt is located. All the dependencies of the installation project are:

[email protected]:~/sites/demo.zmrenwu.com$ source env/bin/activate
(env) [email protected]:~/sites/demo.zmrenwu.com$ cd django-blog-tutorial/
(env) [email protected]:~/sites/demo.zmrenwu.com/django-blog-tutorial$ pip install -r requirements.txt

Collect static files

Continue running in virtual environmentpython manage.py collectstaticCommand to collect static files to the static Directory:

(env) [email protected]:~/sites/demo.zmrenwu.com/django-blog-tutorial$ python manage.py collectstatic

Build database

Continue running in virtual environmentpython manage.py migrateCommand to create a database file:

(env) [email protected]:~/sites/demo.zmrenwu.com/django-blog-tutorial$ python manage.py migrate

Create superuser

Continue running in virtual environmentpython manage.py createsuperuserCommand to create a super user, convenient for us to enter Django management background. This is the same as the local development. Please refer to the article in Django admin background for details.

(env) [email protected]:~/sites/demo.zmrenwu.com/django-blog-tutorial$ python manage.py createsuperuser

Configure Nginx

Next, configure nginx to handle user requests.

First, create a new configuration file in the / etc / nginx / sites available / directory of the server. I usually set the file name to domain name. Write the following configuration:

/etc/nginx/sites-available/demo.zmrenwu.com

server {
    charset utf-8;
    listen 80;
    server_name demo.zmrenwu.com; ①

    location /static { ②
        alias /home/yangxg/sites/demo.zmrenwu.com/django-blog-tutorial/static; 
    }

    location / { ③
        proxy_set_header Host $host;
        proxy_pass http://unix:/tmp/demo.zmrenwu.com.socket;
    }
}

① The domain name of the service is demo.zmrenwu.com.

② All requests with / static URL are processed by nginx, and alias indicates the directory where the static files are stored.

③ Other requests are forwarded to Django for processing. UNIX socket is used after proxy pass to prevent port conflict, which will not be discussed here.

As for how to create and write files in the server, please learn a little about the use of VI editor by yourself, which will not be explained here.

We have placed the configuration file in / etc / nginx / sites available /. Next, we need to create a symbolic link to add the configuration file to the list of enabled websites. The directory of the enabled websites is in / etc / nginx / sites enabled /. You can understand that you have sent a shortcut to the sites enabled / directory from the sites available / directory. The specific orders are as follows:

(env) [email protected]:~/sites/demo.zmrenwu.com/django-blog-tutorial$ sudo ln -s /etc/nginx/sites-available/demo.zmrenwu.com /etc/nginx/sites-enabled/demo.zmrenwu.com

Using gunicorn

Gunicorn is generally used to manage multiple processes. When a process is hung, gunicorn can pull it up to prevent the server from stopping service for a long time. It can also dynamically adjust the number of workers. When there are more requests, the number of workers increases, and when there are fewer requests, the number of workers decreases.

In a virtual environment, install gunicorn:

(env) [email protected]:~/sites/demo.zmrenwu.com/django-blog-tutorial$ pip install gunicorn

Start the server process with gunicorn:

(env) [email protected]:~/sites/demo.zmrenwu.com/django-blog-tutorial$ gunicorn --bind unix:/tmp/demo.zmrenwu.com.socket blogproject.wsgi:application

Browser input domain name, you can see the success of the visit!

Start gunnicorn automatically

Now we start gunicorn manually. If the server crashes and restarts one day, we have to restart it manually. To do this, we write an automatic startup script, so that when the server is restarted, the script will help us restart gunicorn. First press Ctrl + C to stop the server process you just started.

Write a startup script, so that when the server is restarted, it can automatically boot the startup of gunicorn. The script is located in the / etc / init / directory, and the script filename must end in. Conf:

/etc/init/gunicorn-demo.zmrenwu.com.conf

start on net-device-up ①
stop on shutdown

respawn ②

setuid yangxg ③
chdir /home/yangxg/sites/demo.zmrenwu.com/django-blog-tutorial ④

exec ../env/bin/gunicorn --bind unix:/tmp/demo.zmrenwu.com.socket blogproject.wsgi:application ⑤

① Start on net device up ensures that gunicorn is started only when the server is networked.

② If the process crashes (for example, the server restarts or the process is killed due to some other circumstances), repawn will restart gunnicorn automatically.

③ Setuid ensures that the gunicorn process runs as the yangxg user (change to your own user name).

④ Chdir enters the specified directory, where it enters the root directory of the project.

⑤ Exec executes the process, that is, opens the server process.

Now you can start gunicorn with the start command:

sudo start gunicorn-demo.zmrenwu.com

If you update the code later, just run the following command to restart nginx and gunicorn to make the new code take effect:

sudo service nginx reload
sudo restart gunicorn-demo.zmrenwu.com

Using CDN to speed up bootstrap and jQuery loading

Our project uses bootstrap and jQuery, which we load locally. If the performance of the server is poor, it will take a long time to load, and the speed of website opening will become unbearable. We use CDN to speed up loading. Specifically, replace the load labels of several static files of base.html:

base.html

- <link rel="stylesheet" href="{% static 'blog/css/bootstrap.min.css' %}">
- <script></script>
- <script></script>
+ <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
+ <script></script>
+ <script></script>

So the speed of website visit will be greatly improved!

Deployment process automation

During the whole deployment process, we ran a dozen commands and manually entered n characters. It will be very troublesome to connect to the server remotely to execute these commands every time the code is updated. In the next tutorial, we will cover automating the entire deployment process with fabric. After the deployment script is written, the entire deployment can be completed automatically with only one command.

summary

The code of this chapter is located in: step14: deploy using nginx and gunicorn.

If you have problems, please ask for help in the following ways.

  • Leave a comment in the comment area of blogs that use nginx and gunicorn to deploy Django blogs – dreamers.

  • Send a detailed description of the problem by email to [email protected], and reply within 24 hours.

For more Django tutorials, visit the dreamers blog.