- 1. Крок 1 – оновлення системи
- 2. Крок 4 - Встановлення віртуального оточення
- 3. Крок 5 - Установка драйвера PostgreSQL
- 4. Крок 6 - Створення проекту
- 5. Крок 7 - Налаштування підключення до бази даних
- 6. Крок 8 – Виконання міграцій бази даних
- 7. Крок 9 - Установка Gunicorn
- 8. Крок 10 - Налаштування статичних файлів
- 9. Крок 11 - Налаштування Nginx
- 10. Крок 12 - Налаштування supervisor
- 11. Примітка
Після того, як доступ до сервера з Ubuntu 16.04 був налаштований в одній з попередніх статей (https://evileg.com/ru/post/1/), настав час розгорнути на ньому все необхідне для роботи сайту, а саме:
- 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"
Тобто ми вказали, якого порту прив'язуємося, і який користувач запускає процес. А також кількість робочих процесів. У разі їх три. Розраховується за такою формулою:
робітники = 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/
А почему нельзя? Где можно об этом почитать? Киньте, пожалуйста, в меня ссылкой.
При любых попытках взаимодействовать с супервизаром, выбивает в такую ошибку
Помогите пожалуйста, уже все волосы выдрал
Это на какую команду так отвечает?
Отвечал на все команды после
Исправил таким образом