- 1. Шаг 1 - обновление системы
- 2. Шаг 2 - Установка всех необходимых пакетов без установки виртуального окружения
- 3. Шаг 3 - Создание базы данных и пользователя базы данных
- 4. Шаг 4 - Установка виртуального окружения
- 5. Шаг 5 - Установка драйвера PostgreSQL
- 6. Шаг 6 - Создание проекта
- 7. Шаг 7 - Настройка подключения к базе данных
- 8. Шаг 8 - Выполнение миграций базы данных
- 9. Шаг 9 - Установка Gunicorn
- 10. Шаг 10 - Настройка статических файлов
- 11. Шаг 11 - Настройка Nginx
- 12. Шаг 12 - Настройка supervisor
- 13. Примечание
После того, как доступ к серверу с Ubuntu 16.04 был настроен в одной из предыдущих статей , настало время развернуть на нём всё необходимое для работы сайта, а именно:
- Django
- фреймворк для разработки web-приложений на языке Python;
- PostgreSQL
- базу данных SQL ;
- Gunicorn - WSGI HTTP сервер на Python для UNIX систем;
- Ngnix - HTTP-сервер и обратный прокси-сервер, почтовый прокси-сервер, а также TCP/UDP прокси-сервер общего назначения;
- Supervisor - это менеджер процессов, который существенно упрощает управление долго работающими программами, в частности сайтами, которые необходимо автоматически перезапускать после падений.
Шаг 1 - обновление системы
Сделаем обновление существующих пакетов. Мало ли, система имеет устаревшие пакеты.
- sudo apt-get update
- sudo apt-get upgrade
Шаг 2 - Установка всех необходимых пакетов без установки виртуального окружения
Установим пачкой все необходимые пакеты, которые не будут использоваться через virtualenv, а именно Python 3, PostgreSQL, Nginx.
- sudo apt-get install python3-dev python3-setuptools libpq-dev postgresql postgresql-contrib nginx
Pip я в итоге устанавливал отдельно через утилиту easy_install3 , которая идёт в комплекте python3-setuptools , во-первых потому, что тогда ставится последняя версия, а вторых в случае установки через apt-get были ошибки при установке пакетов в virtualenv.
- sudo easy_install3 pip
Шаг 3 - Создание базы данных и пользователя базы данных
А теперь создадим базу данных и пользователя, дав расширенные права пользователю postgres через утилиту sudo, который создаётся при установке PostgreSQL.
- sudo -u postgres psql
Выполнив данную команду, мы попадём в консоль PostgreSQL, где и создадим необходимую базу данных и пользователя, от имени которого будет подключаться Django приложение к этой базе данных.
Создадим базу данных:
- CREATE DATABASE myproject;
Создадим пользователя:
- CREATE USER myprojectuser WITH PASSWORD 'password';
Далее настройка пользователя проекта. Кодировку он будет использовать UTF8, поскольку данная кодировка используется и Django, а Python файлы рекомендует хардкодить с кодировкой UTF8, особенно, если в них присутствует текст, который будет отображаться на страницах сайта. Также устанавливается уровень изоляции в базе данных. То есть когда будут доступны данные для чтения. В данном случае после подтверждения транзакции в общем случае. Конечно, имеются случаи, когда данные доступны до подтверждения, но это отдельная тема для разговора. А также устанавливается тип временных зон, который для Django по умолчанию UTC.
- ALTER ROLE myprojectuser SET client_encoding TO 'utf8';
- ALTER ROLE myprojectuser SET default_transaction_isolation TO 'read committed';
- ALTER ROLE myprojectuser SET timezone TO 'UTC';
Далее дадим права доступа к базе данных для этого пользователя:
- GRANT ALL PRIVILEGES ON DATABASE myproject TO myprojectuser;
Ну и выйдем из консоли PostgreSQL.
- \q
Если возникнут проблемы с кодировками на сервере, когда сервер будет иметь кодировку LATIN1, а базу данных нужно создать в UTF8, то обратитесь к следующей статье , где эта задача решается.
Шаг 4 - Установка виртуального окружения
Установим и активируем виртуальное окружение:
- pip3 install virtualenv
- virtualenv ~/myprojectenv
- source myprojectenv/bin/activate
Шаг 5 - Установка драйвера PostgreSQL
Произведём установку следующей командой
- sudo pip install django psycopg2
Внутри виртуального окружения необходимо пользоваться командой pip , а не pip3
Шаг 6 - Создание проекта
Перейдём в папку с виртуальным окружением, мы по-прежнему должны находиться в режиме работы в виртуальном окружении. И создадим проект.
- cd ~/myprojectenv
- django-admin.py startproject myproject
Шаг 7 - Настройка подключения к базе данных
А теперь отредактируем конфигурационный файл Django, чтобы он подключался к базе данных PostgreSQL, а не создавал и в дальнейшем подключался к базе данных SQLite.
- nano ~/myproject/myproject/settings.py
Для этого найдите в файле следующий кусок кода:
- ...
- DATABASES = {
- 'default': {
- 'ENGINE': 'django.db.backends.sqlite3',
- 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
- }
- }
- ...
И замените его следующим, с учётом ваших данных для подключения к базе данных:
- ...
- DATABASES = {
- 'default': {
- 'ENGINE': 'django.db.backends.postgresql_psycopg2',
- 'NAME': 'myproject',
- 'USER': 'myprojectuser',
- 'PASSWORD': 'password',
- 'HOST': 'localhost',
- 'PORT': '',
- }
- }
- ...
Шаг 8 - Выполнение миграций базы данных
Django обладает одним очень большим преимуществом - он имеет встроенную админку, что очень облегчает жизнь. Но чтобы она заработала, необходимо выполнить миграцию базы данных, то есть подготовить из моделей данных SQL запросы, которые сформируют структуру базу данных.
- cd ~/myproject
- python manage.py makemigrations
- python manage.py migrate
А ещё создадим суперпользователя, который будет администратором с максимальными правами доступа к вашему сайту. Выполните следующую команду и следуйте инструкциям.
- python manage.py createsuperuser
Шаг 9 - Установка Gunicorn
Установим Gunicorn, который будет выступать в качестве HTTP сервера для нашего сайта. Устанавливаем его внутри виртуального окружения.
- sudo pip install django gunicorn
Можете проверить, что сайт уже работает:
- gunicorn myproject.wsgi:application --bind 111.222.333.44:8000 # Укажите ваш IP-адрес
Шаг 10 - Настройка статических файлов
Django по умолчанию отдаёт статические файлы только в Debug режиме, который не используется на боевом сервере. Для боевого сервера все статические файлы из всех проектов собираются в отдельную специальную папку с помощью команды collectstatic , а саму папку необходимо указывать в файл settings.py.
Отредактируем его:
- nano ~/myproject/settings.py
И добавим строку, которая будет указывать, куда собирать статические файлы.
- STATIC_ROOT = '/home/user/myprojectenv/myproject/myproject/static/'
А теперь соберём всю статику в данный каталог:
- python manage.py collectstatic
Шаг 11 - Настройка Nginx
Отредактируем конфигурационный файл Nginx.
- sudo nano /etc/nginx/sites-available/default
Удалим всё его содержимое и замени следующим.
- server {
- listen 80;
- server_name 111.222.333.44; # здесь прописать или IP-адрес или доменное имя сервера
- access_log /var/log/nginx/example.log;
- location /static/ {
- root /home/user/myprojectenv/myproject/myproject/;
- expires 30d;
- }
- location / {
- proxy_pass http://127.0.0.1:8000;
- proxy_set_header Host $server_name;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- }
- }
Перезапустим Nginx.
- sudo service nginx restart
И запустим gunicorn
- gunicorn myproject.wsgi:application
После этого вы обнаружите, что сайт доступен уже на порту 80.
Шаг 12 - Настройка supervisor
Для того, чтобы сайт был доступен в любое время суток, необходимо настроить supervisor, который висит в памяти как служба и будет следить, чтобы сайта всегда работал.
- sudo apt-get install supervisor
Для стабильной работы Gunicorn необходимо создать его конфигурационный файл. Он будет располагаться рядом с файлом, который будет запускаемым для нашего web-приложения.
- cd /home/user/myprojectenv/myproject/myproject
- touch gunicorn.conf.py
- nano gunicorn.conf.py
Добавим следующую конфигурационную информацию:
- bind = '127.0.0.1:8000'
- workers = 3
- user = "nobody"
То есть мы указали, к какому порту привязываемся, и какой пользователь запускает процесс. А также количество рабочих процессов. В данном случае их три. Рассчитывается по следующей формуле:
workers = Ncpu + 1
После чего создадим конфигурацию самого supervisor
- cd /etc/supervisor/conf.d/
- touch myproject.conf
- nano myproject.conf
Пропишем в него следующие настройки
- [program:myproject]
- command=/home/user/myprojectenv/bin/gunicorn myproject.wsgi:application -c /home/user/myprojectenv/myproject/myproject/gunicorn.conf.py
- directory=/home/user/myprojectenv/myproject
- user=nobody
- autorestart=true
- redirect_stderr=true
А теперь запустим supervisor. Есть один нюанс при установке supervisor. Он не стартанул в качестве службы после того, как был установлен. Поэтому нужно принудительно добавить его в автозагрузку и запустить вручную, если не хотите перезагружать сервер.
- sudo update-rc.d supervisor enable
- sudo service supervisor start
Ну а дальше можно обновлять конфиги, проверять статус приложения сайта и его перезапуска.
- supervisorctl reread
- supervisorctl update
- supervisorctl status myproject
- supervisor restart myproject
При перезагрузке сервера всё будет стартовать автоматически
Примечание
Если вы изменили файлы проекта, то необходимо перезапускать gunicorn. Для этого достаточно активировать виртуальное окружение и воспользоваться командой killall
- source ~/myprojectenv/bin/activate
- sudo killall gunicorn
Supervisor автоматически запустит Gunicorn после этой команды, так что можете не беспокоиться, что сервер ляжет надолго. Не более секундного сбоя.
Для
Django
рекомендую
VDS-сервера хостера Timeweb
.
С чем может быть связана ошибка? ставил всё на свою машину, статический ip не покупал.
(myprojectenv) ubuntu@ubuntu:~/myprojectenv/myproject$ gunicorn myproject.wsgi:application --bind мойайпишник:8000
[2017-10-28 11:54:39 +0000] [31426] [INFO] Starting gunicorn 19.7.1
[2017-10-28 11:54:39 +0000] [31426] [ERROR] Invalid address: ('мойайпишник', 8000)
[2017-10-28 11:54:39 +0000] [31426] [ERROR] Retrying in 1 second.
[2017-10-28 11:54:40 +0000] [31426] [ERROR] Invalid address: ('мойайпишник', 8000)
[2017-10-28 11:54:40 +0000] [31426] [ERROR] Retrying in 1 second.
[2017-10-28 11:54:41 +0000] [31426] [ERROR] Invalid address: ('мойайпишник', 8000)
[2017-10-28 11:54:41 +0000] [31426] [ERROR] Retrying in 1 second.
[2017-10-28 11:54:42 +0000] [31426] [ERROR] Invalid address: ('мойайпишник', 8000)
[2017-10-28 11:54:42 +0000] [31426] [ERROR] Retrying in 1 second.
[2017-10-28 11:54:43 +0000] [31426] [ERROR] Invalid address: ('мойайпишник', 8000)
[2017-10-28 11:54:43 +0000] [31426] [ERROR] Retrying in 1 second.
[2017-10-28 11:54:44 +0000] [31426] [ERROR] Can't connect to ('мойайпишник', 8000)
Этот ваш IP адрес случайно не внешний IP адрес роутера, за которым Вы сидите со своим ПК?
перепробывал все ip, которые нашёл у себя на компе. не подскажите, как найти нужный?
А Вы делали вообще bind на '127.0.0.1:8000'?
sudo pip install django gunicorn
sudo pip install django psycopg2
По моему sudo здесь лишнее. Разве sudo устанавливает внутри виртуального окружения?
Как ни странно - Да.
Некропост, однако, хотел бы добавить, что в случае с продакшеном, миграции там делать нельзя. (точнее, конечно, можно, но нельзя)
Все миграции необходимо хранить в репозитории.
Твоя правда. Согласен. Свои миграции храню в репозитории. На продакшене только выполняю обновление структуры базы данных, после тестирования на дев сервере конечно (читай локальная машина разработки).
Здравствуйте, подскажите пожалуйста, как исправить:
в Ubuntu 20.04, в каталоге проекта пытаюсь создать вертуальную среду
virtualenv env
вылезает ошибка:
ModuleNotFoundError: No module named 'virtualenv.seed.via_app_data'
Спасибо.
Это может быть и ошибка в вашей версии virtualenv и не совсем верная установка, и косяки в процессе следования туториалу.
Но подобные ошибки вылезали на GitHub в репозитории virtualenv.
Впрочем я сам с таким не сталкивался, так что готового ответа у меня нет.
Установите venv:
после этого можно сделать
virtualenv - устаревший, venv - часть стандартной библиотеки. в Windows - venv ставится вместе с питоном, в убунте, к сожалению, даже куски стандартной библиотеки приходится доставлять руками.
Ок, спасибо, буду пробовать.
Все заработало, немного ругнулся, что лучше:
python3 -m venv .venv
но в итоге все сработало.
Спасибо!
Стави все по статье. Добрался до шага 12 и после него перестал запускатся сервер через gunicorn myproject.wsgi:application. выдает ошибку
", line 1014, in _gcd_import
", line 991, in _find_and_load
", line 973, in _find_and_load_un locked
[ERROR] Exception in worker process
Traceback (most recent call last):
File "/home/user/myproject/lib/python3.8/site-packages/gunicorn/arbiter.py", line 583, in spawn_worker
worker.init_process()
File "/home/user/myproject/lib/python3.8/site-packages/gunicorn/wo rkers/base.py", line 119, in init_process
self.load_wsgi()
File "/home/user/myproject/lib/python3.8/site-packages/gunicorn/workers/base.py", line 144, in load_wsgi
self.wsgi = self.app.wsgi()
File "/home/user/myproject/lib/python3.8/site-packages/gunicorn/app/base.py", line 67, in wsgi
self.callable = self.load()
File "/home/user/myproject/lib/python3.8/site-packages/gunicorn/app/wsgiapp.py", line 49, in load
return self.load_wsgiapp()
File "/home/user/myproject/lib/python3.8/site-packages/gunicorn/app/wsgiapp.py", line 39, in load_wsgiapp
return util.import_app(self.app_uri)
File "/home/user/myproject/lib/python3.8/site-packages/gunicorn/util.py", line 358, in import_app
mod = importlib.import_module(module)
File "/usr/lib/python3.8/importlib/ init .py", line 127, in import _module
return _bootstrap._gcd_import(name[level:], package, level)
File "
File "
File "
ModuleNotFoundError: No module named 'myproject.wsgi'
На что обратить внимание?
После команд запуска supervisor'а
sudo update-rc.d supervisor enable
sudo service supervisor start
нужно ли вообще в виртуальном окружении запускать Gunicorn
я думаю, вам стоит кастовать сюда Евгения - я предпочитаю использовать systemd для запуска и менеджмента сервера
попробуйте призвать его через кнопку ответить
Евгений доброй ночи, можете что-то посоветовать?
привет
тут нужна твоя помощь=)
я в супервизоре - ноль=)
Ошибка в конфиге инжинкса про статику в root последний слеш лишний путь в таком виде получается
День добрый.
А как вы это делаете?
А разве это не миграция? И как тогда быть с вашим утверждением о миграциях:
я имел в виду, что на проде нельзя делать
правильнее было бы сказать, что на проде нельзя создавать миграции. мигрировать БД - без этого, естественно, никак
Всё, теперь понял. Спасибо!
Ещё вопрос: как правильно обновлять кодовую базу, если произошли изменения в ней?
обновлять где?
если на проде -
если вы используете systemd для управления сервером
То есть я правильно понимаю, что на боевом сервере нужно ставить помимо всего ещё и git?
в целом, тут все не просто
в зависимости от способа доставки это может быть k8s, docker, rsync, ansible, git... да хоть wget-ом качать архив с условного гитхаба
и для каждого способа свои способы доставки и развертывания
для начала, если у вас 1 сервер и минимум каких-то особенностей, git pull вполне хватит. И да, для этого нужно, чтобы был git установлен
Ясно. Спасибо за развёрнутый ответ.
Думаю, что мне для моих целей хватит и git. Локально я им пользоваться умею, а вот с удалёнными серверами не сталкивался, только с github, отсюда и вопросы.
Сижу, ковыряюсь с git pull на виртуалке, и ни черта не понимаю.
Как правильно залить проект на удалённый сервер, чтобы он по git pull принимал изменения? Отправить изменения с локальной машины у меня получилось, а вот на git pull ругается:
Всё, разобрался.
В виртуальном окружении ругается на отсутствие pip:
pip ставил вот так:
поскольку easy_install3 почему-то не поставился вместе с setuptools.
в виртуальном окружении не надо использовать sudo
используя sudo вы ставите пакеты глобально. Если у вас один проект на сервере - ок. но если нет, все плюсы от venv-ов идут на смарку.
кстати, советую посмотреть в сторону poetry - на мой взгялд, это проект уже production-ready. пакеты ставятся в несколько потоков, фиксируются не только зависимости, но и зависимости зависимостей. А venv-вы создаются автоматически и не в проекте. может быть не очень удобно, но можно переопределить поведение локально и глобально. в целом, советую
Ага, спасибо, завелось!
Да мне бы хотя бы с основами разобраться, куда уж продвинутые уровни...
На шаге 11 вылезла вот такая ошибка:
Проблема решилась добавлением в settings.py в ALLOWED_HOSTS IP-адреса 10.0.3.15.
После шага 12 сайт вместо стартовой страницы Django показывает: "502 Bad Gateway".
Что не так?
покажите конфиг nginx и ка запускаете gunicorn
Всё по мануалу выше, буква в букву.
Всё по мануалу выше, буква в букву.
нужна твоя помощь=)
Поднял сервис с помощью systemd, вот по этому мануалу: https://habr.com/ru/post/501414/
А почему нельзя? Где можно об этом почитать? Киньте, пожалуйста, в меня ссылкой.
При любых попытках взаимодействовать с супервизаром, выбивает в такую ошибку
Помогите пожалуйста, уже все волосы выдрал
Это на какую команду так отвечает?
Отвечал на все команды после
Исправил таким образом