Cat

Django 42. Запуск Django-проекта на VPS

Вот мы и добрались до запуска нашего проекта на сервере.

Этот пост – первый из двух, посвященных данной теме. В нём мы с вами подготовим Django для работы в Docker-контейнере и запустим его на VPS на встроенном веб-сервере. В следующем посте мы объединим Django, PostgreSQL, NGINX и Telegram-бота в одном Docker compose-сервисе.

Все статьи

Icon Link

Дополнительные материалы

Icon Link

Реклама

Icon Link
Сайт на Django proDream 06 Июнь 2024 Просмотров: 482

Вот мы и добрались до запуска нашего проекта на сервере.

Этот пост – первый из двух, посвященных данной теме. В нём мы с вами подготовим Django для работы в Docker-контейнере и запустим его на VPS на встроенном веб-сервере. В следующем посте мы объединим Django, PostgreSQL, NGINX и Telegram-бота в одном Docker compose-сервисе.

Пост является частью серии постов "Сайт на Django", и всё происходящее будет демонстрироваться на примере того, что мы делали на протяжении 41-го поста. Кроме того, он будет частично дублировать пост "AIOgram3 17. Подготовка к разворачиванию на сервере" с поправкой на особенности Django.

Приступим.

 

Переменные окружения.

Переменные окружения позволят прописать значения, такие, как логин и пароль базы данных, секретный ключ или данные от почтового сервера, в специальном файле .env (dotenv). Таким образом можно собрать все важные данные в одном файле без необходимости прописывать их непосредственно в коде (хардкодить).

Для того чтобы всё продолжало работать локально, установим библиотеку python-dotenv, выполнив команду:

pip install python-dotenv

 

Не забудьте добавить установленную библиотеку в файл requirements.txt!

В корне проекта создадим файл .env и откроем файл settings.py в директории проекта.

В самом начале файла settings.py после импортов добавим вызов функции load_dotenv(). Это необходимо, чтобы данные из .env-файла подтягивались при локальном запуске. На сервере это не нужно.

from dotenv import load_dotenv  

load_dotenv()

 

Для получения данных из переменных окружения мы воспользуемся методом .get('ключ') из функции environ() в пакете osos.environ.get('ключ'), где ключ – это переменная в .env-файле.

Нам необходимо заменить значения следующих переменных на указанную выше строку, сделав ключом имя переменной, а её текущее содержимое прописать в .env-файле:

  • SECRET_KEY.
  • NAME.
  • USER.
  • PASSWORD.
  • HOST.
  • PORT.
  • EMAIL_HOST.
  • EMAIL_HOST_USER.
  • EMAIL_HOST_PASSWORD.

Пример замены в settings.py:

SECRET_KEY = os.environ.get('SECRET_KEY')

DATABASES = {  
    "default": {  
        "ENGINE": "django.db.backends.postgresql",  
        "NAME": os.environ.get('DB_NAME'),  
        "USER": os.environ.get('DB_USER'),  
        "PASSWORD": os.environ.get('DB_PASSWORD'),  
        "HOST": os.environ.get('DB_HOST'),  
        "PORT": int(os.environ.get('DB_PORT')),  
    }  
}

 

Обратите внимание на параметр PORT. Он приведён к типу int, поскольку по умолчанию все данные из переменных окружения – строки.

Пример .env-файла:

SECRET_KEY=abcde...
DB_NAME=db_name
DB_USER=db_user
DB_PASSWORD=db_password
DB_HOST=postgres
DB_PORT=5432

 

Обратите внимание на формат имя_переменной=значение_переменной, без кавычек.

Кроме того, необходимо изменить параметр ALLOWED_HOSTS, прописав в него IP-адрес VPS, локальный адрес (127.0.0.1) и адрес домена, если он подключен к VPS. Должно быть примерно так:

ALLOWED_HOSTS = ["127.0.0.1", "pressanybutton.ru", "0.0.0.0"]
# Вместо 0.0.0.0 пропишите IP-адрес вашего VPS.

 

После того, как вынесли все важные данные из settings.py в .env, можете проверить, что всё работает как прежде, запустив проект локально.

 

Dockerfile.

Следующим шагом будет создание Dockerfile. Это специальный файл с набором инструкции по сборке Docker-образа.

Создайте файл Dockerfile без расширения со следующим содержимым:

FROM python:3.11.4-buster

ENV PYTHONDONTWRITEBYTECODE=1  
ENV PYTHONUNBUFFERED=1  

WORKDIR /code  

RUN pip install --upgrade pip  
COPY requirements.txt /code/  
RUN pip install -r requirements.txt  

COPY . /code/  

EXPOSE 8000  

CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

 

Разберём по порядку:

  • FROM python:3.11.4-buster - В этой строке указываем на используемый при сборке базовый образ. В нашем случае это Python 3.11.4. Можно взять любую версию, включая 3.12, однако учитывайте совместимости библиотек! В нашем проекте используется Django 4.2.2, поэтому и используется Python 3.11.
  • ENV PYTHONDONTWRITEBYTECODE=1 - Эта переменная окружения говорит Python не записывать файлы байт-кода (.pyc) на диск. Обычно Python автоматически компилирует исходные файлы .py в файлы байт-кода .pyc, чтобы ускорить последующий запуск программы. Однако в контейнерных окружениях это может быть нежелательно
  • ENV PYTHONUNBUFFERED=1 - Эта переменная окружения отключает буферизацию вывода Python. По умолчанию Python буферизует ввод и вывод, чтобы улучшить производительность. Это значит, что вывод в терминал или лог-файлы может быть задержан до тех пор, пока буфер не заполнится. Установка этой переменной в 1 отключает буферизацию, что приводит к немедленному выводу всех данных. Это полезно в контейнерных приложениях.
  • WORKDIR /code - В этой строке указываем, что рабочая директория с файлами проекта будет по пути /code относительно корневой директории файловой системы /.
  • RUN pip install --upgrade pip - В этой строке выполняется команда обновления pip.
  • COPY requirements.txt /code/ - В этой строке происходит копирование файла зависимостей в рабочую директорию внутри образа.
  • RUN pip install -r requirements.txt - В этой строке происходит установка зависимостей в окружение Python внутри образа.
  • COPY . /code/ - В этой строке копируем файлы проекта в рабочую директорию.
  • EXPOSE 8000 - В этой строке указываем, что наш образ будет "вещать" на 8000-м порту.
  • CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"] - В этой строке выполняем команду запуска веб-сервера Django, дополнительно указывая 0.0.0.0:8000, что позволяет веб-серверу вещать не только в пределах 127.0.0.1/localhost, но и быть доступным для других устройств в сети (сетевых интерфейсов).

 

.dockerignore файл.

По аналогии с файлом .gitignore, запрещающим добавление в индекс системы контроля версий нежелательных файлов, таких, как .env или файлов от IDE, для Docker есть такой же файл - .dockerignore
В нашем случае не нужно, чтобы внутрь контейнера попал .env-файл, поэтому в корне проекта создадим .dockerignore-файл.

В файле пропишем всего одну строку – .env.

 

Копирование файлов на VPS.

Скопировать файлы проекта можно разными способами, например, воспользовавшись git (репозиторий на github или другом сервисе) или использовав SFTP.

Я воспользуюсь SFTP и программой для этого WinSCP для Windows. Для этого подойдут и другие программы, например, FileZilla, XFTP и прочие.

Опущу этот процесс, т.к. он индивидуален, и каждый сам выбирает способ доставки файлов проекта на сервер.

 

Сборка образа.

После того, как проект подготовлен и скопированы файлы, приступим к сборке образа.

Запуск Docker-контейнера состоит из двух этапов. Первый – сборка или использование готового образа. В нашем случае готового образа нет, поэтому его необходимо создать. Второй этап заключается в запуске контейнера с указанием параметров запуска и собранного контейнера.

Все дальнейшие действия будут производиться на VPS. Подключитесь к серверу по SSH и перейдите в директорию с проектом. Момент с подключением и работой с сервером я опущу. Если вам нужен гайд по работе с сервером, сообщите об этом в комментариях (Подписчики с Boosty имеют приоритет в просьбах на будущие посты 😉)

Для сборки образа в директории проекта выполним команду:

sudo docker build -t project_image .

 

Разберём команду:

  • sudo docker - Вызываем Docker с правами администратора (root).
  • build - Сообщаем, что нам нужно собрать образ.
  • -t project_image - Присваиваем образу тег (имя), по которому будем обращаться к нему. Можно указать просто имя образа, а также дополнительно версию или другое обозначение, например, -t project_image:dev.
  • . - Точка означает, что Dockerfile для сборки образа находится в этой же директории. Если у вас он в другой, можно указать путь, полный или относительный.

Выполняем команду. Начнётся процесс сборки. Докер пойдёт по шагам, указанным в Dockerfile, начиная со скачивания базового образа и заканчивая копированием файлов. Да, он остановится на этом, т.к. последняя строка CMD ... будет выполнена при запуске контейнера, а не при сборке образа.

 

Запуск контейнера.

После того, как собрали образ, необходимо запустить контейнер.

Для этого выполним следующую команду:

sudo docker run --name project --env-file ./.env -p 8000:8000 -d project_image

 

Разберём команду:

  • sudo docker - Идентично предыдущему разделу.
  • run - Сообщаем, что мы хотим запустить контейнер.
  • --name project - Определяем имя контейнера. Если не указать, то имя будет сгенерированно случайно, но для удобства работы с контейнером его всё же стоит указывать.
  • --env-file ./.env - В данном параметре мы указываем, что нужно получить переменные окружения из .env-файла для того, чтобы они были доступны внутри контейнера. При этом самого файла там не будет.
  • -p 8000:8000 - В этом параметре указываем, что контейнер будет "вещать" наружу по 8000-му порту, используя внутренний 8000-й порт.
  • -d - Данный ключ означает, что контейнер будет запущен в фоновом режиме. Если этот ключ не указать, то при запуске контейнера в терминале будут отображаться выводящиеся в консоль логи.
  • project_image - В самом конце указываем используемый образ для запуска контейнера.

 

Проверка работы.

После того, как контейнер создан и запущен, откройте браутер и перейдите по адресу http://0.0.0.0:8000/, подставив вместо 0.0.0.0 IP-адрес сервера или, если у вас к серверу подключён домен, то http://ваш_домен:8000/.

Должен открыться сайт.

 

Дополнительно.

Если сайт не открылся, стоит проверить состояние контейнера, выполнив команду:

sudo docker ps -a

 

Эта команда отобразит все контейнеры, как запущенные, так и остановленные. Найдите в списке контейнер project и посмотрите на колонку "STATUS". Там должно отображаться UP ....

Если отображается Exited ..., следует проверить логи контейнера выполнив команду:

sudo docker logs project

 

Вероятно, там будет ответ на то, почему не работает проект.

Если же контейнер указан как UP ..., но не работает по IP, следует проверить настройки файрволла или открытые порты.

 

Заключение.

Данный пост не описывает полноценный процесс разворачивания Django-проекта на VPS, а лишь подготовку или запуск dev-сервера для того, чтобы проверять работу во время разработки.

В одном из следующих постов мы с вами разберёмся, как запустить полноценный "prod-сервер" с базой данных и веб-сервером NGINX в Docker compose-сервисе.

Автор

    Нет комментариев

    Реклама