Django 42. Запуск Django-проекта на VPS
Вот мы и добрались до запуска нашего проекта на сервере.
Этот пост – первый из двух, посвященных данной теме. В нём мы с вами подготовим Django для работы в Docker-контейнере и запустим его на VPS на встроенном веб-сервере. В следующем посте мы объединим Django, PostgreSQL, NGINX и Telegram-бота в одном Docker compose-сервисе.
Дополнительные материалы
Для скачивания материалов необходимо войти или зарегистрироваться
Файлы также можно получить в Telegram-боте по коду: 687007
Реклама
Вот мы и добрались до запуска нашего проекта на сервере.
Этот пост – первый из двух, посвященных данной теме. В нём мы с вами подготовим 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()
в пакете os
– os.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-сервисе.
Все статьи