Рубрика: man

  • Запускаем Django на uwsgi + nginx

    Число проектов на сервере росло, а оперативная память не добавлялось так получилось что старый метод на большом числе проектов поедает много оперативной памяти. и вот пришло время разобраться с uwsgi — это WSGI сервер с некоторыми фенями, сам умеет пере запускаться когда обновляется код проекта (как в devserver) умеет сам убивать потомком если они начинают «тупить».

    Теперь по порядку

    aptitude install python-pip build-essential python-dev libxml2-dev
    easy_install install uwsgiCode language: Bash (bash)

    Для виртуал хоста используем примерно вот такой конфг, найденный на просторах тырнета

    server {
        listen        80;
        listen        443;
    
        # указываем свой домен
        server_name   odmin4eg.org www.odmin4eg.org;
    
        # здесь мы задаем абсолютные пути к логам.
        # как я упоминал уже выше, каталог с логами у меня хранится в каталоге
        # с проектом, поэтому пути следующие:
        access_log    /home/odmin4eg.org/logs/nginx_access.log;
        error_log     /home/odmin4eg.org/logs/nginx_error.log;
    
        # ниже указывается каталог с django-проектом. как я указывал выше,
        # я храню его в подкаталоге www, поэтому путь такой:
        root          /home/odmin4eg.org/www/;
    
        location /
        {
            # ниже надо указать путь к socket'у, при помощи которого
            # nginx и uwsgi будут сообщаться.
            # в данном случае путь это '/var/tmp/odmin4eg_uwsgi.sock'
            uwsgi_pass unix:///var/tmp/odmin4eg_uwsgi.sock;
            include uwsgi_params;
    
            # 8 -- число буфферов
            # 128k -- размер буфера
            # фактически, мы сможем передать от Django в nginx только 1 мб информации.
            # играйтесь с этим значением при поднятии своего проекта
            uwsgi_buffers 8 128k;
        }
    
        # ниже описывается директория со статическими файлами проекта (css,js,etc)
        # /static/ -- это STATIC_URL, который вы должны посмотреть в 
        # в settings.py своего django проекта.
        location /static/ {
            # а вот здесь указываем абсолютный путь к директории со
            # статическими файлами
            alias /home/odmin4eg.org/www/static/;
            expires 30d;
        }
        # Это уже у кого как статика для админки
        location /media_admin {
            alias /usr/local/lib/python2.6/dist-packages/django/contrib/admin/media;
            }
    
    }Code language: Bash (bash)

    Дальше конфигурируем uwsgi — создаём файл
    /home/odmin4eg.org/www/uwsgi.yaml

    uwsgi:
        # указываем socket, при помощи которого будет происходить
        # взаимодействие между nginx и uwsgi
        socket: /var/tmp/odmin4eg_uwsgi.sock
        # здесь указываем путь к django-проекту
        pythonpath: /home/odmin4eg.org/www
        # устанавливаем переменную окружения, которая хранит имя settings файла
        env: DJANGO_SETTINGS_MODULE=settings
        # это имя модуля, который будет запускаться на выполнение
        # в такой постановке, будет запускаться wsgi.py из директории
        # указанной выше в 'pythonpath'
        module: wsgi
        # путь к лог файлу
        daemonize: /home/odmin4eg.org/logs/uwsgi.log
        # прочие настройки, значения который можно посмотреть на сайте uWSGI
        max-requests: 5000
        buffer-size: 32768
        harakiri: 30
        reload-mercy: 8
        master: 1
        no-orphans: 1
        # если выполнить команду "touch <имя ниже указанного файла>",
        # то произойдет перезапуск uwsgi демона.
        touch-reload: /home/odmin4eg.org/uwsgiCode language: Bash (bash)

    ну и создаём файлик который будем пинать для перезагрузки демона

    touch /home/odmin4eg.org/uwsgiCode language: Bash (bash)

    ну и последнее осталось написать wsgi.py и положить его в каталог указанный в pythonpath (i.g., в /home/odmin4eg.org/www). wsgi.py выглядит до безумия просто:

    import django.core.handlers.wsgi
    application = django.core.handlers.wsgi.WSGIHandler()Code language: Python (python)

    запускаем

    service nginx restart
    uwsgi -y /home/odmin4eg.org/conf/uwsgi.yamlCode language: Bash (bash)

    У меня всё поехало после этого.
    по мативам kalnitsky.org

  • Запускаем django на nginx

    Давным давно, я писал как установить nginx

    там же в комментариях подсказали ещё способ

    nginx=stable # use nginx=development for latest development version
    add-apt-repository ppa:nginx/$nginx
    apt-get update
    apt-get install nginxCode language: Bash (bash)

    получаем последний nginx.

    Напомню, что у меня за nginx стоят разные «бэк-энды»
    для самого нагруженного сайта я использую php5-fpm
    для остальных сайтов я использую apache2
    для Django проектов я использовал Apache2 + mod_python но его прожорливость, давала повод задуматься.

    в итоге я искал способ освободить ресурсы занимаемые Индейцем.

    Такой способ нашёлся 🙂

    создаю конфигурационный файл хоста nginx.

    touch djangositeCode language: Bash (bash)

    у меня они лежат в /etc/nginx/sites-available и уже от туда симлинками идут в /etc/nginx/sites-enabled

    Конфигурационный файл такого содержания

    server {
    listen 80;
    server_name sitename.ru www.sitename.ru;
    
    charset utf-8;
    
    access_log /var/log/nginx/sitename-access.log;
    error_log /var/log/nginx/sitename-error.log;
    client_max_body_size 300m;
    
    # Это, чтоб стили и статические файлы админки подгружались, проверьте у себя,
    # в разных версиях Ubuntu могут быть разные версии Питона.
    # ну и в настройках джанго проекта разумеется у нас тоже указан ADMIN_MEDIA как media_admin
    
    location /media_admin {
        alias  /usr/lib/python2.5/site-packages/django/contrib/admin/media;
        }
    location / {
    #Это как пример как мы запускаем джангоСервер
    #python ./manage.py runfcgi method=prefork socket=/tmp/sitemane.sock pidfile=/tmp/sitename.pid
    # Общаться будем по сокету, хотя можно и по 127.0.0.1:8000
    fastcgi_pass   unix:/tmp/sitename.sock;
    #Ага и вот этот файлик не забудем создать, о нём ниже
    include fastcgi_params_django;
    }
    
    #error_page 404 /404.html;
    
    # redirect server error pages to the static page /50x.html
    #
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
    root html;
    }Code language: Bash (bash)

    так же создаём файл

    touch /etc/nginx/fastcgi_params_djangoCode language: Bash (bash)

    и в него вкладываем вот такие параметры

    fastcgi_param PATH_INFO $fastcgi_script_name;
    fastcgi_param REQUEST_METHOD $request_method;
    fastcgi_param QUERY_STRING $query_string;
    fastcgi_param CONTENT_TYPE $content_type;
    fastcgi_param CONTENT_LENGTH $content_length;
    fastcgi_pass_header Authorization;
    fastcgi_intercept_errors off;
    
    fastcgi_param GATEWAY_INTERFACE CGI/1.1;
    fastcgi_param SERVER_SOFTWARE nginx;
    
    fastcgi_param REMOTE_ADDR $remote_addr;
    fastcgi_param REMOTE_PORT $remote_port;
    fastcgi_param SERVER_ADDR $server_addr;
    fastcgi_param SERVER_PORT $server_port;
    fastcgi_param SERVER_NAME $server_name;
    fastcgi_param SERVER_PROTOCOL $server_protocol;
    
    # PHP only, required if PHP was built with --enable-force-cgi-redirect
    fastcgi_param REDIRECT_STATUS 200;Code language: Bash (bash)

    проверяем верность конфигурации

    nginx -tCode language: Bash (bash)

    если всё ОК идём дальше.

    проекты джанго у меня лежат в /home/django

    Заходим в нужный нам проект и создадим там скрипт сервера.

    touch server.shCode language: Bash (bash)

    Вот с таким содержанием

    #!/bin/bash
    
    
    case "$1" in
    "start")
    #есть 2 варианта запуска сервера, по сети и через unix сокеты
    # последний выигрывает по производительности
    #python ./manage.py runfcgi method=prefork host=127.0.0.1 port=8000 pidfile=/tmp/sitename.pid
    python ./manage.py runfcgi method=prefork socket=/tmp/sitename.sock pidfile=/tmp/sitename.pid
    # не забываем, про то, что сокет у нас мог прочитать фронт-энд
    # а nginx  у меня работает с правами www-data
    chown www-data:www-data /tmp/sitename.sock
    ;;
    "stop")
    kill -9 `cat /tmp/sitemane.pid`
    ;;
    "restart")
    $0 stop
    sleep 1
    $0 start
    ;;
    *) echo "Usage: ./server.sh {start|stop|restart}";;
    esacCode language: Bash (bash)

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

    чтоб запустить сервер

    ./server.sh startCode language: Bash (bash)

    А вот он и не запустился ругается на Flup

    No module named flupCode language: Bash (bash)

    нам понадобится пакет flup это питоновский пакет, поэтому его я устанавливаю вот так

    easy_install flupCode language: Bash (bash)

    Можно попробовать поставить его из репозитория убунты

    apt-get install python-flupCode language: Bash (bash)

    Но я так не пробовал 😉

    Всё сервер запустился, можно перезапустить nginx для применения новой конфигурации

    /etc/init.d/nginx restartCode language: Bash (bash)

    Всё готово, наш сервер запустился.

    Теперь по хорошему добавить скрипт запуска сервера в автозагрузку.

  • squid на два внешних интерфейса

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

    И так, что надо сделать для Squid чтоб  он использовал оба внешних канала.

    Мне нужно было зарулить только определённый набор ИП адресов внутренней сети.

    Объявим 2 списка, укажем в каждом диапазон ип адресов, которые куда будем отправлять.

    acl provider1 src 10.0.0.0/24
    acl provider2 src 16.0.0.0/24Code language: Bash (bash)

    Чуть ниже скажем что нам можно что не можно

    http_access allow provider1
    http_access allow provider2Code language: Bash (bash)

    И дальше

    tcp_outgoing_address 10.1.0.1 provider1
    tcp_outgoing_address 10.1.0.2 provider2Code language: Bash (bash)

    10.1.0.1 10.1.0.2 — это внешние адреса сервера с разными интерфейсами.

    Собственно всё, после этого всё будет как нам хочется.

  • Связанные списки select в django (ajax select linked)


    Потратив часа 3 на поиск рабочего решения связанных полей (Это когда в зависимости от категории нужно показывать под категорию) спешу поделиться чтоб не забыть

    в urls.py

    (r'^ajax/categ/$', 'proj.list.views.feeds_subcat'),Code language: Python (python)

    во Вьюхе

    def feeds_subcat(request):
        from django.core import serializers
        json_subcat = serializers.serialize("json", SubCategory.objects.filter(category_name=request.GET['id']))
        return HttpResponse(json_subcat, mimetype="application/javascript")Code language: Python (python)

    Примерно рассказываю что там происходит
    В модели SubCategory выбираем имя субкатегории, которая соответствует ид_категории, что к нам привалило.
    всё это оборачиваем в JSON попутно подгружаем библиотеки для этих дел.
    и отправляем прямо в формате js всё обратно.

    теперь создаём ещё один js файл называем его как душе угодно (и не забываем подключить)

    <script src="/static/js/categ.js" type="text/javascript"></script>Code language: HTML, XML (xml)
      $(function(){
        $("select#id_categ").change(function(){
          $.getJSON("/ajax/categ/",{id:+$(this).val()}, function(j) {
            var options = '<option value="">---------- </option>';
            for (var i = 0; i < j.length; i++) {
              options += '<option value="' + parseInt(j[i].pk) + '">' + j[i].fields['name'] + '</option>';
            }
            $("#id_sub").html(options);
            $("#id_sub option:first").attr('selected', 'selected');
            $("#id_sub").attr('disabled', false);
          })
          $("#id_categ").attr('selected', 'selected');
        })
      })Code language: JavaScript (javascript)

    Что он делает?
    находит элемент select с id = «id_categ»
    При изменении которого вызывает функцию $.getJSON, которая долбится по урле /ajax/categ/ гет запросом и параметром ?id=то_что_выбрано
    Если всё отлично выполняется функция j
    Которая и меняет значение во втором селекте.
    #id_categ — ИД_селекта категории
    #id_sub — ИД_селекта подкатегории

  • django devserver статические файлы ( django devserver static files)

    Во время разработки нужно чтоб статика обрабатывалась dev сервером, всякие файлы стилей js и т.п.

    Для решения этой задачи я использую вот это:

    urls.py

    (r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': '/home/django/list/static'}),Code language: Python (python)

    в корне проекта создаю каталог static, в котором создаю подкаталоги js images style и т.п