3 горизонтальные линии, бургер
3 горизонтальные линии, бургер
3 горизонтальные линии, бургер
3 горизонтальные линии, бургер

3 горизонтальные линии, бургер
Удалить все
ЗАГРУЗКА ...

Содержание



    Как сделать деплой сайта на timeweb(или хостинг, или VPS). Полная инструкция

    Часы
    24.07.2025
    /
    Часы
    01.10.2025
    /
    Часы
    23 минут
    Глазик
    2057
    Сердечки
    0
    Соединённые точки
    0
    Соединённые точки
    0
    Соединённые точки
    2

    Введение или про что статья

    В этой статье я расскажу и покажу, как можно разместить сайт на серверах от timeweb (хостинг-провайдер). Данный провайдер предоставляет широкий выбор платформ разработки/CMS, которые используются для создания сайта. Но в этой статье я расскажу только о том, как развернуть сайт написанный на Django, ибо разбираюсь в этом.
    В дополнение того, что было сказано ранее, я хочу ещё показать, как можно настроить ваш проект/сайт таким образом, чтобы при необходимости внедрения новых фич, или их исправление), это было не сложнее чем нажатие одной кнопки. Делать это будем через bash, git и ssh.
    Кроме предоставления обычного (виртуального) хостинга, timeweb предоставляет такую услугу как VPS. Так вот, на timeweb, твой сайт можно разместить двумя способами:
    1. Быстро и просто, хотя не без нюансов. Суть его в том, чтобы использовать предоставляемый функционал без необходимости пользоваться терминалом. Как ты увидишь после, всё равно придётся его использовать.
    2. Немного муторно и запутанно, но с гораздо большей свободой при размещении. Суть второго способа, заключается в том, чтобы создать свой VPS и настроить сервер в ручную. (Phusion Passenger/Gunicorn) (Nginx/Apache2)
    VPS(Virtual Private Server) - такой сервер размещён вместе с другими на одном железе(компьютере), от сюда и virtual server, так же доступ к такому серверу есть только у его владельца, от сюда и private.
    Данная статья разбита на 3 основные части:
    1. Первая — Подготовка. Её нужно выполнить вне зависимости от того, какую платформу деплоя ты выбрал.
    2. Вторая — Деплой на виртуальном хостинге. Расскажет, как развернуть сайт на виртуальный хостинг, с минимальным взаимодействием с терминалом.
    3. Третья — Деплой на VPS. Расскажет, как создать и настроить твой VPS на timeweb. После чего будет сам деплой Django-приложения.
    Я продемонстрирую оба способа. Объясню в чём особенности и нюансы обоих, и почему лучше, по моему мнению, именно VPS. Сразу к сравнению можно перейти сюда.

    Особенности данного туториала

    Для демонстрации я буду использовать специально сделанное для этого django-приложение. Это приложение было специально сделано со всеми фишками, которые возможно будет использовать твой Django сайт:
    1. Работа и настройка с БД
    2. Работа и настройка почты
    3. Работа со статикой
    4. Работа с медиа файлами
    5. Работа с переводами
    6. Тестирование приложения
    Я постоянно работаю над этим приложением, ибо собираюсь тестировать его и на других хостингах (не только timeweb). В конце концов, я вижу его как один, большой интерактивный тест хостингов, на то насколько они дружелюбны к Django-сайтам.

    Подготовка, или покупаем домен

    Для того чтобы купить домен, зайди на https://hosting.timeweb.ru/domains/registration. Там будет поле для ввода желаемого домена, вводишь, регистрируешь:
    Выбор и регистрация домена на timeweb.com
    После будет перенаправление на страницу настроек домена, там необязательно брать SSL сертификат. Чуть позже, мы установим бесплатный от LetsEncrypt
    Настройка нового домена на timeweb.com
    Теперь, когда у нас на руках есть домен, привяжем его к сайту и установим SSL сертификат. Всё это можно сделать, уже на этой странице https://hosting.timeweb.ru/domains/settings?fqdn=DOMAIN_NAME
    Привязывать и устанавливать SSL сертификат, нужно только в том случае если мы размещаем сайт на виртуальном хостинге. Если ты решил развернуть сайт на VPS - не делай этого.
    Где DOMAIN_NAME - это полное название новоприобретённого домена.
    Чтобы привязать домен к сайту, его нужно ещё создать. Это можно сделать на этой странице https://hosting.timeweb.ru/sites.
    Зачем вообще париться насчёт SSL сертификата? Разве мой сайт не будет работать без него? Будет и неплохо, просто ему не будут доверять пользователи, браузеры и поисковые системы, особенно если сайт про финансы, политику или другие очень важные темы, где безопасность отправляемых запросов на сервер в приоритете.
    1. Нужно будет обязательно прикрепить домен к созданному сайту. После придётся ещё подождать от 15 минут до 24 часов, пока DNS не обновиться.
    2. После нажатия, будет представлен выбор доступных SSL сертификатов. Выбирай LetsEncrypt и идём дальше

    Деплой на виртуальном хостинге

    Создание базы данных

    У нас есть уже есть сайт и привязанный к нему сайт. Давай к списку завершённых дел, добавим ещё и базу данных. Создание и редактирование баз данных происходит тут -> https://hosting.timeweb.ru/mysql
    Страница создания базы данных
    Тебе нужно будет заполнить, а потом и запомнить следующие значения:
    1. Имя базы данных (cs86772_bd для меня соответственно)
    2. Имя пользователя (будет совпадать с именем базы данных)
    3. Пароль базы данных
    Так же, если собираешься размещать сайт на VPS не забудь добавить дополнительный адрес доступа к БД.
    Timeweb на данный момент предоставляет базы данных только на MySQL 8

    Создание почты

    Настройка почты ещё легче чем базы данных. На странице https://hosting.timeweb.ru/mailman нажми на "Добавить ящик" и введи требуемые данные. Нужно будет запомнить следующие данные (они потребуются для настройки после):
    То что выделено КАПСОМ и жирным шрифтом, является название константы, которую можно будет применить после, в settings.py файле.
    1. some@cs86772.tw1.ru - логин для входа (EMAIL_HOST_USER)
    2. 743Ew0x35 - пароль для входа (EMAIL_HOST_PASSWORD)
    1. smtp.timeweb.ru - почтовый сервер для отправки почты (EMAIL_HOST)
    2. 465 - порт для подключения к почтовому серверу (EMAIL_PORT)
    SMTP (Simple Mail Transfer Protocol) - это стандартный протокол, используемый для передачи электронной почты между почтовыми серверами в интернете. Он обеспечивает отправку и получение писем, а также пересылку сообщений между серверами
    POP3 (Post Office Protocol 3) - это протокол, используемый для получения почты с почтового сервера на устройство пользователя
    IMAP (Internet Message Access Protocol) - это протокол, который позволяет пользователям получать доступ к электронной почте, хранящейся на удаленном сервере, и управлять ей с помощью различных устройств, таких как компьютеры, планшеты или смартфоны

    Подключение к виртуальному хостингу через SSH

    Закончив с подготовительной частью, можно переходить непосредственно к деплою. Чтобы иметь возможность работать с удалённым сервером, нам необходимо подключиться к нему. Есть несколько способов это сделать, самый простой это использовать встроенные команды и утилиты самого хостинга.
    И чтобы получить доступ через SSH, можно воспользовавшись браузерным терминалом от timeweb.
    Это довольно важно. Не знаю почему этого не пишут, но, для того чтобы активировать доступ к серверу через SSH, требуется подтверждение через мобильный телефон (ТОЛЬКО РОССИЙСКИЙ). Хоть вариантов предлагают больше. Я сам из Беларуси, поэтому возникла небольшая заминка (╯_╰). Пришлось обращаться в службу поддержки, там они без проблем активировали мой аккаунт, так что не стесняйтесь, спрашивайте.
    Вход в веб-терминал
    Стилизованная при помощи команды начальная страница
    SSH (Secure SHell) - это интернет-протокол по которому осуществляется безопасное, зашифрованное общение между клиентом и сервером. Есть SSH-клиент (он необходим для тех машин, с которых будет осуществлено подключение), а есть SSH-сервер (он необходим, если вы хотите предоставить удалённый доступ к своей машине). Все сервера имеют SSH-сервер установленным по умолчанию.

    Установка виртуального окружения

    Увы, но нас не получиться использовать встроенный модуль venv, чтобы создать виртуальное окружение. Вместо этого придётся работать вот так. Скачаем архив с необходимой версией python:
    cd bddt3.site wget https://bootstrap.pypa.io/virtualenv/X.X/virtualenv.pyz
    На момент написания данной статьи виртуальные хостинги от timeweb поддерживает только две версии python:
    1. Python 3.10 - на Ubuntu 22.04
    2. Python 3.6 и Python 2.7 - на Ubuntu 18.04
    Наконец создадим виртуальное окружение, вот так:
    python3 virtualenv.pyz venv
    Теперь можно его активировать и установить необходимые пакеты для работы нашего сайта.

    Перенос файлов сайта

    Для работы сайта требуется сам сайт. Надо как-то его перенести на хостинг. Поэтому для переноса файлов сайта можно воспользоваться встроенный файловым менеджером или командой терминальной командой - scp.
    scp (secure copy) — это утилита командной строки, которая позволяет безопасно копировать файлы и каталоги между двумя местами (машинами/серверами).
    А если твой проект использует систему контроля версий исходного кода, то есть git. Как у меня, то можно просто клонировать необходимый репозиторий:
    cd ~/bddt3.site/public_htmk && git clone https://github.com/DmRafaule/DjangoDeploymentTest source
    1. Где bddt3.site/public_html - это директория сайта
    2. Где source - это директория в которую будет клонирован Django-сайт
    После успешного переноса файлов сайта, наконец активируем виртуальное окружение и установим необходимые пакеты:
    cd ~/bddt3.site/public_html && source ../venv/bin/activate && pip install -r source/requirements.txt

    Конфигурация статических и медиа файлов

    Что я подразумевая под конфигурацией статических и медиа файлов? Дело в том, что при сборе статических файлов или загрузки файлов на сервер. Они, файлы, будут помещены в static и media директорию соответственно. А эти директории, в свою очередь, будут созданы относительно корневой директории проекта. То есть там, где располагается manage.py файл.
    Шутка в том, что у веб-сервера нет доступа к корневой директории проекта, но у него есть доступ к директории public_html. Нам нужно создать директории static и media в public_html, а после создать мягкие ссылки на них из корневой директории проекта. Это можно сделать так:
    cd ~/bddt3.site/public_html/source/Website && mkdir ../../static && mkdir ../../media && ln -s ../../static static && ln -s ../../media media
    Мягкая ссылка, также известная как символическая ссылка или симлинк (symlink), - это специальный вид ссылки в файловой системе, который указывает на другой файл или каталог, но не содержит данных файла-оригинала.
    Главное оказаться в директории рядом с manage.py файлом. Там и должны быть созданы мягкие ссылки.

    Работа с файлами конфигурации хостинга (.htaccess и wsgi.py)

    Настройка файлов .htaccess и wsgi.py имеет свою специфику, которая свойственна только хостингу от timeweb. Как .htaccess, так и wsgi.py файлы должны находиться в public_html.
    Мы имеем следующую структуру проекта:
    1. ~/bddt3.site <- Ты здесь
    2. venv
    3. public_html
    4. cgi-bin
    5. media
    6. static
    7. source
    8. Website
    9. Website
    10. settings.py
    11. Frontend
    12. Backend
    13. manage.py
    14. settings.json (Про этот файл в следующей главе)
    15. media -> ../../media
    16. static -> ../../static
    17. requirements.txt
    18. .htaccess (В этой главе работаем с этим файлам)
    19. wsgi.py (В этой главе работаем с этим файлам)
    20. index.htm
    Задача файла конфигурации .htaccess, состоит в том, чтобы перенаправлять запросы направленные на web-сервер Apache на наше Django-приложение. Ещё вам нужно знать одну важную особенность хостинга на timeweb. Они для хостинга используют особый модуль для хостинга -> mod_wsgi.
    По сути это значит, что ты сможешь использовать WSGI протокол для работы хостинга, но не ASGI.
    WSGI (Web Server Gateway Interface) — стандарт обмена данными между веб-сервером и веб-приложением, написанным на Python и описанный в документе PEP 333. Подробно о нём написал Юревич Юрий здесь
    ASGI (Asynchronous Server Gateway Interface) - это стандарт, определяющий, как веб-серверы взаимодействуют с асинхронными веб-приложениями и фреймворками в Python
    Твой .htaccess файл должен содержать следующее, чтобы работать:
    Options +ExecCGI AddHandler wsgi-script .py RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ /wsgi.py/$1 [QSA,PT]
    Надо ещё написать простенький wsgi (файл должен называться wsgi.py) скрипт для работы и поместить его в одну директорию рядом с .htaccess. Вот содержимое файла wsgi.py:
    import os import sys #1 activate_this = os.path.expanduser('~/bddt3.site/venv/bin/activate_this.py') exec(open(activate_this).read(), {'__file__': activate_this}) #2 sys.path.insert(1, os.path.expanduser('~/bddt3.site/public_html/source/Website')) from django.core.wsgi import get_wsgi_application #3 os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Website.settings') application = get_wsgi_application()
    Всё что выделено, это то, что тебе предстоит поменять для своего сайта.
    1. Путь до скрипта активации виртуального окружения
    2. Путь до корневой директории проекта (это там, где файл manage.py находится)
    3. Путь до модуля настроек (относительно путя указаного во втором выделении)

    Настраиваем наш Django-сайт

    Когда ты закончил со созданием и конфигурацией файлов для работы шлюза Phusion Passenger и веб сервера Apache2, можно заняться редактированием файла конфигурации Django-сайта, то есть settings.py.
    Если ты делаешь всё на моём примере, то ты мог заметить, что мой файл конфигурации Django-сайта немного видоизменён. Все данные для конфигурации он берёт из другого файла - settings.json.
    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 # ...
    Пример того, как выглядит мой видоизменённый файл - settings.py
    Файл конфигурации находится в корневом каталоге проекта, рядом с manage.py. Его содержимое будет выглядеть как-то так:
    { "SECRET_KEY": "django-insecure-4#-wrp_(53^0_9$%p8lq+qf43z0fje9iwoeifoweii jjfepiejfh!sa1mfn^l)4-lq@", "DEBUG": false, "ALLOWED_HOSTS": ["bddt3.space"], "DATABASES": { "default": { "ENGINE": "django.db.backends.mysql", "NAME": "cs86772_db", "USERNAME": "cs86772_db", "PASSWORD": "cL1PcShz", "HOST": "localhost" } }, "DEFAULT_FROM_EMAIL": "bddt3@cs86772.tw1.ru", "DEFAULT_TO_EMAIL": "timachuduk@gmail.com", "EMAIL_HOST": "smtp.timeweb.ru", "EMAIL_PORT": 465, "EMAIL_HOST_USER": "bddt3@cs86772.tw1.ru", "EMAIL_HOST_PASSWORD": "D631nL2Fn" }
    Это уже полностью сконфигурированный файл с использованием всех данных, о которых я говорил, что их нужно запомнить.
    1. Для того, чтобы узнать что и куда вставлять для базы данных, смотри главу о создании базы данных - Создание базы данных
    2. Для того, чтобы узнать что и куда вставлять для почты, смотри главу о создании и почты - Создание почты
    Я поменял DEBUG на false т.к. мы разворачиваем Django-проект уже на боевом сервере. Так же нужно добавить в ALLOWED_HOSTS имя приобретённого тобой домена. Плюс не забудь поменять SECRET_KEY на новый.

    Завершаем деплой

    И последними штрихами для завершения развёртывания сайта являются следующие команды:
    1. Миграция базы данных [./manage.py migrate]
    2. Сбор статических файлов [./manage.py collectstatic]
    3. Компиляция переводов (если есть) [./manage.py compilemessages]
    4. Проверка тестов (если есть) [./manage.py test]
    После успешного выполнения каждой из них, можно считать, что сайт успешно развёрнут.
    Хочется сказать, что сделать компиляцию переводов у тебя не получиться, ибо не установленны необходимые зависимости для этого. По этому если ты решил, что будешь делать многоязычный сайт, то тебе нужен явно не этот хостинг

    Деплой на VPS

    Итак, если ты прочитал первую часть, то ты не мог не заметить существенных минусов, которые несёт размещение на виртуальном хостинге. Так например, у тебя не получиться реализовать асинхронное общение между веб-сервером и твоим приложением (ASGI). Или тебе не удастся создать многоязычный сайт.
    На VPS, таких трудностей не предвидится. И я покажу, как можно разместить сайт на VPS.

    Создаём VPS

    VPS и виртуальный хостинг это две разные сущности и работают с ними по-разному. Так, чтобы создавать и управлять своими виртуальными машинами тебе потребуется зайти сюда - https://timeweb.cloud.
    После этой страницы, тебе будет предоставлена возможность сконфигурировать свой сервер. Я сделаю самый дюшманский сервер, который только смогу, как всегда. По итогу, самый простой сервер тебе обойдётся в 500:
    1. Выбираю Ubuntu 22.04
    2. Физическое расположение сервера (Это не столь важно если используешь CDN или у тебя одноязычная аудитория)
    3. Какое железо использовать (Чем сложнее проект, тем круче надо брать)
    4. Будет ли у меня публичный IP. То есть смогу ли я вбить его адрес в поиск и получить, что-нибудь
    5. SSH-ключ, для тех кто помешан на безопасности и тех, кому лень вбивать пароль для входа.( Нужно отправить публичную часть ключа)

    Редактируем DNS

    Это делается достаточно быстро. Так как мы уже приобрели домен, нужно будет всего две записи A и AAAA. Если конкретнее, нужно будет поменять IP по умолчанию на IP нашего VPS сервера. На этой странице выбираете VPS который недавно создали и копируете его IPv4 и IPv6.
    После чего меняем DNS записи для нашего домена, в моём случае это bddt3.space:
    DNS (Domain Name System) - Это телефонная книга интернета, преобразующая понятные человеку доменные имена (например, google.com) в числовые IP-адреса, используемые компьютерами для определения местоположения друг друга. Она позволяет пользователям получать доступ к веб-сайтам и другим онлайн-ресурсам, используя легко запоминающиеся имена вместо сложных IP-адресов.
    Учти, чтобы DNS сервера поменялись потребуется время. Сколько? Бывает по-разному, у меня это заняло 15 минут. Только учти что у браузеров есть свой встроенный DNS кеш. Посмотреть его ты можешь вбив вот это(для firefox) : about:networking#dns.
    Таким образом, при обращении по указанному домену (в моём случае это bddt3.space), DNS сервер укажет на нужный нам (то есть созданный нами) VPS сервер.

    Создаём базу данных на VPS

    Любому сайту, так или иначе требуется место для хранения данных. Данный хостинг провайдер поддерживает множество баз данных (MySQL, PostgreSQL, MongoDB ...). Я продемонстрирую работу с MySQL потому что хорошо знаком с ней.
    Так ты создашь базу данных и предварительно настроишь её. После её успешного развёртывания (а это займёт 5-10 минут), нужно будет отредактировать файл settings.json, но об этом чуть ниже, а пока я покажу какие данные нам нужно будет знать:
    1. Публичный IP - 89.169.1.110
    2. Логин пользователя - gen_user (Значение по умолчанию
    3. Пароль пользователя - *******
    4. Имя базы данных - default_db (Значение по умолчанию)
    5. Порт подключения - 3306 (Значение по умолчанию)
    Эти данные потребуются в главе про подключение к базе данных MySQL. Ну а пока, подключимся к VPS и перенесём сайт.

    Подключаемся к созданному VPS через SSH

    Мы успешно создали свой первый виртуальный сервер( и базу данных) на Timeweb, теперь нужно к нему подключиться. Для этого будем использовать SSH. И чтобы можно было подключиться к нашему серверу нужно узнать его IP и пароль к нему. Всё это приходит по почте, которую вы указали при регистрации аккаунта на Timeweb.
    SSH (Secure SHell) - это интернет-протокол по которому осуществляется безопасное, зашифрованное общение между клиентом и сервером. Есть SSH-клиент (он необходим для тех машин, с которых будет осуществлено подключение), а есть SSH-сервер (он необходим, если вы хотите предоставить удалённый доступ к своей машине). Все сервера имеют SSH-сервер установленным по умолчанию.
    Или, как вариант, можно посмотреть в админке хостинга. Скопируй указанную команду и используй в терминале:
    Пароль при необходимости можно будет сбросить, а имя пользователя к которому всегда можно подключиться это root - всегда. Подключимся же к нашему серверу:
    ssh root@92.51.22.80
    На Linux машинах SSH-клиент установлен по умолчанию, но на Windows нет. Чтобы активировать SSH-клиент, потребуется просто активировать такую "Фичу". Вот замечательная статья об этом.
    А через что, собственно подключаться? Можно через PowerShell, можно через Git Bash если привык к Линукс, можно и через специально созданные программы для подключения к серверам через SSH, а можно установить специальное расширение для VSCode и получить не только терминал на удалённом сервере, но и файловый менеджер и среду разработки - расширение такое называется если что Remote - SSH.
    Так как я пока работаю и сижу на Windows, буду использовать самый простой и доступный способ, здесь и дальше - PowerShell.

    Подключение к серверу по ключу (опционально)

    Я вангую, тебе придётся очень часто заходить на удалённый сервер, хотя бы потому, что связь может постоянно обрываться, а вручную вписывать пароль для подключения, та ещё задачка.
    По этому, предлагаю создать ключ-пару для авторизации без пароля. Для этого, на своём рабочем компьютере, введи команду:
    ssh-keygen -t rsa -f .ssh/bddt3
    1. Где флаг -t отвечает за тип сгенерированного ключа
    2. Где флаг -f отвечает за путь к файлу (который может не существовать), куда будет сохранён ключ
    После генерации у тебя будут два файла, bddt3 и bddt3.pub. Первый (bddt3), это приватный ключ, храни его как зеницу ока, он нужен для авторизации. Второй ключ (bddt3.pub) раздаётся всем удалённым серверам, к которым ты хочешь получать доступ без ввода пароля.
    Осталось выполнить ещё одну команду, а именно передать ключ на удалённый сервер, на который ты хочешь попасть по ключу.
    ssh-copy-id .ssh/bddt3.pub USERNAME@SERVER
    1. Где .ssh/bddt3.pub - путь к публичной части ключа
    2. Где USERNAME - это имя пользователя, через которое ты хочешь попасть на сервер, обычно это root, если никаких других пользователей ещё не создавалось.
    3. Где SERVER- это адрес удалённого сервера. Это может быть как IPv4, так и доменное имя.
    Мы закончили. После этого, чтобы войти на сервер, используй данную команду:
    ssh USERNAME@SERVER_ADDR -i .ssh/bddt3

    Устанавливаем необходимые пакеты

    Теперь время для Ctrl-C, Ctrl-V. Сейчас будет немного команд, которые установят на ваш сервер необходимые пакеты:
    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 &&
    А для того, чтобы установить новейшие версии Python, потребуется обновить индекс репозитория пакетного менеджера Ubuntu
    add-apt-repository ppa:deadsnakes/ppa && apt-get update
    И тогда можно установить Python и всё необходимое:
    apt-get install python3.12 python3.12-venv python3.12-dev
    Теперь давай поговорим о том, для чего я всё это установил, и что сделала каждая из этих команд:
    1. apt-get update - всегда выполняй её первой, при установке любого пакета. Она синхронизирует индекс пакетов приложений и обновляет все зависимости, при необходимости.
    2. apt-get upgrade - устанавливает самые последние версии установленных пакетов на системе.
    3. apt-get install gettext libgettextpo-dev - она устанавливает зависимости необходимые для генерации переводов для твоих сайтов (которые используют утилиту gettext)
    4. apt-get install pkg-config default-libmysqlclient-dev build-essential - необходимые зависимости для работы с базами данных на MySQL.
    5. apt-get install nginx - для запуска веб-сервера
    6. apt-get install gunicorn - для переадресации запросов от nginx-сервера к нашему django-приложению
    7. apt-get install python3.12 python3-dev python3.12-venv - для возможности создания виртуального окружения при работе python-приложений
    С установкой необходимых пакетов на сервер мы закончили. Остались только "не необходимые". Можешь пропустить до начала следующей главы, если у тебя нет функциональных тестов в приложении.
    nginx - это легко конфигурируемый веб-сервер и прокси для запросов направляемые на сервер.
    gunicorn - это сервер для python-приложений который связывает веб-сервера (такие, как nginx и apache) и python приложение
    Мой "не необходимый" пакет - это selenium. Чтобы мои функциональные тесты отработали, мне он необходим. И чтобы он работал, ему потребуется браузер Firefox, который мы и установим как .deb пакет. О бой, это то ещё приключение ヽ(°〇°)ノ. Всех интересующихся приглашаю посетить официальный сайт мозилы и выполнить одну команду за другой
    В дополнение к firefox, потребуется ещё установить geckodriver. Версии последних релизов можно найти здесь: https://github.com/mozilla/geckodriver/releases . И теперь, команда для установки этого 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/
    Скачав (wget) и разархивировав geckodriver (tar -xzvf), мы после поместили его в /usr/local/bin/ директорию, чтобы у всех приложений был доступ к драйверу.

    Создаём пользователя

    Этот шаг обязателен и не думай делать сайт на root-правах. Сейчас необходимо будет создать пользователя с root привилегиями и домашней директорией.
    useradd -m -s /bin/bash site passwd site usermod -aG sudo site
    Первая команда создаст пользователя по имени "site", создаст для него домашнюю директорию (флаг -m) и установит командную оболочку по умолчанию т.е. bash. Вторая команда задаст пароль для нового пользователя. Третья добавит пользователя "site" в sudo группу, которая способна выполнять все команды, только с использованием команды sudo.
    sudo - это команда(программа) выполняемая в терминале на Unix-like операционных системах (Linux, MacOS), которая позволяет запускать другие программы с разрешениями выполнять административные и потенциально опасные команды.

    Перенос проекта

    База для нашего сервера готова, теперь давай займёмся файлами самого сайта. Я собираюсь создать простую файловую структуру, где при помощи git получу файлы своего проекта и скопирую их в source директорию. А так же, создам виртуальное окружение:
    Все дальнейшие команды я выполнял от лица ново созданного пользователя "site". Если, что-то изменится, я дам знать.
    mkdir ~/bddt3.space cd ~/bddt3.space git clone https://github.com/DmRafaule/DjangoDeploymentTest source python3.12 -m venv venv
    После выполнения всех этих команд, у тебя должна будет получиться следующая структура проекта:
    1. bddt3.space <- Ты тут
    2. venv
    3. source
    Теперь, активируем виртуальное окружение и установим необходимые пакеты из source/requirements.txt:
    source ./venv/bin/activate pip install -r source/requirements.txt
    Здесь не должно возникнуть ни каких проблем, но если всё таки возникли прочитайте внимательно логи ошибок. Зачастую, это просто не установленные зависимости на сервере, которые легко исправить при помощи пакетного менеджера apt.
    Давай попробуем запустить установленное Django-приложение (предварительно зайдя в директорию с файлом manage.py:
    cd ./source/Website python manage.py runserver

    Подключение к базе данных MySQL

    Тебе выдаст ошибку, что файл settings.json не был найден. Это файл конфигурации, который я использую как прокси, вместо того чтобы писать непосредственно в settings.py. Сделал я это с той целью, чтобы можно было безопасно добавлять файл settings.py в git репозиторий и для упрощения развёртывания.
    Вот пример такого файла(settings.json), создай его в source/Website директории:
    { "SECRET_KEY": "django-insecure-4#-wrp_(53^0_9$%p8lq+qf43z0dx0ji6bh!sa1mfn^l)4-lq@", "DEBUG": true, "ALLOWED_HOSTS": ["bddt3.space"], "DATABASES": { "default": { "ENGINE": "django.db.backends.mysql", "NAME": "default_db", "USER": "gen_user", "PASSWORD": "aD9bN5oV3pjD7qJ9", "HOST": "89.169.1.110", "PORT": 3306 } }, "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.bddt3.space" }
    Как ты видишь, я уже использую MySQL в качестве базы данных. Что нужно знать для подключения к базе данных из VPS:
    1. Во-первых нужно знать какой бекенд подключать - django.db.backends.mysql
    2. Во-вторых имя базы данных- default_db
    3. В-третьих имя пользователя - gen_user
    4. В четвёртых, пароль от базы данных - aD9bN5oV3pjD7qJ9
    5. В пятых, имя хоста базы данных - 89.169.1.110
    6. И в шестых, порт подключения - он всегда один и тот же - 3306
    Все эти данные можно получить при создании своей базы данных, процесс которого я описал в соответствующей главе.
    Как я переношу, данные из settings.json в Website/settings.py? В файле settings.py я открываю файл settings.json и читаю от туда данные, вот так:
    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 # ...
    Использую JSON-формат, ибо просто очень удобно с ним работать через Python.

    Заканчиваем перенос проекта

    Уже, кстати, можно запустить тесты и посмотреть, что работает, а что нет. Всё должно отработать. Итак, мы успешно закинули наш сайт на сервер и даже прошли все тесты. А это значит, что пора настроить nginx, после чего свяжем наш сайт с nginx веб-сервером через gunicorn.
    Почему, а главное зачем именно Nginx и Gunicorn? Смотри, nginx делает наш VPS сервер, как бы доступным для других машин. Он настраивает 80-й порт и домен(при необходимости), чтобы другие машины знали где он, и куда направлять свои запросы. Но одного nginx мало, нам нужно как-то передать запросы от других машин на наше Django-приложение. Для этого и используется Gunicorn, он тоже прослушивает соответствующий, 80-й порт (хотя можно и нужно это делать через UNIX-сокеты, я покажу), а после того как получил запрос направляет его в Django-приложение, где уже и происходи вся остальная логика сайта.

    Супер быстрая настройка Nginx (очень опционально)

    Дальше я собираюсь подробно описать, для чего используется каждый файл, как запускать и перезапускать nginx, плюс как добавлять сайты на nginx. Если тебе это интересно, то милости прошу, но если нет ты можешь воспользоваться скриптом server-setup.sh, который я оставил в репозитории.
    Чтобы им воспользоваться, введи:
    ./server-setup.sh YOUR_DESIRED_DOMAIN on_https
    1. Где YOUR_DESIRED_DOMAIN - это желаемый домен
    2. Где on_https - это флаг, который говорит настроить редирект на HTTPS протокол
    Этот скрипт создаст соответствующие файлы конфигураций и будет перезагружен.

    Настраиваем Nginx

    Вместе с файлами проекта, ты ещё получишь дефолтные файлы конфигурации для настройки nginx - nginx-server-http_only.conf, nginx-server-https_301.conf, nginx-server-https.conf. Пока открой файл nginx-server-http_only.conf, ты увидишь следующую конфигурацию для нашего сайта:
    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. В этой конфигурации мы настраиваем порт на котором мы будем слушать входящие запросы.
    2. Имя для нашего сервера (доменное имя). В моём случае это должно быть bddt3.space.
    3. Папки, которые этот сервер будет обслуживать. Как минимум нужно настроить корневой каталог "/". Но этим всё не ограничивается, на моём сайте используется различная статика в виде картинок и иконок. Плюс медиа файлы, которые загружаются непосредственно пользователем.
    Что за непонятные переменные USER_PLACE_SETUP и HOST_PLACE_SETUP? Всё дело в том, как работает мой кастомный скрипт по настройке сервера. Если вкратце, то он, используя sed команду заменяет две вышеуказанные переменные и заменяет их на необходимые администратору значения. Всё это делается через специальный скрипт server-setup.sh, о котором через главу.
    Итак, финальная версия этой конфигурации будет выглядеть вот так:
    server { listen 80; server_name bddt3.space; location /static { root /home/site/bddt3.space; } location /media { root /home/site/bddt3.space; } location / { proxy_set_header Host bddt3.space; proxy_pass http://unix:/tmp/bddt3.space.socket; } }
    Чтобы не забыть, давай сразу создадим директории media и static в ~/bddt3.space директории и мягкие ссылки на них. Мягкие ссылки на них создаются с тем, чтобы предоставить серверу доступ к ним.
    cd ~/bddt3.space mkdir static mkdir media cd source/Website
    Мягкая ссылка, также известная как символическая ссылка или симлинк (symlink), - это специальный вид ссылки в файловой системе, который указывает на другой файл или каталог, но не содержит данных файла-оригинала.
    Все необходимые директории были созданны и теперь мы готовы создать мягкие ссылки, на эти директории:
    ln -s ../../static static ln -s ../../media media
    При работе с медиа файлами, сервер может дать 413 ответ - 413 Request Entity Too large. Связано это с тем, что максимальный размер тела в запросе по умолчанию может быть не больше 1 Мегабайта. Что бы изменить это, в файле /etc/nginx/nginx.conf, в раздел http добавь: ```client_max_body_size 50M;```
    Теперь, любой файл который будет создан в директории ~/bddt3.space/source/Website/static или ~/bddt3.space/source/Website/media будет доступен и в директориях ~/bddt3.space/static и ~/bddt3.space/media.
    Чтобы это проверить, можешь запустить команду collectstatic и убедиться что все файлы, хоть и были скопированы в ~/bddt3.space/source/Website/static, так же доступны и в ~/bddt3.space/static.

    Решаем проблему с 403 ошибкой - запрещено (опционально, надеюсь)

    Ещё одна, очень часто возникающая проблема, это то что сервер может возвращать 403 ответ на запрос какого-нибудь статического файла. Зачастую это связано с тем что у пользователя www-data, нет разрешения на чтение определённых файлов. В файле настройки nginx указан пользователь от лица которого и запускается веб-сервер.
    Чтобы это исправить есть три способа:
    1. Заменить пользователя в файле /etc/nginx/nginx.conf
    2. Дать доступ всем к чтению файлов
    3. Добавить пользователя www-data в группу пользователя, который запускает приложение.
    Я опишу 3-й ибо это, на мой взгляд самый простой и правильный способ. И нужно всего лишь выполнить одну команду:
    sudo usermod -aG site www-data
    1. site - имя группы к которому хотите добавить пользователя (оно будет совпадать с именем пользователя)
    2. www-data - имя пользователя, которого хотите присоединить к группе.
    Теперь вся статика, и все медиа файлы на сайте должны быть доступны.

    Заканчиваем настройку Nginx

    Давай закончим настраивать веб-сервер и скопируем созданный файл конфигурации в /etc/nginx/sites-available:
    sudo cp ~/bddt3.space/source/nginx-server.conf /etc/nginx/sites-available/staging-nginx-server.conf
    Теперь сделаем то же самое что и с директориями static и media, создадим мягкую ссылку на этот файл конфигурации. Но сначала перейди в директорию где должна быть эта ссылка:
    sudo cd /etc/nginx/sites-enabled sudo ln -s ../sites-available/staging-nginx-server.conf staging-nginx-server.conf
    Перезапустим nginx-службу при помощи systemctl, чтобы изменения вошли в силу:
    sudo systemctl restart nginx
    Я думаю, сейчас стоит попробовать посетить наш сайт - bddt3.space.
    И да, ты должен увидеть что-то вроде этого. Почему так происходит, что за "Плохой шлюз"? А дело всё в одной строке, в файле конфигурации сайта /etc/nginx/sites-available/staging-nginx-server.conf.
    ... proxy_pass http://unix:/tmp/bddt3.space.socket; ...
    По факту, nginx-сервер перенаправил мой GET-запрос по указанному сокету, но к нему ещё ничего не подключено. Вот на этом моменте в роль вступает gunicorn.

    Настраиваем Gunicorn

    Почти готовый файл конфигурации, находится там же где и файл конфигурации nginx-сервера - ~/bddt3.space/source/gunicorn.service. Это файл описывающий работу linux-демона, вот его содержимое:
    [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
    Данный скрипт имеет подстановочные переменные HOST_PLACE_SETUP И USER_PLACE_SETUP. Я заменяю их на необходимые мне значения через специальный скрипт server-setup.sh. О нём подробнее в следующей главе.
    Данный сервис(демон), запущенный пользователем site и с его привилегиями, будет перезагружаться каждый раз при возникновении какой-либо ошибки (Restart=on-failure). Работать данный демон будет в директории указанной в WorkingDirectory. А делать он будет то, что указано в ExecStart, то есть запускать gunicorn сервер.
    При запуске gunicorn мы так же указали к какому сокету подключаться и куда перенаправлять запросы - в наше Django-приложение.
    Создай такой же файл в /etc/systemd/system/ и отредактируй вставив своего пользователя, свой домен и свой сокет. Теперь запустим службу и сделаем так, чтобы она запускалась на сервере при загрузке.
    sudo cp ~/bddt3.space/source/gunicorn.service /etc/systemd/system/gunicorn.service sudo vim /etc/systemd/system/gunicorn.service sudo systemctl start gunicorn sudo systemctl enable gunicorn
    Теперь всё будет работать. Мы создали специальный сервис, который запускает gunicorn-сервер при старте, а он в свою очередь запускает наше django-приложение. Обновив вкладку, ты должен будешь увидеть следующее:
    На этом, процесс развёртывания Djanog-сайта на VPS от Timeweb завершён. Рекомендую ещё прочитать следующую главу о том как поместить данный сайт на новый протокол HTTPS.

    Переходим на HTTPS (опционально, хотя не очень)

    Для того чтобы поместить наш сайт на HTTPS протокол, потребуется получить специальный сертификат. Его мы получим у LetsEncrypt. Он бесплатный, но что более классно, всё можно сделать через командную строку, а значит автоматизировать. Смотри, для того чтобы, настроить nginx веб-сервер под https, потребуется сертификат и ключ к нему.
    Команда LetsEncrypt, сделала специальную утилиту, которая очень крутая в плане поддерживаемых стеков технологий для сертификации. Вот, например страница для генерации, подписи и издания сертификатов для сайтов на nginx и использующий pip. Просто чума) И не нужно этой мозгоебли с самоподписанными сертификатами, которым никто не доверяет, и как результат, никто не заходит на сайт.
    Активируем виртуальное окружение и установим программу:
    source ~/bddt3.space/venv/bin/activate pip install certbot certbot-nginx
    Теперь генерируем и подписываем сертификаты:
    sudo ~/bddt3.space/venv/bin/certbot certonly --nginx -d bddt3.space
    Данная команда сгенерирует и подпишет сертификаты, которые расположит в /etc/letsencrypt/live/bddt3.space. Ты увидишь вот такой вот интерактивный промпт:
    1. Просит ввести почту
    2. Согласись на продажу своей души и души своего сайта)
    3. Регистрация, по желанию
    4. Выбор доменов(поддоменов) для которых будет действовать данный сертификат. Если просто нажать ENTER, сертификат будет применён ко всем.
    5. Путь до сертификата (для настройки nginx)
    6. Путь до ключа (для настройки nginx)
    Можно так же задать cron-задачу на обновление сертификата, каждый месяц:
    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
    Осталось только поменять конфигурации в sites-available, делается это так:
    server { listen 443 ssl; server_name HOST_PLACE_SETUP; ssl_certificate /etc/letsencrypt/live/bddt3.space/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/bddt3.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; } }
    Отличие от предыдущей конфигурации состоит в том, что мы поменяли порт и добавили ssl_certificate и ssl_certificate_key. Пути для которых вам скажет certbot. Вот собственно и всё, по тому как добавить https на ваш сайт.
    Но ты мог заметить, что при попытке получить свой сайт через обычный http, уже не получиться. Нужно будет сделать отдельную конфигурацию для 80 порта и сделать 301 редирект на https версию. Это считается хорошей практикой. Для этого создайте ещё один файл конфигурации в /etc/nginx/sites-available, например http_301_redirect-bddt3.space, и создайте файл со следующей конфигурацией:
    server { l isten 80; server_name HOST_PLACE_SETUP; location / { return 301 https://HOST_PLACE_SETUP$request_uri; } }
    Где HOST_PLACE_SETUP, это домен вашего сайта, например bddt3.space. Данная конфигурация делает 301 редирект с любых страниц с протоколом http на страницы с протоколом https.
    301 код сервера - Его ещё называют перманентный редирект, ответ сервера при котором происходит перенаправление с одного URL на другой.
    Есть ещё и 302 код сервера и это тоже редирект. Так в чём их отличие? Отличие в значении которое передаёт 302 код. Если 301, то он как бы говорит: УРЛ на который ты попал, всегда будет доступен только по новому адресу. А 302, в свою очередь говорит: УРЛ на который ты попал сейчас доступен по этому адресу, но возможно так будет не всегда.

    Сравнение запуска сайта через Хостинг и через VPS

    Возможность тестированияБез ограниченийБез ограничений
    Кастомная структура проектаОграниченаБез ограничений
    Автоматизация деплояОграниченаБез ограничений
    WSGI серверПоддерживаетБез ограничений
    ASGI серверНе поддерживаетБез ограничений
    Веб серверApache2Без ограничений
    Переход на HTTPSПочти незаметноСложно
    Настройка базы данныхЛегкоЛегко
    Подключение доменаПочти незаметноЛегко
    ЦенаДешевоДороже
    ПереводыНе поддерживаетПоддерживает
    ПоказателиTimeWeb ХостингTimeWeb VPS
    Честно скажу, я бы разворачивал сайты на виртуальном хостинге, чем самолично бы это делал на VPS. Но ограничения в версиях используемого питона, ещё в невозможности использовать другие БД, и как вишенка на торте не возможность поддержки ASGI и встроенного функционала django для локализации, сильно меня отталкивают.

    Заключение

    И вот очередной хостинг-провайдер покорён и изучен. Теперь ты знаешь, как можно размещать сайты на TimeWeb. По моему опыту скажу, что разместить сайт на TimeWeb легче чем на тех же beget и reg.ru. Хотя функционал немного урезан.
    А ещё я надеюсь, что данная статья помогла тебе разобраться с тем, как и где разворачивать твой сайт написанный на Django и на твой благой комментарий и тем, что ты можешь захотеть поделиться этой статьёй с другом или подругой, тоже надеюсь. В любом случае до встречи в следующей статье (⌒‿⌒)


    Не забудь поделиться, лайкнуть и оставить комментарий)

    Комментарии

    (0)

    captcha
    Отправить
    ЗАГРУЗКА ...
    Сейчас тут пусто. Буть первым (o゚v゚)ノ

    Другое

    Похожие статьи


    Как запустить телеграм бота на сервере (деплой телеграм бота)

    Часы
    19.01.2024
    /
    Часы
    05.10.2025
    Глазик
    5579
    Сердечки
    3
    Соединённые точки
    0
    Соединённые точки
    2
    Соединённые точки
    1
    Это гайд про то как запустить телеграм бота, написанного на python/aiogram, на сервере. Как его установить, запустить и обновлять при необходимости. А также подготовка виртуального окружения вместе с автоматизацией обновления …

    Как развернуть Django сайт на бегет хостинг (или VPS). Полная инструкция.

    Часы
    12.05.2024
    /
    Часы
    02.10.2025
    Глазик
    5615
    Сердечки
    3
    Соединённые точки
    1
    Соединённые точки
    2
    Соединённые точки
    0
    Это статья-инструкция о том как можно разместить django-сайт на beget. Показываю два способа (деплой на хостинге и деплой на VPS). Плюс, как настроить и подключить базу данных, почту, статику и …

    Как разместить django сайт на хостинг(или VPS) от reg.ru Полная инструкция

    Часы
    16.03.2025
    /
    Часы
    02.10.2025
    Глазик
    3727
    Сердечки
    0
    Соединённые точки
    0
    Соединённые точки
    2
    Соединённые точки
    0
    Как развернуть django-сайт на хостинге (или VPS) от reg.ru. Так же, как создать и настроить БД(в том числе и используя кластер в рег облаке). Настроим переадресацию на HTTPS, будет показано …