Деплой проекта Django в продакшн с Nginx + Gunicorn + Supervisor

👁 90 просмотров
1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Загрузка...

В данном посте рассмотрим один из современных вариантов деплоя готового проекта Django в готовый режим работы. В посте будет рассмотрены моменты настройки и интеграции с Django таких инструментов, как:

  • Nginx — WEB-сервер;
  • Gunicorn — HTTP-сервер Python WSGI;
  • Supervisor — менеджер процессов.

Исходные данные

Для использования данного поста требуются следующие исходные данные по ПО:

  • готовый удаленный сервер Linux в виде VPS/VDS с выделенным IP;
  • установленный и настроенный Python 3 c виртуальными средами и разрабатываемым проектом на Django;

Исходные данные по неймингу:

  • /home/myprojectenv/ — абсолютный путь к папке виртуальной среды;
  • /home/myprojectenv/myproject/ — абсолютный путь к папке проекта на Django;
  • (myprojectenv)user@host: /myprojectenv/ —  вид строки запроса в консоли под активной виртуальной средой Python;
  • 11.22.33.44IP нашего удаленного сервера VDS/VPS;
  • 8000 — порт, на котором будет подвешен наш проект.

 

Установка и настройка Nginx и Gunicorn

Для начала нужно сделать апгрейд

sudo apt-get update
sudo apt-get upgrade

Ставим Nginx

sudo apt-get install nginx

Теперь заходим под виртуальную среду нашего(или вашего) проекта

cd /home/myprojectenv/
source bin/activate

Под активной виртуальной средой ставим Gunicorn

(myprojectenv)user@host: /home/myprojectenv# pip[pip3] install gunicorn

Замечание. Помните про версии pip. Если Python 2.x, то пишем pip, если Python 3.xpip3. Это по дефолту, если у вас не настроено иначе.

Теперь, перед тем, как идти дальше, протестируем удачную установку Gunicorn и интеграцию с проектом Django и для этого выполняем команду

(myprojectenv)user@host: /home/myprojectenv/myproject# gunicorn myproject.wsgi:application --bind 11.22.33.44:8000

Идем в браузер и запускаем по адресу страницу 11.22.33.44:8000 и убеждаемся, что все ок.

Далее настраиваем папку статических файлов и для этого открываем файл настроек проекта в папке /home/myprojectenv/myproject/myproject/settings.py

nano settings.py

Добавляем в этот файл параметр STATIC_ROOT, если его нет, со следующим значением

...
STATIC_ROOT = '/home/myprojectenv/myproject/static/'
...

Сохраняем, выходим и далее выполняем из папки проекта команду

(myprojectenv)user@host: /home/myprojectenv/myproject# python manage.py collectstatic

После чего в папке проекта появится новая папка с именем static.

Теперь идем и настраиваем Nginx по пути в файле

cd /etc/nginx/sites-available/

открываем файлик default

nano default

и перепишем некоторые моменты, как ниже

server {
    listen 80;
    server_name 11.22.33.44; #либо ip, либо доменное имя
    access_log  /var/log/nginx/example.log;

    location /static/ {
        root /home/myprojectenv/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

 

Активируем нашу среду и заходим в папку проекта для проверки запуска в связке Gunicon + Nginx

(myprojectenv)user@host: /home/myprojectenv/myproject# gunicorn myproject.wsgi:application

В браузере набираем 11.22.33.44:8000 и убеждаемся, что все ок.

Установка и настройка Supervisor

Чтобы ваше приложение стартовало после любого непредвиденного рестарта системы или сбоя, нам нужно использовать в деле supervisor.

Установим supervisor

apt-get install supervisor

Создадим конфигурационный файл для gunicorn в подпапке проекта (myproject/myproject/) рядом с settings.py

cd /home/myprojectenv/myproject/myproject
touch gunicorn.conf.py
nano gunicorn.conf.py

и записываем туда такие данные, которые означают, что данный проект будет запущен на IP и порте 0.0.0.0:8000, что будет означать внешний адрес нашего VPS. Если у вас сервер локальный, то ставим 127.0.0.1

bind = '0:8000'
workers = 3
user = "nobody"

Теперь создаем конфигурационный файл для supervisor

cd /etc/supervisor/conf.d/
touch myproject.conf
nano myproject.conf

и записываем туда такие данные

[program:myproject]
command=/home/myprojectenv/bin/gunicorn myproject.wsgi:application -c /home/myprojectenv/myproject/myproject/gunicorn.conf.py
directory=/home/myprojectenv/myproject
user=nobody
autorestart=true
redirect_stderr=true

 

Запускаем проект через supervisor

supervisorctl restart myproject

В браузере набираем 11.22.33.44:8000 и убеждаемся, что все ок.

Дополнительный тест. Можно также перезагрузить сервер

shutdown -r now

и убедиться, что наш проекта на Django сам автоматом встал и заработал при помощи supervisor.

При использовании Supervisor необходимо использовать его подпроцесс управления supervisorctl. Остальные основные команды supervisor

  • supervisorctl start myproject;
  • supervisorctl reread;
  • supervisorctl update;
  • supervisorctl status myproject.

 

Возможные ошибки использования Supervisor и Gunicorn

Ошибки в файлах конфигурации

Это с большей вероятностью, потому что конфигурационных файлов 2 и нужно, чтобы они были настроены слажено без ошибок. Напомним, что они у нас находятся по путям:

  • Файл конфигурации Gunicorn в пределах текущего проекта /home/myprojectenv/myproject/myproject/gunicorn.conf.py
  • Файл конфигурации проекта в виде управляемого процесса внутри Supervisor /etc/supervisor/conf.d/myproject.conf

 

Ошибка запуска из-за занятости стандартного порта Supervisor

Обычно, эта ошибка выглядит так, при запуске команды запуска supervisorctl start myproject

cloudApp: ERROR (spawn error)

или так, при запуске команды поиска ошибок supervisord -n

Error: Another program is already listening on a port that one of our HTTP servers is configured to use.  Shut this program down first before starting supervisord

Для решения этой проблемы сначала убиваем процесс Supervisor, который можно сделать несколькими способами.

Первый. Выводим весь список процессов Supervisor и убиваем нужный по PID(в списке он будет после первого)

ps -ef | grep supervisord
sudo kill -9 PID_OUR_PROJECT

или

ps -ef | grep supervisord
kill -s SIGTERM PID_OUR_PROJECT

 

Второй. Убиваем сам supervisord

sudo pkill supervisord

 

Третий. Удаляем файл supervisor.sock и запускаем supervisor обратно

sudo unlink /run/supervisor.sock
sudo /etc/init.d/supervisor start

Теперь перезапускаем проект

supervisorctl start cloudApp
Ошибка ERROR (no such process) при запуске нового процесса

Данная ошибка появляется, когда мы создали новый проект, но он не обновился в системе Supervisot и для решения этой проблемы нам нужно перезаписать все процессы и перезагрузить supervisorctl

supervisorctl reread
supervisorctl reload

 

Если не удается идентифицировать ошибку

Если проблему трудно найти или идентифицировать, то будет полезной использовать команду

supervisord -n

который выведет весь список ошибок в файлах или сервисах, которые мешают запускаться процессу Supervisor.

 

Использованные материалы:

  1. Django + Python3 + Nginx + Gunicorn + DO;
  2. Setting up Django with Nginx, Gunicorn, virtualenv, supervisor and PostgreSQL

 

Как построить Bootstrap из исходников

👁 54 просмотров
1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Загрузка...

Настройка инструментов

Bootstrap использует скрипты NPM для их построения. Наш package.json включает подходящие методы для работы с фреймворком, включающие компиляцию кода, запуск тестов и многое другое.

Используя систему построения Bootstrap можно запустить документацию локально, вам всего лишь нужно скачать исходники последней версии Bootstrap и Node.js. В следующих шагах предполагается, что вы готовы к подводным камням:

  1. Загружаем и устанавливаем Node.js, который будет необходим для управления зависимостями Bootstrap;
  2. Переходим в корень папки скачанных исходников /bootstrap  и выполняем команду npm install для установки наших локальных зависимостей, находящихся в списке файла package.json;
  3. Устанавливаем Ruby, устанавливаем Bundler при помощи команды gem install bundler, и в конце запускаем команду установки bundle install. Это должно установить все зависимости Ruby, такие как Jekyll и плагины.

Замечания для пользователей Windows. Необходимо читать это руководство для получения Jekyll и установить без проблем.

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

Bootstrap использует скрипты NPM для построения. Наш package.json включает методы для работы с фреймворком, включая компиляции кода, запуска тестов и другое.

 

Использование скриптом NPM

Наш package.json включает следующие команды и задачи:

Задача Описание
npm run dist npm run dist создает папку /dist с скомпилированными файлами. Используются SassAutoprefixer и UglifyJS.
npm test Похоже на npm run dist и плюс это запустит документацию локально.
npm run docs Построение и склейка CSS/JavaScript для документации. Вы сможете затем запустить документацию локально npm run docs-serve.

Обновление WordPress без данных FTP

👁 46 просмотров
1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Загрузка...

В зависимости от настройки серверов обновление движка/тем/плагинов может требовать от пользователя адрес сервера, логин и пароль для FTP. Обычно это происходит, когда веб-сервер запущен от имени другого пользователя. Попробуйте добавить в wp-config.php строку:

define('FS_METHOD', 'direct');

…и обновление будет происходить напрямую.

Установка темы Zurb Foundation на свой WordPress — сайт

👁 124 просмотров
1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Загрузка...

Что, если вы решили изменить библиотеке Bootstrap и решили попробовать на вкус альтернативный вариант в виде Zurb Foundation? Эта статья покажет, как его установить и скомпилить.

Начальные условия

У нас есть установленный голый движок WordPress, который работает у нас либо на локальном или удаленном сервере.

Перед работой с темой

Для компиляции исходников темы нам будет необходим Node.js с инструментами разработки. Устанавливаем его по инструкции, в зависимости у кого какая система. К примеру, если у нас уделанный сервер на Ubuntu, то нам подходит инструкци я в этом разделе:

curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
sudo apt-get install -y nodejs
sudo apt-get install -y build-essential
  1. Первым делом скачиваем исходники темы-скелетона по адресу или на GitHub.
  2. Устанавливаем эту тему в нашу систему WordPress, но если сейчас открыть сайт, то ничего не заработает, потому что тема еще не скомпилирована.
  3. Входим в корневую папку темы через командную строку системы и выполняем процесс компиляции и настройки:

Устанавливаем все зависимости

npm install

Конфигурируем и для этого необходимо файл config-default.yml скопировать под именем config.yml и произвести ряд настроек (актуально, если у вас локальный сервер).

Запускаем процесс построения

npm run build

Создание конечного архива с темой

После того, как мы поработали с исходниками и конфигурацией, то на конец можно уже выпустить конечный релиз собранной и конечной темы и для этого достаточно набрать команду:

npm run package

Данная команда соберет все скомпилированные исходники без лишних вспомогательных файлов в один zip — архив темы в папке packaged.

Примечания

Если выходи ошибка npm ERR! Failed at the node-sass@4.7.2 postinstall script. , надо установить зависимости для sass

sudo npm i gulp-sass -ES --unsafe-perm=true

 

Раскрытие выпадающего меню при наведении в Bootstrap 3/4

👁 235 просмотров
1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Загрузка...

По-умолчанию выпадающиее меню в Bootstrap раскрывается при клике и сворачивается тоже только при клике мышкой.

Было бы не плохо, чтоб раскрытие и сворачивание меню происходило при наведении мышки. И это сделать совершенно не сложно! Для этого нужно лишь добавить CSS правило:

.dropdown:hover > .dropdown-menu { 
    display: block; 
}

И выпадающее меню реагирует на наведение.

Отключение обновлений в WordPress

👁 90 просмотров
1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Загрузка...

Иногда бывает полезно отключить обновления определенных модулей в WordPress. Это могут быть темы, плагины, виджеты и т.п. и часто такая необходимость возникает, когда вы сдаете проект клиенту на WordPress и где вы не всегда на месте, чтобы разъяснять или справлять все ньюансы, которые могут возникнуть в связи новыми обновлениями модулей.

Запретить обновление темы

Рассмотрим отключение обновлений тем. Тут привести 3 способа, как это сделать.

Способ 1.

Суть первого способа заключается в изменении файла стилей. Да да, именно файла стилей — style.css. В начале этого файла, пишутся некоторые параметры, например — название темы, автор и нужная нам версия.

Выглядит такая строка примерно так — Version: 1.0, смотрите внимательно. она где-то в начале. Так вот, чтобы отключить обновления, Вам просто нужно изменить версию на другую, которая будет побольше, например так — Version: 999.0.

Теперь получается, что любая версия будет меньше указанной, а значит не актуальной и тема не будет обновляться.

 

Способ 2. 

Второй способ потребует от Вас тоже небольшого вмешательства в код темы, а именно в файл пользовательских функций — functions.php. Открываем его для редактирования, а потом в самый конец перед закрывающим тегом PHP — ?>, если такого нет, то просто в конец, добавляем такие вот функции.

// отключаем обновление тем
remove_action( 'load-update-core.php', 'wp_update_themes' );
add_filter( 'pre_site_transient_update_themes', '__return_null' );
 
// отключаем авто обновления
add_filter( 'auto_update_theme', '__return_false' ); 
 
// спрячем имеющиеся уведомления
add_action('admin_menu','hide_admin_notices');
function hide_admin_notices() {
    remove_action( 'admin_notices', 'update_nag', 3 );
}

По комментариям видно что мы отключаем сразу несколько параметров — обновление тем, авто обновления и уведомления о надобности обновится.

Способ 3.

Последний способ, наверное самый простой, но требует установки плагина. Скачивает с сайта WordPress плагин — Easy Updates Manager или WordPress Theme Updates, ну и подобные им, которые сделают все за Вас.

Как по мне, то лучше выбрать один из ручных методов, ведь использование плагинов лишний раз нагружает Ваш WordPress, хоть и не сильно, но все же.

Запретить обновление плагина

В некоторых случаях может оказаться, что обновлять плагин вам не нужно. Это может произойти, если вы самостоятельно внесли доработки и изменения в код плагина. Тогда обновление перезапишет все ваши правки. Либо же если авторы плагина в чем-то изменили концепцию, и новая версия вас больше не устраивает. В моем случае так случилось с замечательным плагином NextGen Gallery, который после обновления до версии 2 стал неповоротливым и тяжело модифицируемым.

Способ 1.

Версия плагина прописывается в начале его главного файла. Открываем список плагинов, выбираем нужный и нажимаем «Изменить».

<?php
/*
Plugin Name: NextGEN Gallery
Plugin URI: http://www.nextgen-gallery.com/
Description: A NextGENeration Photo Gallery for WordPress
Author: Photocrati
Author URI: http://www.photocrati.com/
Version: 1.9.13

Если заменить значение «Version:» на большое число, например 99.99, то проверка обновлений будет сообщать, что установленная  версия новее, и не будет предлагать обновиться.

Способ 2.

Пропишем фильтр, позволяющий блокировать обновления конкретных плагинов централизованно. Для этого нужно в файл wp-config.php добавить массив:

<?php
$DISABLE_UPDATE = array( 'nextgen-gallery', 'nospamnx', 'другие-плагины');

Где значением элемента массива является название директории, в которой расположен плагин,  или его название, если плагин не имеет своей категории (состоит из одного файла).

Затем в файл functions.php текущей темы следует добавить код, который будет обрабатывать данный массив и запрещать для указанных плагинов обновления:

<?php
// запрет обновления выборочных плагинов
function filter_plugin_updates( $update ) {    
    global $DISABLE_UPDATE; // см. wp-config.php
    if( !is_array($DISABLE_UPDATE) || count($DISABLE_UPDATE) == 0 ){  return $update;  }
    foreach( $update->response as $name => $val ){
        foreach( $DISABLE_UPDATE as $plugin ){
            if( stripos($name,$plugin) !== false ){
                unset( $update->response[ $name ] );
            }
        }
    }
    return $update;
}
add_filter( 'site_transient_update_plugins', 'filter_plugin_updates' );

Однако имейте ввиду, с обновлением самого WordPress старые версии плагинов или тем могут оказаться несовместимыми и перестать работать, поэтому отключать обновления следует с осторожностью.

Источники:

  1. Как отключить обновления темы WordPress
  2. Запрещаем обновление конкретного плагина в WordPress

Как сделать из папки в корне сайта корневой раздел при помощи .htaccess?

👁 65 просмотров
1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Загрузка...

Допустим, есть у нас ситуация при котором index.php находится не в самом корне, а в субкаталоге корня сайта и нам необходимо сделать эту папку корнем сайта. для этого необходимо внести некоторые изменения в файл .htaccess

RewriteEngine On

# Map http://www.example.com to /folder.
RewriteRule ^$ /folder/ [L]

# Map http://www.example.com/x to /folder/x unless there is a x in the web root.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/folder/
RewriteRule ^(.*)$ /folder/$1

# Add trailing slash to directories within folder
# This does not expose the internal URL.
RewriteCond %{SCRIPT_FILENAME} -d
RewriteRule ^folder/(.*[^/])$ http://www.example.com/$1/ [R=301]