3 horizontal lines, burger
3 horizontal lines, burger
3 horizontal lines, burger
3 horizontal lines, burger

3 horizontal lines, burger
Remove all
LOADING ...

Content



    How to deploy a Django project on virtual hosting(or VPS) provider reg.ru

    Clock
    16.03.2025
    /
    Clock
    02.10.2025
    /
    Clock
    25 minutes
    An eye
    1259
    Hearts
    0
    Connected dots
    0
    Connected dots
    0
    Connected dots
    1

    Introduction, or what this is all about

    In this article I will tell and show how you can host a site on servers from reg.ru (hosting provider). This provider provides a wide range of development platforms/CMS that are used to create a site. But in this article I will only tell you how to deploy a site written in Django, because I understand this.
    In addition to providing regular hosting, reg provides such a service as VPS.
    VPS(Virtual Private Server) - such a server is located together with others on the same hardware (computer), hence the virtual server, and only its owner has access to such a server, hence the private.
    So, on reg.ru, you can host a site in two ways. The first is simple, but limited, the second is complex, but much more complicated. The first is to use a ready-made solution from the hosting provider itself and do a little magic in Docker. The essence of the second method is to create your own VPS and configure the server manually.
    I will demonstrate both, explain the features and nuances of both, and why, in my opinion, virtual hosting is better.

    Features of this article

    For demonstration, I will use a specially made django application. This application has built-in all the features that the site may need in the future, such as:
    1. working and setting up with the database
    2. working with static files
    3. uploading various media to the site
    4. translations for backend and frontend
    5. tests both functional and modular
    I am constantly working on this application. It is all because I am going to test it on other hostings (not only beget). In the end, I see it as one big interactive test of hostings and how friendly they are to Django sites.
    I'm also going to use next domains:
    1. search-result-parser.site - for deploying via virtual hosting
    2. bddt2.space - for deploying via VPS
    Plus, and this is important, by the time you read this article, the site at the domain bddt2.site will no longer be available :(. Well, you know, I don't throw money away.

    Preparation, domain acquisition

    In this chapter, you will need to browse the reg.ru website itself and complete some preparatory steps, which are common for deploying a website via hosting or via VPS.
    In your personal account, click order and select the service "domain":
    1. Click
    2. Select a domain
    3. Enter the desired one
    4. Choose
    Afterwards, you will be shown different variations of your domain in different zones. Different discounts and prices will be applied to them. I chose bddt2.space and search-result-parser.site.
    That's not all, on the new page you will be offered a bunch of other services that might be useful in other scenarios and under other circumstances, but not now. We just need to register the domain.

    Deploy via virtual hosting

    Deploying a site on hosting from reg.ru is much easier than on beget. My point is that we do not have to install the necessary software (such as Python or OpenSSL, they are already there), and some steps are automated (for example, entering the docker container). Sure if compare to deploying a site on beget.

    Setting up the hosting

    Everything starts with purchasing such a service as hosting. I think you have already purchased this service on reg.ru, otherwise you would not be here :) We will need to go to ISPManager - the admin panel for hosting management:
    Then go to the control panel (computer icon):
    Next, you will need to go to all sites on the dashboard (1), select the appropriate site (2) and click the change parameters button (3). Since we have already purchased the domain, we will have one ready-made website.
    Now, about what levers and buttons you will definitely need to press. To be more specific, this means choosing the required version of Python and toggle CGI scripts on.
    I want to note that if your django site is written on versions higher than 4.2, then for you (just like for me) only one version of python will do, 3.10.1. Also, if you also bought an SSL certificate, include it too.
    If you, my friend, want some version of python different from those offered on the hosting, then I must to disappoint you, you will not be able to. At least, there is definitely no version younger than 3.10. The thing is that you will need root rights to install the corresponding version of OpenSSL - you will not have such rights under Docker. So if your application uses the latest features of Python 3.11 and older, you will have to install the site on a VPS, or look for a new hosting provider.
    I just want to make one remark about the interface. The order of python interpreter versions goes from the earliest to the latest, it would seem. But for some reason, version 3.10 is almost in the middle. I didn’t notice it right away. But it’s exactly what we need.
    We have completed the basic hosting setup. And unlike the beget hosting provider, we will not need to manually download and install the required version of python and openssl, they are already there.

    To make a database

    Any site, one way or another, requires a place to store data. The hosting provider only supports MySQL 8 databases, so we will work with them.
    This method is suitable only if you deploy the site on a purchased virtual hosting. And remote access can only be implemented for MySQL 5.7. And you can’t create a DB with this version via ISPManager.
    Let me show you how to create one of these:
    1. u3044930_bddt2_bd is a database's name
    2. u3044930_bddt2_user is a name of the user, which will work in the database
    3. Just a password, remember this
    4. You can check it or not - it doesn't matter. Remote access to such databases is still not allowed

    Deploy

    Deploying a website always starts with transferring its files. They can be transferred in two ways, either through the control panel or using the scp command, through the terminal. Here I will consider only the first method, because it is stupidly simpler.
    First, go to the file manager, after which you will need to go to the directory under the name of the domain name you bought. In my case, this is search-result-parser.site. All such directories are located in the www directory.
    Upload the archive with the site's files and unpack it. Later, in the root directory of the site, create a virtual environment, activate it and install the necessary packages via pip:
    cd /www/search-result-parser.site/ /opt/python/python-3.10.1/bin/python3.10 -m venv .venv source .venv/bin/activate pip install -r req.txt
    I want to note that if you need to use python3.10, you will have to specify the full path to the interpreter, because it is not in the $PATH environment variable. Keep that in mind.
    We have successfully transferred our site files and prepared a virtual environment for our application to work in. Next, we will connect the previously created database, deal with static files and connect to the Apache2 web server.
    Apache2 -is the name of the most common open-source web server software, also known as the Apache HTTP Server

    Connect to database

    You need to immediately connect the site to the database that we recently created. In the Django site settings file, edit the following lines:
    DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'database_name', 'USER': 'user_name', 'PASSWORD': 'database_password', 'HOST': 'localhost', } }
    But that's not all. Right now we're interested in the following keys in the dictionary:
    1. NAME - The name of the database, in my case it is u3044930_bddt2_bd
    2. USER - Database user name, in my case it is u3044930_bddt2_user
    3. PASSWORD - A password to Database
    All other values remain as I specified them. To find out for sure and to finish this chapter, let's migrate to a new database, for this:
    python manage.py migrate
    Now all the necessary tables and connections between them have been created. And we can safely work with Django ORM.
    Django ORM (Object-Relational Mapper) - is a core component of the Django web framework that facilitates interaction with relational databases using Python code instead of raw SQL queries.

    Setting up directories for static and media files

    In order for the server to be able to access our files, they must all be in the root directory of the site, that is, in my case, /www/search-result-parser.site/. It will be necessary to make soft links to the static/ and media/ directories in the root directory. To do this, first, create the directories:
    cd /www/search-result-parser.site/ mkdir static mkdir media
    Then we create soft links:
    A soft link, also known as a symbolic link or symlink, is a special kind of link in a file system that points to another file or directory but does not contain the original file's data.
    cd /www/search-result-parser.site/Website ln -s ../static static ln -s ../media media
    And to finish this chapter and test whether we did everything correctly, let's collect all the statics in the application:
    python manage.py collectstatic
    All static files should be available under the directory /www/search-result-parser.site/static/. And all media files, when uploading something to the server, should be in /www/search-result-parser.site/media/.

    Connect to WSGI web server

    Now let's connect to the hosting web server. For reg.ru, it's Apache2. To do this, you'll need to create a special file passenger_wsgi.py:
    # -*- coding: utf-8 -*- import os, sys sys.path.insert(0, '/var/www/u3044930/data/www/search-result-parser.site/Website') sys.path.insert(1, '/var/www/u3044930/data/www/search-result-parser.site/.venv/lib/python3.10/site-packages') os.environ['DJANGO_SETTINGS_MODULE'] = 'Website.settings' from django.core.wsgi import get_wsgi_application application = get_wsgi_application()
    1. Where instead of sys.path.insert(0, ..., you will have to specify the path to the root folder of your django site.
    2. Where instead of sys.path.insert(1, ..., you will have to specify your path to the packages in the virtual environment created earlier.
    We have finished deploying our site on virtual hosting from reg.ru.
    How to reload the server?
    How to reload the server? Now restart the server by creating a file .restart-app in the root directory of the site, /www/search-result-parser.site/. The servers work in such a way that every minute they check the hostings for the presence of such a file and if it is there, they restart. Wait until the minute is up :)

    Deploying via VPS

    Creating a VPS on Reg.ru website

    To create dedicated servers, reg provides a very wide range of choice in the choice of operating systems, ready-made systems and in the choice of hardware on which you will place your VPS. Plus, I want to note the price, they are much cheaper in comparison with the same beget hosting provider.
    So go to this configuration page https://www.reg.ru/vps/.
    1. Let's choose the Ubuntu LTS 24.04 ( the latest version at this moment).
    2. Type and power of processor
    3. Tariff, we don't need much. But the more demanding the site, the more you will need

    Edit DNS records and add a subdomain

    At the moment you have a domain and a VPS, but they are not connected in any way yet. In order to connect the purchased domain and the newly created VPS, we will need to dig into the DNS records. Specifically, those that were sent to you by email when the server was created, or more specifically, these are ns5.hosting.reg.runs6.hosting.reg.ru.
    DNS (Domain Name System) - is a fundamental part of the internet that translates human-readable domain names (like google.com) into the numerical IP addresses that computers use to locate each other
    Open the page with all purchased domains and select the DNS editing option:
    After this, you need to change the default DNS server to the ones I indicated above, that is: ns5.hosting.reg.runs6.hosting.reg.ru.
    We have successfully changed the DNS servers, now we need to make the appropriate A or AAAA records to indicate the address of our VPS.
    Keep in mind that it will take time for the DNS servers to change. How long? It varies, but it took me 15 minutes. Just keep in mind that browsers have their own built-in DNS cache. You can view it by typing this (for Firefox): about:networking#dns.
    And where, actually, do you edit this DNS of yours? Editing DNS servers for VPS is done in a separate admin panel. Its address is specified in the same letter when creating a VPS. There is also a login and password for it.
    When creating a domain, you need to specify its name - bddt2.space and the IP of the purchased VPS.
    After successfully adding the domain to DNS, we don't need to do anything else. But if, for example, you need to add a subdomain. Or change the VPS server address, then:
    Where we fill in all the required fields, the IP will be the same as the main domain, only the name will be different. So, for example, my domain is bddt2.space, and I will call the subdomain staging.bddt2.space.
    Thus, when accessing the specified domain (in my case it is bddt2.space), the DNS server will point to the VPS server we need (that is, the one we created).

    Database creation

    Creating a database on reg.ru is a bit tricky in my opinion. For example, why not allow remote access to databases created in ISPManager. It's fast, easy and convenient.
    But they decided to go the other way. For those who deploy a site on a VPS, you will have to:
    1. Either create a database on the same VPS server
    2. Or use the cloud and create it there
    3. Or use databases from other hostings.
    I will demonstrate the 2nd method, because you have probably already paid for the hosting and it would be strange and wasteful to use someone else's services. Creating a database in the reg cloud is very simple:
    1. Type of database (In my case it is MySQL)
    2. Type of plan to apply.
    MySQL - is a widely used, open-source relational database management system (RDBMS)
    1. Do we need a fail-safe database? If one fails, another one will take its place, its exact copy
    2. Database name, you need to remember - in my case it is bddt2_bd
    3. User name through which we will connect to the database - bddt2_user
    4. A Password
    After that, we click "create cluster" and wait until this cluster is created. This will take time.
    In general, when I wrote "This will take time" you will have to wait a day or two. I waited so long that I started thinking about using some other solution. For example, using Beget databases. I tearfully ask the owners of Reg.ru, warn your users (clients) how long the cluster creation process will take.
    When our cluster is created, we will need to find out the host to which we can connect and the port on which the MySQL server sits. To do this:
    1. After opening the created cluster, go to the "Databases" tab
    2. bddt2_bd - the name of the database to which you are connecting
    3. bddt2_user - the name of the user through which you are connecting
    4. 79.174.89.21 - the address of the host on which the MySQL server is located
    5. 18320 - the port on which this database accepts requests
    Now we have everything we need to connect to the database for our site on the VPS.

    Connect to the created VPS via SSH

    We have successfully created our first virtual server (and database) on Reg, now we need to connect to it. For this we will use SSH. And in order to be able to connect to our server we need to know its IP and password to it. All this comes to the mail that you specified when registering an account on Reg.
    SSH (Secure SHell) - is an Internet protocol that enables secure, encrypted communication between a client and a server. There is an SSH client (it is required for the machines from which the connection will be made), and there is an SSH server (it is required if you want to provide remote access to your machine). All servers have an SSH server installed by default.
    1. Location of the server
    2. A User name to log in on the server
    3. A Password to log in on the server
    If for some reason you did not receive the letter, you can find out the server address by going to the virtual server control panel at https://cloud.reg.ru/panel:
    The password can be reset if necessary, and the username to which you can always connect is root - always. Let's connect to our server:
    ssh root@83.166.244.155
    Linux machines have SSH client installed by default, but Windows does not. To enable SSH client, you just need to enable this "Feature". Here is a great article about it.
    And what do you actually connect through? You can use PowerShell, you can use Git Bash if you're used to Linux, you can use specially created programs for connecting to servers via SSH, or you can install a special extension for VSCode and get not only a terminal on a remote server, but also a file manager and development environment - this extension is called Remote - SSH, by the way.
    Since I am still working and sitting on Windows, I will use the simplest and most accessible method, from here on - PowerShell.

    Connect to the server by the key (optional)

    I predict that you will have to log into the remote server very often, if only because the connection can be constantly interrupted, and manually entering the password to connect is quite a task.
    Therefore, I suggest creating a key pair for authorization without a password. To do this, on your work computer, enter the command:
    ssh-keygen -t rsa -f .ssh/bddt2
    1. Where the -t flag is responsible for the type of the generated key
    2. Where the -f flag is responsible for the path to the file (which may not exist) where the key will be saved
    After generation, you will have two files, bddt2 and bddt2.pub. The first (bddt2) is a private key, keep it like the apple of your eye, it is needed for authorization. The second key (bddt2.pub) is distributed to all remote servers that you want to access without entering a password.
    It remains to execute one more command, namely, to transfer the key to the remote server that you want to access using the key.
    ssh-copy-id .ssh/bddt2.pub USERNAME@SERVER
    1. Where .ssh/bddt2.pub is the path to the public part of the key
    2. Where USERNAME is the username through which you want to get to the server, usually root if no other users have been created yet.
    3. Where SERVER is the address of the remote server. This can be either IPv4 or a domain name.
    We are done. After that, to enter the server, use this command:
    ssh USERNAME@SERVER_ADDR -i .ssh/bddt2

    Installing the necessary packages

    Now it's time for Ctrl-C, Ctrl-V. There will be a few commands that will install the necessary packages on your server:
    apt-get update && apt-get upgrade && apt-get install gettext libgettextpo-dev && apt-get install pkg-config default-libmysqlclient-dev build-essential && apt-get install nginx && apt-get install gunicorn && apt-get install python3.12-venv python3-dev
    Now let's talk about why I installed all of this, and what each of these commands did:
    1. apt-get update - Always run it first when installing any package. It syncs the application package index and updates all dependencies if necessary.
    2. apt-get upgrade - Installs the latest versions of installed packages on the system.
    3. apt-get install gettext libgettextpo-dev - it installs the dependencies needed to generate translations for your sites (which use the gettext utility)
    4. apt-get install pkg-config default-libmysqlclient-dev build-essential - necessary dependencies for working with MySQL databases.
    5. apt-get install nginx - to start the web server
    6. apt-get install gunicorn - to redirect requests from the nginx server to our django application
    7. apt-get install python3-dev python3.12-venv - to be able to create a virtual environment when running python applications
    We are done with installing the necessary packages on the server. Only "unnecessary" ones remain. You can skip to the beginning of the next chapter if you do not have functional tests in the application.
    nginx - It is an easily configurable web server and proxy for requests to be directed to the server.
    gunicorn - This is a server for python applications that connects web servers (such as nginx and apache) and python applications.
    My "unnecessary" package is selenium. I need it for my functional tests to work. And for it to work, it will need the Firefox browser, which we will install as a .deb package. Oh boy, this is quite an adventure ヽ(°〇°)ノ. I invite everyone interested to visit the official Mozilla website and run one command after another.
    In addition to firefox, you will also need to install geckodriver. The latest releases can be found here: https://github.com/mozilla/geckodriver/releases . And now, the command to install this geckodriver:
    wget https://github.com/mozilla/geckodriver/releases/download/v0.36.0/geckodriver-v0.36.0-linux64.tar.gz tar -xzvf geckodriver-v0.36.0-linux64.tar.gz sudo mv geckodriver /usr/local/bin/
    After downloading (wget) and unzipping geckodriver (tar -xzvf), we then placed it in the /usr/local/bin/ directory so that all applications had access to the driver.

    Create a new user

    This step is mandatory and do not think about making a site with root rights. Now you will need to create a user with root privileges and a home directory.
    useradd -m -s /bin/bash site passwd site usermod -aG sudo site
    The first command will create a user named "site", create a home directory for it (flag -m) and set the default shell, i.e. bash. The second command will set a password for the new user. The third will add the user "site" to the sudo group, which is able to execute all commands, only using the sudo command.
    sudo - is a command (program) executed in the terminal on Unix-like operating systems (Linux, MacOS), which allows you to run other programs with permissions to execute administrative and potentially dangerous commands.

    Transferring the project to the server

    The base for our server is ready, now let's work on the site files themselves. I'm going to create a simple file structure where I'll get my project files using git and copy them to the source directory. I'll also create a virtual environment:
    All further commands I executed on behalf of the newly created user "site". If anything changes, I'll let you know.
    mkdir ~/bddt2.space cd ~/bddt2.space git clone https://github.com/DmRafaule/DjangoDeploymentTest source python -m venv venv
    After running all these commands, you should have the following project structure:
    1. bddt2.space <- You are here
    2. venv
    3. source
    Now, activate the virtual environment and install the necessary packages from source/requirements.txt:
    source ./venv/bin/activate pip install -r source/requirements.txt
    There shouldn't be any problems here, but if they do, read the error logs carefully. Often, these are simply uninstalled dependencies on the server, which can be easily fixed using the apt package manager. Let's try to run the installed Django application (from the directory with the manage.py file):
    cd ./source/Website python manage.py runserver

    Setting up mysql database (optional, though not really)

    You will get an error that the settings.json file was not found. This is a configuration file that I use as a proxy instead of writing directly to settings.py. I did this so that I could safely add the settings.py file to the git repository and to simplify deployment.
    Here is an example of such a file (settings.json), create it in the source/Website directory:
    { "SECRET_KEY": "django-insecure-4#-wrp_(53^0_9$%p8lq+qf43z0dx0ji6bh!sa1mfn^l)4-lq@", "DEBUG": true, "ALLOWED_HOSTS": ["bddt2.space"], "DATABASES": { "default": { "ENGINE": "django.db.backends.mysql", "NAME": "bddt2_bd", "USER": "bddt2_user", "PASSWORD": "aD9bN5oV3pjD7qJ9", "HOST": "79.174.89.21", "PORT": 18320 } }, "EMAIL": { "DEFAULT_FROM_EMAIL": "bddt@bddt.space", "DEFAULT_TO_EMAIL": "chedrden@gmail.com", "EMAIL_HOST": "", "EMAIL_PORT": , "EMAIL_HOST_USER": "", "EMAIL_HOST_PASSWORD": "" } , "STAGING_SERVER": "http://staging.bddt2.space" }
    As you can see, I'm already using MySQL as a database. What you need to know to connect to the database from a VPS:
    1. First, you need to know which backend to connect to - django.db.backends.mysql
    2. Second, the database name - bddt2_bd
    3. Third, the username - bddt2_user
    4. Forth, the database password - aD9bN5oV3pjD7qJ9
    5. Fifth, the database host name (address) - 79.174.89.21
    6. Sixth, the connection port - 18320
    All this data can be obtained when creating your database, the process of which I described in the corresponding chapter at the beginning.
    How do I transfer data from settings.json to Website/settings.py? In the settings.py file, I open the settings.json file and read the data from there, like this:
    from django.utils.translation import gettext_lazy as _ from pathlib import Path import os import json import sys # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent # Read the settings file with open(os.path.join(BASE_DIR,"settings.json"), 'r') as settings_file: settings = json.load(settings_file) # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = settings["SECRET_KEY"] # SECURITY WARNING: don't run with debug turned on in production! DEBUG = settings["DEBUG"] ALLOWED_HOSTS = settings["ALLOWED_HOSTS"] STAGING_SERVER = settings["STAGING_SERVER"] # More code bellow # ...
    I use the JSON format because it is simply very convenient to work with it via Python.

    Finishing up the project transfer

    By the way, we can already run tests and see what works and what doesn't. Everything should work:
    So, we have successfully uploaded our site to the server and even passed all the tests. This means that it is time to configure nginx, after which we will connect our site to the nginx web server via gunicorn.
    Why, and most importantly, why exactly Nginx and Gunicorn? Look, nginx makes our VPS server, as it were, accessible to other machines. It configures port 80 and domain (if necessary) so that other machines know where it is and where to send their requests. But nginx alone is not enough, we need to somehow pass requests from other machines to our Django application. This is what Gunicorn is used for, it also listens on the corresponding port 80 (although it is possible and necessary to do this via UNIX sockets, I will show how), and after receiving a request, it sends it to the Django application, where all the rest of the site logic occurs.

    Configuring Nginx

    Along with the project files, you will also receive default configuration files for configuring nginx - nginx-server-http_only.conf, nginx-server-https_301.conf, nginx-server-https.conf.

    Super fast Nginx configuration (very optional)

    Next I'm going to go into detail about what each file is used for, how to start and restart nginx, plus how to add sites to nginx. If you're interested, you're welcome, but if not, you can use the server-setup.sh script I left in the repository.
    To use it, enter:
    ./server-setup.sh YOUR_DESIRED_DOMAIN on_https
    1. Where YOUR_DESIRED_DOMAIN is the desired domain
    2. Where on_https is a flag that tells to configure redirect to HTTPS protocol
    This script will create the corresponding configuration files and will be reloaded.

    Let's continue configuring Nginx

    Well, if you are still interested in the details and the process, let's continue. For now, open the file nginx-server-http_only.conf, you will see the following configuration for our site:
    server { listen 80; server_name HOST_PLACE_SETUP; location /static { root /home/USER_PLACE_SETUP/HOST_PLACE_SETUP; } location /media { root /home/USER_PLACE_SETUP/HOST_PLACE_SETUP; } location / { proxy_set_header Host HOST_PLACE_SETUP; proxy_pass http://unix:/tmp/HOST_PLACE_SETUP.socket; } }
    1. In this configuration, we set up the port on which we will listen for incoming requests.
    2. The name for our server (domain name). In my case, it should be bddt2.space.
    3. The folders that this server will serve. At a minimum, you need to set up the root directory "/". But this is not all, my site uses various statics in the form of pictures and icons. Plus media files that are uploaded directly by the user.
    What are these incomprehensible variables USER_PLACE_SETUP and HOST_PLACE_SETUP? It's all about how my custom server setup script works. In short, it uses the sed command to replace the two above-mentioned variables and replaces them with the values required by the administrator. All this is done through a special server-setup.sh script, which I'll talk about in the next chapter.
    So the final version of this configuration will look like this:
    server { listen 80; server_name bddt2.space; location /static { root /home/site/bddt2.space; } location /media { root /home/site/bddt2.space; } location / { proxy_set_header Host bddt2.space; proxy_pass http://unix:/tmp/bddt2.space.socket; } }
    To make sure we don't forget, let's immediately create the media and static directories in the ~/bddt2.space directory and soft links to them. Soft links to them are created to give the server access to them.
    cd ~/bddt2.space mkdir static mkdir media cd source/Website
    A soft link, also known as a symbolic link or symlink, is a special kind of link in a file system that points to another file or directory but does not contain the original file's data.
    All the necessary directories have been created and now we are ready to create soft links to these directories:
    ln -s ../../static static ln -s ../../media media
    The project now has the following structure:
    1. bddt2.space
    2. venv
    3. media
    4. static
    5. source
    6. Website
    7. Backend
    8. Frontend
    9. Website
    10. media -> ../../media
    11. static -> ../../static
    12. manage.py
    13. settings.json
    14. deploy.sh
    15. server-setup.sh
    16. requirements.txt
    17. gunicorn.service
    18. nginx-server-http_only.conf
    19. nginx-server-on_httsp-301.conf
    20. nginx-server-on_https.conf
    When working with media files, the server can give a 413 response - 413 Request Entity Too large. This is due to the fact that the maximum body size in a request by default can be no more than 1 megabyte. To change this, in the file /etc/nginx/nginx.conf, in the http section, add: ```client_max_body_size 50M;```
    Now, any file that is created in the ~/bddt2.space/source/Website/static or ~/bddt2.space/source/Website/media directory will be available in the ~/bddt2.space/static and ~/bddt2.space/media directories.
    To check this, you can run the collectstatic command and make sure that all files, although copied to ~/bddt2/source/Website/static, are also available in ~/bddt2.space/static.

    403 Forbiden error - how to solve (optional, I hope)

    Another very common problem is that the server can return a 403 response to a request for some static file. This is often due to the fact that the user www-data does not have permission to read certain files. The nginx configuration file specifies the user on whose behalf the web server is launched.
    There are three ways to fix this:
    1. Replace the user in the /etc/nginx/nginx.conf file
    2. Give everyone access to read files
    3. Add the user www-data to the group of the user who launches the application.
    I will describe the 3rd because this is, in my opinion, the simplest and most correct way. And you just need to run one command:
    sudo usermod -aG site www-data
    1. site - the name of the group to which you want to add the user (it will match the user name)
    2. www-data - the name of the user you want to join the group.
    Now, all statics and all media files on the site should be available.

    Finish up a Nginx set up

    Let's finish setting up the web server and copy the created configuration file to /etc/nginx/sites-available:
    sudo cp ~/bddt2.space/source/nginx-server.conf /etc/nginx/sites-available/staging-nginx-server.conf
    Now let's do the same as with the static and media directories, create a soft link to this configuration file. But first, go to the directory where this link should be:
    sudo cd /etc/nginx/sites-enabled sudo ln -s ../sites-available/staging-nginx-server.conf staging-nginx-server.conf
    Let's restart the nginx service using systemctl so that the changes take effect:
    sudo systemctl restart nginx
    I think it's worth trying to visit our website now - bddt2.space.
    And yes, you should see something like this. Why is this happening, what is this "Bad Gateway"? It's all because one line, in the site configuration file /etc/nginx/sites-available/staging-nginx-server.conf.
    ... proxy_pass http://unix:/tmp/bddt2.space.socket; ...
    In fact, the nginx server forwarded my GET request to the specified socket, but nothing is connected to it yet. This is where gunicorn comes into play.

    Seting up a Gunicorn

    The almost ready configuration file is located in the same place as the nginx server configuration file - ~/bddt2.space/source/gunicorn.service. This is a file describing the work of the linux daemon, here are its contents:
    [Unit] Description=Gunicorn server for HOST_PLACE_SETUP [Service] Restart=on-failure User=USER_PLACE_SETUP WorkingDirectory=/home/USER_PLACE_SETUP/HOST_PLACE_SETUP/source/Website ExecStart= /home/USER_PLACE_SETUP/HOST_PLACE_SETUP/venv/bin/gunicorn --bind unix:/tmp/HOST_PLACE_SETUP.socket Website.wsgi:application [Install] WantedBy=multi-user.target
    This script has substitution variables HOST_PLACE_SETUP and USER_PLACE_SETUP. I replace them with the values I need via a special script server-setup.sh. More about it in the next chapter.
    This service (daemon), launched by the user site and with its privileges, will be rebooted every time an error occurs (Restart=on-failure). This daemon will work in the directory specified in WorkingDirectory. And it will do what is specified in ExecStart, that is, launch the gunicorn server.
    When launching gunicorn, we also specified which socket to connect to and where to redirect requests - to our Django application.
    Create the same file in /etc/systemd/system/ and edit it by inserting your user, your domain and your socket. Now let's launch the service and make it start on the server after boot.
    sudo cp ~/bddt2.space/source/gunicorn.service /etc/systemd/system/gunicorn.service sudo vim /etc/systemd/system/gunicorn.service sudo systemctl start gunicorn sudo systemctl enable gunicorn
    Now everything will work. We have created a special service that starts the gunicorn server at startup, and it starts our django application. After refreshing the tab, you should see the following:
    This completes the process of deploying a Djanog site on a VPS from reg.ru. I also recommend reading the next chapter on how to put this site on the new HTTPS protocol.

    Migrate to HTTPS (optional, although not really)

    In order to place our site on the HTTPS protocol, we will need to get a special certificate. We will get it from LetsEncrypt. It is free, but what is even cooler is that everything can be done through the command line, which means automation. Look, in order to configure the nginx web server for https, you will need a certificate and a key to it.
    The LetsEncrypt team made a special utility, which is very cool in terms of supported technology stacks for certification. Here, for example, is a page for generating, signing and issuing certificates for sites on nginx and using pip. It is just dope ;) And you do not need this headache with self-signed certificates that no one trusts, and as a result, no one visits the site.
    Activate the virtual environment and install the program:
    source ~/bddt2.space/venv/bin/activate pip install certbot certbot-nginx
    Now we generate and sign up the certificates:
    sudo ~/bddt2.space/venv/bin/certbot certonly --nginx -d bddt2.space
    This command will generate and sign up certificates, which will be placed in /etc/letsencrypt/live/bddt2.space. You will see an interactive prompt like this:
    1. Asks to enter email
    2. Agree to sell your soul and the soul of your site)
    3. Registration, optional
    4. Selecting domains (subdomains) for which this certificate will be valid. If you simply press ENTER, the certificate will be applied to all.
    5. Path to the certificate (for configuring nginx)
    6. Path to the key (for configuring nginx)
    You can also set a cron task to update the certificate every month:
    echo "0 0,12 * * * root /opt/certbot/bin/python -c 'import random; import time; time.sleep(random.random() * 3600)' && sudo certbot renew -q" | sudo tee -a /etc/crontab > /dev/null
    All that remains is to change the configuration in sites-available, this is done like this:
    server { listen 443 ssl; server_name HOST_PLACE_SETUP; ssl_certificate /etc/letsencrypt/live/bddt2.space/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/bddt2.space/privkey.pem; location /static { root /home/USER_PLACE_SETUP/HOST_PLACE_SETUP; } location /media { root /home/USER_PLACE_SETUP/HOST_PLACE_SETUP; } location / { proxy_set_header Host HOST_PLACE_SETUP; proxy_pass http://unix:/tmp/HOST_PLACE_SETUP.socket; } }
    The difference from the previous configuration is that we changed the port and added ssl_certificate and ssl_certificate_key and the paths for which certbot will tell you. That's all, on how to add https to your site.
    But you may have noticed that when trying to get your site via regular http, it will no longer work. You will need to make a separate configuration for port 80 and make a 301 redirect to the https version. This is considered good practice. To do this, create another configuration file in /etc/nginx/sites-available, for example http_301_redirect-staging.bddt.space, with the following:
    server { listen 80; server_name HOST_PLACE_SETUP; location / { return 301 https://HOST_PLACE_SETUP$request_uri; } }
    Where HOST_PLACE_SETUP is your site's domain, for example bddt2.space. This configuration makes a 301 redirect from any http pages to https pages.
    301 server code - It is also called a permanent redirect, the server response in which a redirection occurs from one URL to another.
    There is also a 302 server code and this is also a redirect. So what is the difference between them? The difference is in the meaning that the 302 code transmits. If 301, then it kind of says: the URL you got will always be available only at the new address. And 302, in turn, says: the URL you got is now available at this address, but it may not always be so.

    Comparison of launching a website on a Hosting and on a VPS

    TestingNo limitNo limit
    Custom project structureLimitedNo limit
    Automation of deploy, setting up etc.LimitedNo limit
    WSGI serverPhusion PassengerNo limit
    Web serverApache2No limit
    Migration to HTTPSSeamlessHard
    Database setupEasyHard
    Linking domainSeamlessHard
    PriceCheapLess cheap
    MetricsReg.ru HostingReg.ru VPS
    Honestly, I would rather deploy sites on a virtual hosting than do it myself on a VPS. But the limitations in the versions of Python used, and the impossibility of using other databases, really put me off.

    Conclusion

    And here is another hosting provider conquered and studied. Now you know how to host sites on reg.ru. From my experience, I will say that hosting a site on reg.ru is more difficult than on the same beget. There are too many pitfalls and non-obviousness. I hope I have analyzed them all and shown acceptable ways to solve and bypass them.
    I also hope that this article helped you figure out how and where to deploy your site written in Django and I also hope for your kind comment and that you might want to share this article with a friend. In any case, see you in the next article (⌒‿⌒)


    Do not forget to share, like and leave a comment :)

    Comments

    (0)

    captcha
    Send
    LOADING ...
    It's empty now. Be the first (o゚v゚)ノ

    Other

    Similar articles


    How to deploy a Django project on Beget (Either via hosting or VPS)

    Clock
    12.05.2024
    /
    Clock
    02.10.2025
    An eye
    3820
    Hearts
    0
    Connected dots
    0
    Connected dots
    0
    Connected dots
    0
    This is an article on how to deploy django site on beget. I show two methods (deployment either on hosting or VPS). Plus, how to set up and connect a …

    Series of articles about creating and promoting SearchResultParser | Tim the webmaster

    Clock
    16.07.2024
    /
    Clock
    05.10.2025
    An eye
    1041
    Hearts
    0
    Connected dots
    0
    Connected dots
    0
    Connected dots
    0
    This is an article that is going to introduce you to my new project/webtool, SearchResultParser. Also, from this article, you can navigate to any interesting article for you. See them …

    Developing frontend part of a website with React on Django | SearchResultParser p. 2

    Clock
    16.08.2024
    /
    Clock
    02.10.2025
    An eye
    667
    Hearts
    0
    Connected dots
    0
    Connected dots
    0
    Connected dots
    0
    I show and tell how to develop a frontend for a site on React with a backend on django. I use MaterialUI and TailwindCSS, with source code and comments.

    How to implement localization and translation for django website (python, js, templates and models) p. 5

    Clock
    06.02.2025
    /
    Clock
    02.10.2025
    An eye
    2850
    Hearts
    0
    Connected dots
    0
    Connected dots
    0
    Connected dots
    0
    In this article, I will show how you can add localization and translations to a Django website(i18n). We will translate Python, JS code, as well as templates and Django-models. Plus, …

    SEO website audit of the website by January and February

    Clock
    03.03.2025
    /
    Clock
    02.10.2025
    An eye
    510
    Hearts
    0
    Connected dots
    0
    Connected dots
    0
    Connected dots
    0
    About what my site achieved during SEO promotion in January-February. Analysis of traffic from Google via GSC and analysis of traffic from Yandex using Yandex.Webmaster. Also provided are full statistics …

    Used termins


    Related questions