Развертывание Django в продакшн правильный способ сделать это?
Я разрабатываю приложение Django Wagtail на своей локальной машине, подключенной к локальному серверу postgres.
У меня есть тестовый сервер и рабочий сервер.
Однако, когда я разрабатываю локально и пытаюсь загрузить его, всегда возникают проблемы с makemigration и migrate, например, KeyError и т.д.
Какие наилучшие методы гарантируют, что я не столкнусь с этими проблемами? Какие файлы мне нужно перенести?
Итак, я расскажу вам, что делаю я и что делало большинство компаний, в которых я работал как разработчик django, и я могу сказать вам по опыту, что это работает довольно хорошо.
Сначала контейнеризируйте ваше приложение, это значительно упростит вашу жизнь и устранит внешнее влияние в вашем коде, а также даст вам простой способ воспроизвести вашу среду.
Ваш Dockerfile должен быть из какого-нибудь образа python и должен делать 3 основные вещи:
- Установите зависимости ваших требований
- Запустите команду
python manage.py migrate --noinput
- Запустите http-сервер, такой как gunicorn с помощью
gunicorn -c /gunicorn.py wsgi:application
Вы должны сделать makemigration на своей локальной машине и убедиться, что все работает перед фиксацией в репо.
В вашем gunicorn.py вы должны поместить ваши настройки для запуска приложения, такие как количество CPU, порт привязки, папку, в которой находится ваше приложение, что-то вроде:
import os
import multiprocessing
# Chdir to specified directory before apps loading.
# https://docs.gunicorn.org/en/stable/settings.html#chdir
chdir = '/app/'
# Bind the application on localhost both on ipv6 and ipv4 interfaces.
# https://docs.gunicorn.org/en/stable/settings.html#bind
bind = '0.0.0.0:8000'
Второй контейнер для других вещей, например, базы данных postgres, redis (для кэша), пулера соединений для базы данных в зависимости от размера вашего приложения.
Настоятельно рекомендуется, чтобы у вас был шаг в конвейере для выполнения тестов, они должны выполняться до всего, возможно, только после lint
Ок, что теперь? Теперь вам нужен способ развернуть этот материал, лучший вариант для этого сценария: вытащить образ в реестр github, и вы можете добавить тег к этому, например:
IMAGE_ID=ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME
# Change all uppercase to lowercase
IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]')
docker tag $IMAGE_NAME $IMAGE_ID:staging
docker push $IMAGE_ID:staging
Это можно добавить, например, в действие github на этапе сборки.
После того, как ваш новый код находится в новом образе внутри github, вам просто нужно обновить текущий, это можно сделать, создав скрипт для этого на сервере и запустив этот скрипт из действия github, это что-то вроде:
docker pull ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME
echo 'Restarting Application...'
docker stop {YOUR_CONTAINER} && docker up -d
sudo systemctl restart nginx
echo 'Cleaning old images'
sudo docker system prune -af
Вы видите, что я создаю изображение с тегом staging, вы можете создать правило в github actions, например, для запуска этого действия при создании нового релиза, и создать другое действие для запуска при каждом новом коммите и сборке/развертывании для тега dev.
Что касается проблемы миграции, первое, что нужно сделать, когда ваше приложение запускается, раздавить все миграции до первой (вы можете удалить базу данных и все миграции, затем создать базу данных и запустить команду makemigration снова, чтобы достичь этого), так что вы можете иметь чистую миграцию на сервере. Никогда не создавайте ненужных связей между таблицами, предпочитайте всегда делать кэшированные свойства вместо добавления новых колонок, используйте UUID для уникальных идентификаторов, и старайтесь не делать ломающих изменений в базе данных, это трудно, но если вы планируете базу данных заранее, это не так сложно сделать.
<<<Если у вас возникнут вопросы, обращайтесь ко мне. Многое из того, что я рассказал, можно сделать на многих других платформах, таких как gitlab, travis, circle ci, но я использую в примере действие github, потому что считаю его более простым для представления.
РЕДАКТИРОВАНИЕ:
Я забыл сказать, что вы должны иметь cron на вашем сервере, делающий резервные копии ваших баз данных, команда migrate применяет изменения только после проверки, но если что-то еще сломает базу данных, это может спасти вам жизнь.