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.
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:
- working and setting up with the database
- working with static files
- uploading various media to the site
- translations for backend and frontend
- tests both functional and modular
I'm also going to use next domains:
- search-result-parser.site - for deploying via virtual hosting
- bddt2.space - for deploying via VPS
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":

- Click
- Select a domain
- Enter the desired one
- 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.
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.
Let me show you how to create one of these:


- u3044930_bddt2_bd is a database's name
- u3044930_bddt2_user is a name of the user, which will work in the database
- Just a password, remember this
- 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:
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.
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:
But that's not all. Right now we're interested in the following keys in the dictionary:
- NAME - The name of the database, in my case it is u3044930_bddt2_bd
- USER - Database user name, in my case it is u3044930_bddt2_user
- 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:
Now all the necessary tables and connections between them have been created. And we can safely work with Django ORM.
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:
Then we create soft links:
And to finish this chapter and test whether we did everything correctly, let's collect all the statics in the application:
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:
- Where instead of sys.path.insert(0, ..., you will have to specify the path to the root folder of your django site.
- 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?
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/.
- Let's choose the Ubuntu LTS 24.04 ( the latest version at this moment).
- Type and power of processor
- 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.ru • ns6.hosting.reg.ru.
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.ru • ns6.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.
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:
- Either create a database on the same VPS server
- Or use the cloud and create it there
- 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:

- Type of database (In my case it is MySQL)
- Type of plan to apply.

- Do we need a fail-safe database? If one fails, another one will take its place, its exact copy
- Database name, you need to remember - in my case it is bddt2_bd
- User name through which we will connect to the database - bddt2_user
- A Password
After that, we click "create cluster" and wait until this cluster is created. This will take time.
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:

- After opening the created cluster, go to the "Databases" tab
- bddt2_bd - the name of the database to which you are connecting
- bddt2_user - the name of the user through which you are connecting
- 79.174.89.21 - the address of the host on which the MySQL server is located
- 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.

- Location of the server
- A User name to log in on the server
- 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:
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:
- Where the -t flag is responsible for the type of the generated key
- 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.
- Where .ssh/bddt2.pub is the path to the public part of the key
- Where USERNAME is the username through which you want to get to the server, usually root if no other users have been created yet.
- 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:
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:
Now let's talk about why I installed all of this, and what each of these commands did:
- apt-get update - Always run it first when installing any package. It syncs the application package index and updates all dependencies if necessary.
- apt-get upgrade - Installs the latest versions of installed packages on the system.
- apt-get install gettext libgettextpo-dev - it installs the dependencies needed to generate translations for your sites (which use the gettext utility)
- apt-get install pkg-config default-libmysqlclient-dev build-essential - necessary dependencies for working with MySQL databases.
- apt-get install nginx - to start the web server
- apt-get install gunicorn - to redirect requests from the nginx server to our django application
- apt-get install python3-dev python3.12-venv - to be able to create a virtual environment when running 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:
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.
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.
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:
After running all these commands, you should have the following project structure:
- bddt2.space <- You are here
- venv
- source
Now, activate the virtual environment and install the necessary packages from 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):
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:
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:
- First, you need to know which backend to connect to - django.db.backends.mysql
- Second, the database name - bddt2_bd
- Third, the username - bddt2_user
- Forth, the database password - aD9bN5oV3pjD7qJ9
- Fifth, the database host name (address) - 79.174.89.21
- 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:
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.
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:
- Where YOUR_DESIRED_DOMAIN is the desired domain
- 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:
- In this configuration, we set up the port on which we will listen for incoming requests.
- The name for our server (domain name). In my case, it should be bddt2.space.
- 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.
So the final version of this configuration will look like this:
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.
All the necessary directories have been created and now we are ready to create soft links to these directories:
The project now has the following structure:
- bddt2.space
- venv
- media
- static
- source
- Website
- Backend
- Frontend
- Website
- media -> ../../media
- static -> ../../static
- manage.py
- settings.json
- deploy.sh
- server-setup.sh
- requirements.txt
- gunicorn.service
- nginx-server-http_only.conf
- nginx-server-on_httsp-301.conf
- nginx-server-on_https.conf
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:
- Replace the user in the /etc/nginx/nginx.conf file
- Give everyone access to read files
- 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:
- site - the name of the group to which you want to add the user (it will match the user name)
- 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:
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:
Let's restart the nginx service using systemctl so that the changes take effect:
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.
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:
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.
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:
Now we generate and sign up the certificates:
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:

- Asks to enter email
- Agree to sell your soul and the soul of your site)
- Registration, optional
- Selecting domains (subdomains) for which this certificate will be valid. If you simply press ENTER, the certificate will be applied to all.
- Path to the certificate (for configuring nginx)
- Path to the key (for configuring nginx)
You can also set a cron task to update the certificate every month:
All that remains is to change the configuration in sites-available, this is done like this:
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:
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.
Comparison of launching a website on a Hosting and on a VPS
| Testing | No limit | No limit |
| Custom project structure | Limited | No limit |
| Automation of deploy, setting up etc. | Limited | No limit |
| WSGI server | Phusion Passenger | No limit |
| Web server | Apache2 | No limit |
| Migration to HTTPS | Seamless | Hard |
| Database setup | Easy | Hard |
| Linking domain | Seamless | Hard |
| Price | Cheap | Less cheap |
| Metrics | Reg.ru Hosting | Reg.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 (⌒‿⌒)