Debian, Dojo, Django, Python

Делюсь опытом в описанных технологиях. Блог в первую очередь выполняет роль памяток для меня самого.

Grunt

Введение

Надоело мне как-то перепроверять все CSS-файлы при изменении дизайна. Поискав немного, я остановился на LESS. Вместо того, чтобы управлять одним огромным файлом styles.css, LESS позволяет создать множество мелких файлов, каждый из которых отвечает за свою часть общей таблицы стилей. Однако, собирать всё вручную мне было лень, поэтому я решил для своего проекта использовать Grunt. Для него есть множество модулей, которые способны сильно облегчить жизнь Web-разработчика, в частности, компилировать множество LESS файлов автоматически, собирать и сжимать JavaScript'ы и т.д.

В данной статье пойдёт рассказ о том, зачем нужен Grunt, показаны примеры его использования и базовой настройки, а также мимоходом захвачено использование LESS для разработки каскадных таблиц стилей.

Для проекта, над которым я работаю, было принято решение создать в корневом каталоге папку /less, куда поместить следующие файлы:

  • bootstrap.less - объединяет в себе все остальные файлы. Изменяя содержимое этого файла легко управлять результирующей таблицей стилей.
  • colors.less - содержит переменные, описывающие цвета, используемые на страницах, например, @red: #FF0000;.
  • fonts.less - описывает используемые на страницах шрифты. В своём проекте я решил использовать символьный шрифт FontAwesome вместо того, чтобы рисовать иконки.

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

Установка

Целевой системой сегодня будет не Debian, а Windows 8. Установка всех средств в Debian, кроме NodeJS, производится аналогично - командами в консоли. Если хотите NodeJS в Debian Wheezy - прочитайте вот эту статью.

Скачиваем установщик с сайта проекта NodeJS и запускаем, при установке не забываем указать, что нам также понадобится менеджер пакетов (Node Package Manager - NPM).

Настройка проекта для использования Grunt

Существует два способа установки Grunt'а - глобально и локально, в проект. Я рекомендую сам Grunt установить глобально, а необходимые модули - в папку проекта. Её всегда можно добавить в исключения вашей СКВ.

Запускаем командную строку от имени администратора и вводим следующие команды:

npm install grunt -g
npm install grunt-cli -g

Первый пакет - это собственно Grunt, второй - утилиты командной строки, позволяющие работать с ним. Ключ -g означает, что установленные пакеты должны быть доступны глобально.

Перейдём в каталог нашего проекта (вместо %project_root_folder% подставьте нужное) и инициализируем его для использования Grunt'а:

cd %project_root_folder%
grunt init

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

{
    "name": "tester",
    "version": "0.0.0",
    "description": "Система тестирования",
    "main": "index.html",
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
    },
    "author": "Dunaevsky Maxim",
    "license": "MIT",
    "devDependencies": {
    "grunt": "^0.4.5",
    "grunt-contrib-concat": "^0.5.0",
    "grunt-contrib-less": "^0.11.4",
    "grunt-contrib-uglify": "^0.5.1"
  }
}

Теперь нам нужно будет установить необходимые модули, я ограничусь всего тремя:

  • concat - собирает несколько указанных файлов в один.
  • less - компилирует LESS-файлы в каскадные таблицы стилей CSS.
  • uglify - оптимизирует и сжимает JavaScript-код.

Установка производится очень просто:

npm install grunt-contrib-concat --save-dev
npm install grunt-contrib-less --save-dev
npm install grunt-contrib-uglify --save-dev

Ключ --save-dev означает, что пакеты должны быть также прописаны в файле package.json.

Пакеты установлены, самое время дать Grunt'у задание - скомпилировать LESS-файлы, склеить вместе все JavaScript'ы из каталога /src/ и сжать итоговый файл. Для этого нам понадобится файл Gruntfile.js. Обратите внимание, первая буква в названии файла должна быть большой. Создать его следует в корневом каталоге проекта.

Рассмотрим Gruntfile.js, которым пользуюсь я сам:

"use strict";
module.exports = function(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        less: {
            dev: {
                files: {
                    'css/styles.css': 'less/bootstrap.less'
                }
            },
            min: {
                options: {
                    ieCompat: true,
                    compress: 2,
                    optimization: true
                },
                files: {
                    'css/styles.min.css': 'less/bootstrap.less'
                }
            }
        },
        concat: {
            js: {
                src: [
                    'src/*.js'
                ],
                dest: 'js/ui.js'
            }
        },
        uglify: {
            build: {
                src: 'js/ui.js',
                dest: 'js/ui.min.js'
            }
        }
    });

    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-uglify');

    grunt.registerTask('default', ['less:dev', 'concat:js', 'uglify']);
};

Первым делом определяются настройки для задач, а также указывается, откуда брать информацию о проекте (файл package.json).

Задание для сборки CSS из LESS-файлов содержит две секции - настройки для разработки (dev) и для релиза (min), когда важен маленький размер файла и оптимизация кода. В обоих заданиях указано, что нужно на основе файла bootstrap.less из каталога less собрать файл styles.css в каталоге css.

Задание для concat'а небольшое - ему нужно всего навсего взять все js-файлы в каталоге src и склеить в один - ui.js, положив его в каталог js.

Самое последнее задание - оптимизация и сжатие получившегося при склеивании файла с помощью утилиты uglify.

В конце файла производится загрузка необходимых модулей и выполнение их в порядке перечисления аргументов функции grunt.registerTask. Изменяя порядок следования аргументов можно управлять процессом сборки.

Закончив редактирование файла Gruntfile.js, запустите командую строку в текущем каталоге и выполните команду grunt. В случае ошибки в конфигурации или одном из файлов проекта будет выдано соответствующее сообщение. В противном случае вывод на экран будет выглядеть примерно так:

Running "less:dev" (less) task
File css/styles.css created: 0 B → 251 B

Running "concat:js" (concat) task
File js/ui.js created.

Running "uglify:build" (uglify) task

Done, without errors.

Минимальная настройка SSH в Debian 7 Wheezy

Статья обновлена 18.12.2017, исправлены опечатки и ошибка с перемещением публичного ключа вместо приватного.

Цели

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

Все действия выполняются от имени пользователя root, если не указано иное.

Установка пакетов

Установить сервер OpenSSH в Debian очень просто:

Установка
apt-get install openssh-server -y

Вместе с самим сервером ставится несколько зависимостей. В моём случае (Debian 7.5) это openssh-client и ncurses-term.

Служба сервера sshd будет автоматически запущена после установки. Обращаться к ней в терминале следует по имени ssh, например (запуск, остановка, перезапуск):

Установка
service ssh start
service ssh stop
service ssh restart

Увеличение длины серверного ключа

По умолчанию длина ключа OpenSSH в Debian 7 - 768 бит, что явно недостаточно. Следует указать значение не ниже 2048 и сгенерировать ключи заново!

До того, как приступить к изменению основных настроек OpenSSH, следует сгенерировать более длинные серверные ключи, иначе безопасность будет под угрозой. Делается это очень просто:

  1. Переходим в каталог /etc/ssh
  2. Изменяем в sshd_config значение параметра ServerKeyBits с 768 на 2048.
  3. Удаляем старые ключи командой

    rm -rf ssh_host_*
  4. Выполняем перегенерацию ключей сервера (служба будет перезапущена автоматически):

    dpkg-reconfigure openssh-server

Минимальная настройка

Все найстроки сервера OpenSSH хранятся в файле /etc/ssh/sshd_config. Откроем его для редактирования и рассмотрим минимально необходимые опции, которые не рекомендуется трогать либо наоборот настоятельно рекомендуется изменить.

  • Port 22 - лучше всего сразу сменить порт на другой, однако, номер порта желательно выбрать больше 1024, чтобы случайно не создать конфликт с какой-нибудь другой программой, работающей на этом порту.
  • ListenAddress 0.0.0.0 - по умолчанию закомментировано. Можно указать, какой интерфейс должен слушать наш сервер. Если на сервере несколько интерфейсов, один из которых торчин наружу, например, предоставляет доступ к WEB-серверу, а работа с сервером будет производиться только из внутренней сети, я советую указать здесь адрес сервера во внутренней сети, чтобы заблокировать доступ из Интернета.
  • UsePrivilegeSeparation yes - ни в коем случае не отключать разделение привилегий!
  • LoginGraceTime 120 - время в секундах, в течение которого следует авторизоваться на сервере. По истечении указанного интервала сервер автоматически разорвёт соединение.
  • PermitRootLogin yes - настоятельно рекомендую сменить на no! Пользователь root не должен подключаться к серверу! Для выполнения команд, требующих повышения привилегий, следует использовать sudo!
  • PubkeyAuthentication yes - включаем, т.к. дальше будет рассматриваться использование публичных ключей для подключения к серверу.
  • AuthorizedKeysFile %h/.ssh/authorized_keys - следует раскомментировать для доступа с помощью открытых ключей шифрования. По умолчанию эта настройка указывает на то, что открытые ключи каждого пользователя следует искать в его домашнем каталоге, в файле authorized_keys, лежащем в подкаталоге .ssh.

Изменив эти минимальные настройки, перезапустите службу ssh.

Проверка работоспособности

Попробуйте подключиться к своему серверу с него самого:

ssh user@localhost

где user - ваш настоящий логин в системе.

При самом первом подключении ваш SSH-клиент будет спрашивать, следует ли доверять указанному хосту и принять от него ключ шифрования. Отвечаем yes (нужно написать слово полностью). Сервер предложит ввести пароль для авторизации в системе. Вводим его. Если всё правильно, вы окажетесь в консоли, где сможете вводить команды.

Генерация и размещение ключей

Генерация ключей

При шифровании с открытым ключом потребуется создать пару из двух ключей - открытого и закрытого. В *nix-системах стандартным средством для их генерации является программа ssh-keygen. Запуск её с различными параметрами приводит к созданию различных ключей. В нашем случае будет использован минимум настроек.

Выполните указанную ниже команду для создания ключа длиной 2048 бит и с комментарием "New generated key". Права root не требуются. Я советую добавить комментарий для ключа - в этом случае при подключении с его помощью в логах сервера будет отображаться этот комментарий. Можете ввести сюда свои имя и фамилию.

Генерация пользовательских ключей
ssh-keygen -b 2048 -C "New generated key"

Система предложит указать имя для новых файлов. Для примера будем использовать new_key

Затем будет задан вопрос, какая парольная фраза будет использоваться для ключа. Если не заполнять это поле, то ключ не будет защищён паролем. Рекомендую ввести сюда что-нибудь. После первого ввода парольной фразы будет предложено ввести её ещё раз.

После этого в текущем каталоге (если вы ввели имя файла выше) будут созданы два файла - new_key и new_key.pub

Файл new_key - это закрытый ключ. Его нужно сохранить в надёжное место на вашем компьютере и не давать никому. Как правило, его кладут в домашнем каталоге в папку .ssh под именем id_rsa, при этом права на файл должны быть 0600:

Изменение прав доступа к ключу
mv new_key ~/.ssh/id_rsa
chmod 0600 ~/.ssh/id_rsa

Если права будут указаны неправильно, могут возникнуть проблемы. Например, утилита Seahorse из комплекта Gnome при попытке добавить этот ключ в хранилище будет запрашивать пароль, но при нажатии кнопки "Сохранить" выдаст ошибку.

Файл new_key.pub - это открытый ключ. Его также следует сохранить на вашем компьютере, однако, именно его следует распространять на серверах, к которым вы будете подключаться.

Размещение ключей на целевой системе

Если в домашнем каталоге пользователя не существует каталога .ssh, создайте его, а внутри него разместите пустой файл authorized_keys.

Размещение ключей на сервере
cd ~
mkdir .ssh
cd .ssh/
touch authorized_keys

Теперь в этот файл мы добавим наш открытый ключ с помощью стандартной команды >>

cat ~/new_key.pub >> authorized_keys

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

Использование закрытых ключей и Putty

Формат закрытых ключей, используемых программой Putty, несколько отличается от того, который используется в *nix-системах. Тем не менее, в комплекте идёт программа puttygen. Запустите её.

В меню выберите пункт Conversion, а в нём - Import key.

Найдите ваш закрытый ключ и откройте его.

Если ранее вы указали парольную фразу, сейчас её нужно будет ввести для открытия ключа.

Нажмите кнопку Save private key

Дайте подходящее имя закрытому ключу и сохраните его куда-нибудь. Как видите, формат файла изменился - теперь он ppk

Создайте в Putty новое подключение. В настройках найдите пункт Auth. На этой странице в поле Private key file for authentication выберите сохранённый ключ.

Сохраните подключение.

Нажмите Open

Теперь при подключении вам нужно будет вводить не пароль пользователя системы, а пароль от вашего ключа. Удобство заключается в том, что можно создать один публичный ключ и разместить его на десятке серверов. Теперь вместо того, чтобы помнить 10 разных паролей, достаточно помнить всего один и хранить его и секретный ключ в надёжном месте, исключающем доступ посторонних лиц.

Использование ключей для авторизации не отменяет ввода пароля пользователя при вызове команды sudo!

Настройка Redmine на Debian 7

Установка и настройка Redmine в Debian 7 (nginx + postgresql + thin)

В данной статье рассматривается установка и настройка Redmine версии 1.x в Debian 7 с помощью apt. Если вам нужна инструкция по настройке Redmine версии 2.x, то эта статья не для вас.

Краткое содержание:

  • Введение
  • Список используемых пакетов.
  • Порядок установки и настройки пакетов.
    • Предварительная настройка PostgreSQL
    • Установка пакетов
    • Создание базы данных
  • Увязка Redmine с nginx через thin.

Введение

Redmine - система для управления проектами. Если говорить простым языком, эта система служит для того, чтобы можно было вести учёт обращений, заявок, багрепортов и известных проблем о каждом продукте компании. Помимо этого в системе есть встроенная Wiki, база знаний, диаграммы Ганта, разделение по проектам и ролям и т.д. Если вы работаете в фирме, которая занимается разработкой ПО, то этот или аналогичный продукт вам жизненно необходим. С помощью Redmine можно оперативно отслеживать ход работы, исправления обнаруженных ошибок и т.д. В общем, на выходе получается целый комбайн.

Список используемых пакетов

Для работы Redmine требуется установка Ruby On Rails. К нашему удовольствию разработчики Debian'а включили все необходимые пакеты в список зависимостей, значительно упростив установку. Исключение сделано лишь для двух пакетов - сервер, который будет запускать Redmine, и пакет для соединения с БД.

Ниже приведён минимальный список пакетов, которые нам потребуются:

  • thin - сервер для запуска продуктов, написанных на Ruby
  • redmine - сама система
  • ruby-pg - драйвер для подключения программ, написанных на Ruby On Rails, к СУБД PostgreSQL.

Установка Ruby будет выполнена автоматически

Предварительная настройка базы в PostgreSQL

Запустим интерпретатор psql от имени суперпользователя postgres:

sudo su -c psql postgres

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

CREATE ROLE redmine WITH PASSWORD 'redmine' LOGIN;
CREATE DATABASE redmine WITH OWNER redmine;
\q

Естественно, вы можете дать пользователю и базе любое нужное имя. Кроме того, на одном сервере можно развернуть несколько экземпляров Redmine - для этого нужно будет создать несколько баз (и, возможно, пользователей) и настроить несколько конфигураций для thin, но я сейчас этого делать не буду.

Установка пакетов и настройка параметров Redmine

Установка пакетов

Для установки всех необходимых пакетов нужно от имени root выполнить команду:

apt-get install redmine ruby-pg thin -y

Во время установки менеджер пакетов предложит настроить базу данных. Отвечаем отрицательно. Базу данных лучше настраивать через правку конфигурационных файлов, т.к. установщик Redmine предлагает дать ему административный доступ к PostgreSQL.

Настройка доступа к БД

Перейдём в каталог /etc/redmine/default

cd /etc/redmine/default

Здесь находится всего два файла - database.yml и session.yml. Нам нужен только первый, отвечающий за настройки доступа к БД.

Содержимое database.yml:

production:
  adapter: postgresql
  database: redmine
  host: localhost
  port:
  username: redmine
  password: redmine
  encoding: utf8

Все настройки, полагаю, понятны без комментариев. Отмечу только, что первая строка, production:, указывает на то, что данная конфигурация должна использоваться при запуске сервера в рабочем режиме. Также доступны режимы development и test.

Настройка сервера thin

Теперь нужно настроить thin. В Debian 7 при установке thin ставятся сразу две его версии, 1.8 и 1.9.1, мы будем использовать последнюю. Переходим в каталог настроек и создаём файл для запуска Redmine:

cd /etc/thin1.9.1/
touch redmine.yml
chmod 644 redmine.yml

Открываем созданный файл в любимом текстовом редакторе и вносим туда следующие данные:

---
chdir: /usr/share/redmine
environment: production
timeout: 30
log: /var/log/thin/redmine.log
pid: /var/run/redmine/redmine.pid
max_conns: 1024
max_persistent_conns: 512
require: []

wait: 30
socket: /var/run/redmine/redmine.sock
daemonize: true
user: www-data
group: www-data
servers: 1
prefix: /redmine

socket указывает путь и имя сокетов, создаваемых thin при запуске Redmine.

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

Servers: 1

ls /var/run/redmine
redmine.sock.0

Servers: 2

ls /var/run/redmine
redmine.sock.0
redmine.sock.1

prefix указывает на то, по какому адресу на сервере будут обрабатываться запросы к Redmine. Поясню на примере. Допустим, адрес нашего сайта - http://sharkon.ru/ . При переходе к этому адресу человек будет получать главную страницу нашего сайта. Пусть при переходе по ссылке http://sharkon.ru/redmine/ открывается Redmine. Именно за часть адреса, идующую после указания доменного имени, отвечает этот параметр. Если сайт используется для внутренних нужд и не торчит наружу, можно дать ему, например, такое доменное имя: http://redmine.lo/ , прописав в настройках сервера DNS, к какой машине в локальной сети нужно подключаться для работы с этим сайтом. В этом случае строку с параметром prefix следует удалить из файла конфигурации полностью!

Настройка nginx.

В каталоге /etc/nginx/ следует создать файл proxy_params.conf. На моих серверах он выглядит примерно так:

proxy_redirect                          off;
proxy_set_header Host                   $http_host;
proxy_set_header X-Real-IP              $remote_addr;
proxy_set_header X-Url-Scheme           $scheme;
proxy_set_header X-Forwarded-For        $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto      $scheme;
client_max_body_size                    20m;
client_body_buffer_size                 1m;
proxy_buffering                         off;
proxy_send_timeout                      180;
proxy_read_timeout                      180;
proxy_connect_timeout                   180;
proxy_buffer_size                       4k;
proxy_buffers                           32 32k;
proxy_busy_buffers_size                 64k;
proxy_temp_file_write_size              1m;
add_header X-Frame-Options "SAMEORIGIN";

При необходимости измените настройки, исходя из параметров вашего сервера. Указанные в примере данные хорошо себя показали на не очень мощной машине с 2 GB RAM.

В каталоге /etc/nginx/conf.d/ создадим файл redmine.conf со следующим содержимым:

upstream redmine {
        server unix:/var/run/redmine/redmine.0.sock;
}

server {
    listen 80;
    server_name sharkon.ru;
    access_log off;
    error_log /var/log/redmine/nginx_error.log;
    include /etc/nginx/proxy_params.conf;
    proxy_redirect off;

    location / {
        root /var/www/sharkon.ru;
    }
    
    location /redmine {
        root /usr/share/redmine/public;
        error_page 404 404.html;
        error_page 500 502 503 504 500.html;
        try_files $uri/index.html $uri.html $uri @redmine_server;
    }

    location @redmine_server {
        proxy_pass http://redmine;
    }
}

Здесь указано, что следует использовать для соединения с Redmine сокет, расположенный по пути /var/run/redmine/. Имя сокета формируется из строки, указанной ранее в параметрах thin плюс порядковый номер созданного сокета, начиная с нуля. Далее идёт указание имени нашего сервера и пути, по которому расположен Redmine. Все запросы к нему автоматически будут переадресовываться к созданному ранее сокету.

Миграции

Т.к. мы настраивали доступ к БД вручную, создание её структуры мы будем производить вручную. Это не сложно:

cd /usr/share/redmine
rake db:migrate RAILS_ENV=production

Права на сокет

Так как сокет для redmine будет создаваться пользователем www-data, следует сделать так, чтобы после перезагрузки системы Redmine мог создать его заново. Для этого мы сменим владельца папки с сокетами и pid-файлом.

cd /var/run
mkdir redmine
chown www-data:www-data redmine/

Кодировка CSV-файлов

По-умолчанию Redmine генерирует все отчёты в кодировке UTF-8. Пакет Microsoft Office использует кодировку Win1251, поэтому CVS-отчёт, открытый с помощью Excel, будет показывать кракозябры. Следует всего лишь в одном месте изменить настройки:

cd /usr/share/redmine/config/locale
nano ru.yml

Здесь следует найти строку:

general_csv_encoding: UTF-8

и заменить её на

general_csv_encoding: CP1251

При необходимости здесь же можно изменить и другие параметры локализации Redmine, например, перевод некоторых слов и кодировку файлов pdf.

Запуск

Все подготовительные операции выполнены, можно запустить сам Redmine и перезапустить nginx.

service thin start
service nginx restart

Redmine будет доступен по адресу http://sharkon.ru/redmine/

Установка Debian на RAID-контроллер (обновлено 6 марта 2015)

Введение

В статье рассказывается об установке Debian на Fake-RAID - это RAID, эмулируемый некоторыми материнскими платами. При этом аппаратного RAID-контроллера, позволяющего прозрачно работать с массивом, на таких материнских платах нет. Проблем с установкой Debian на нормальный RAID обычно не бывает, а вот с Fake-RAID - ещё какие. Здесь рассказывается о том, как две такие проблемы решить.

Во многом эта статья является цитированием моего же перевода со странички в Wiki Debian, но есть несколько существенных отличий, о которых там не сказано.

Примечания для UEFI-систем.

Debian 7 Wheezy давно поддерживает установку на UEFI-системы, поэтому не надо переводить компьютер в Legacy-режим, продолжайте установку как обычно. В редких случаях в UEFI нужно зайти на вкладку Security и в поле OS type вместо Windows выбрать Other system.

Небольшие различия есть в работе установщика Debian - в случае с обычной системой для правки параметров запуска следует нажать Tab. Для UEFI-систем нужно нажать e. Запуск установщика в этом случае так же производится по-разному: Enter для обычных систем и F10 для UEFI.

Так же для UEFI-систем я НАСТОЯТЕЛЬНО рекомендую преобразовать таблицу разделов из устаревшего уже формата MBR в современный GPT. Однако, должен сразу предупредить: десктопные версии Windows могут работать с GPT только начиная с версии 8, т.е. установить Windows 7 на диск с GPT-таблицей разделов уже не получится.

Начало установки

  1. Создайте RAID-массив. Для этого обычно есть специальные утилиты, поставляемые производителем материнской платы.

  2. Загрузитесь с носителя. Выбрав пункт Install, нажмите нужную клавишу для редактирования параметров загрузки.

  3. Для BIOS-систем просто допишите в конце строки параметров:

    dmraid=true

    В UEFI-системах следует использовать клавиши со стрелочками для перехода к 4-ой строке, которая на 64-битных системах обычно выглядит так:

    linux /install.amd/vmlinuz video=vesa:ywrap,mtrr vga=788 \ -- quiet

    В конце этой строки следует дописать параметр dmraid=true, в итоге получится такая строка:

    linux /install.amd/vmlinuz video=vesa:ywrap,mtrr vga=788 \ -- quiet dmraid=true
  4. Запустите установщик нажатием Enter в BIOS-системах или F10 в UEFI-системах.

  5. Установка будет идти как обычно. В редакторе разделов для UEFI-систем не забудьте Создать в самом начале диска раздел размером 100 МБ, используемый как Загрузочный раздел UEFI. Там будет создана соответствующая запись, позволяющая запускать загрузчик Debian.

  6. На этапе установки загрузчика произойдёт ошибка. ТАК И ДОЛЖНО БЫТЬ - ЗАГРУЗЧИК БУДЕТ УСТАНОВЛЕН ЧУТЬ ПОЗЖЕ. Следует выбрать в меню Продолжение установки без загрузчика.

  7. Устанока будет завершена, будет предложено извлечь установочный носитель и перезагрузиться - перезагрузитесь, снова выбрав загрузку с установочного носителя!

Установка загрузчика

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

  1. В меню выберите пункт Advanced options и нажмите Enter, выберите пункт Rescue mode и сконфигурируйте параметры загрузки ядра так, как это было описано выше, после чего запустите режим восстановления.

  2. Проделайте те же шаги, что и на этапе установки. На одном из этапов будет предложено выбрать корневой раздел для загрузки. Следует выбрать самую первую запись - /dev/dm-1

  3. Будет запущена оболочка BusyBox, в которой по-умолчанию используется интерпретатор sh. Для большего удобства я рекомендую запустить bash соответствующей командой.

  4. Откройте файл /etc/fstab с помощью редактора nano:

    nano /etc/fstab
  5. Обратите внимание на имена разделов. Сейчас они будут выглядеть примерно так:

    /dev/mapper/pdc_ehdiebafp1 /               ext4    errors=remount-ro 0       1
    /dev/mapper/pdc_ehdiebafp9 /home           ext4    defaults          0       2
    /dev/mapper/pdc_ehdiebafp8 /tmp            ext4    defaults          0       2
    /dev/mapper/pdc_ehdiebafp5 /usr            ext4    defaults          0       2
    /dev/mapper/pdc_ehdiebafp6 /var            ext4    defaults          0       2
    /dev/mapper/pdc_ehdiebafp7 none            swap    sw                0       0
    /dev/sr0        /media/cdrom0   udf,iso9660 user,noauto              0       0
    /dev/fd0        /media/floppy0  auto    rw,user,noauto               0       0
  6. Всё, что нужно сделать сейчас - удалить лишнюю букву p перед цифрой в конце имени раздела, т.е. привести все строки к такому виду:

    /dev/mapper/pdc_ehdiebaf1 /               ext4    errors=remount-ro 0       1
    /dev/mapper/pdc_ehdiebaf9 /home           ext4    defaults          0       2
    /dev/mapper/pdc_ehdiebaf8 /tmp            ext4    defaults          0       2
    /dev/mapper/pdc_ehdiebaf5 /usr            ext4    defaults          0       2
    /dev/mapper/pdc_ehdiebaf6 /var            ext4    defaults          0       2
    /dev/mapper/pdc_ehdiebaf7 none            swap    sw                0       0
    /dev/sr0        /media/cdrom0   udf,iso9660 user,noauto             0       0
    /dev/fd0        /media/floppy0  auto    rw,user,noauto              0       0

    После внесения изменений следует сохранить их с помощью Crrl+O и выйти из редактора с помощью Ctrl+X.

  7. Следует перемонтировать все имеющиеся разделы:

    mount -o remount /
    mount /dev/mapper/pdc_ehdiebaf9 /home
    mount /dev/mapper/pdc_ehdiebaf8 /tmp
    mount /dev/mapper/pdc_ehdiebaf5 /usr
    mount /dev/mapper/pdc_ehdiebaf6 /var

    Количество разделов зависит от того, как был размечен диск на этапе установки. Если вдруг забудете, какой раздел куда смонтирован, легко подсмотреть содержимое fstab с помощью команды cat:

    cat /etc/fstab
  8. Теперь следует в файле /etc/default/grub снять комментарий с параметра GRUB_DISABLE_LINUX_UUID=true.

    После того, как изменения будут сделаны и сохранены, выполните следующие команды для установки загрузчика:

    update-grub
    grub-install /deb/mapper/pdc_ehdiebaf

    Здесь вместо pdc_ehdiebaf следует указать такое имя, раздела, которое указано в вашем /etc/fstab для раздела /. Главная отличительная особенность - отсутствие цифр в конце имени.

  9. После того, как загрузчик будет установлен, следует завершить работу в оболочке с помощью команды exit. Если запускали bash, вводить exit придётся дважды.

  10. Перезагрузите ситему, выбрав соответствующий пункт в меню режима восстановления. Теперь установленная система сможет загрузиться.

Дополнительно

Разработчики Debian знают об этом баге с 2013 года, материалы для статьи были взяты из переписки одного из пользователей с ними. Тикет описан здесь, описанное там решение было опробовано в реальной работе.

Non Unicode character at position...

Введение

Как я уже писал ранее, моя компания использует множество проектов, написанных на Python. В качестве платформы для некоторых продуктов используется M3, построенная на основе популярного фреймворка Django. При первоначальной установке проектов на боевые сервера я столкнулся с тем, что при загрузке на сервер файлов, в имени которых встречается кириллица, система выдаёт невнятные сообщения. Оказалось, что проблема заключается в неправильной работе Python с кодировками, в которых хранятся имена файлов. В частности, от этого постоянно падали PIL и Pillow, а в некоторые разделы файлы не загружались вовсе.

В поисках решения

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

  • Использовать в коде явное преобразование строк из одной кодировки в другую с помощью встроенных функций языка либо сторонних пакетов.
  • Установить в систему нужные локали.
  • Прописать настройки в конфигах Django.
  • Перейти с этого вашего Python'а на PHP или Ruby On Rails.

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

Установка в систему нужных локалей.

При установке Debian 7 предлагается выбрать язык системы и кодировку по умолчанию. Если Вы указали свою национальную кодировку (уверен, меня читают не только жители России, но и других стран СНГ), можете этот пункт пропустить. Если же нет, то приступим к установке:

Первым делом следует войти в систему от имени root и выполнить команду по установке пакета управления локалями:

apt-get install locales

После установки этого пакета становится доступна следующая команда:

 dpkg-reconfigure locales

Откроется окно, в котором нужно с помощью пробела отметить локали, которые следует держать в системе (можно выбрать вариант "Все локали", но я не рекомендую - чем меньше в системе лишнего, тем лучше). Я оставил там две локали: en_US.UTF-8 и ru_RU.UTF-8.

После нажатия кнопки OK будет предложено выбрать локаль по-умолчанию. Я использую ru_RU.UTF-8.

В самом конце система приступит к генерации недостающих локалей и их установке в систему.

Настройка окружения для работы Python

Как я писал в одной из статей, для запуска проектов на Python 2.x лучшим выбором является виртуальное окружение, созданное с помощью virtualenv, в которое установлен Gunicorn. При этом управление всем приложением осуществляется с помощью Supervisor'а. Здесь же сразу перейдём к делу.

Переходим в каталог настроек приложений Supervisor'а:

cd /etc/supervisor/conf.d/

Открываем файл настроек нашего приложения и приводим его к следующему виду:

[program:project]
environment=PROJECT_CONFIG_PATH="/var/www/project/conf/",DJANGO_SETTINGS_MODULE="project.settings",PYTHONIOENCODING="UTF-8",LANG="ru_RU.UTF-8",LC_ALL="ru_RU.UTF-8",LC_LANG="ru_RU.UTF-8"
command=/var/www/.virtualenvs/project/bin/gunicorn_django -c /var/www/project/conf/gunicorn.conf.py

user=www-data
group=www-data

daemon=false
debug=false

autostart=true
autorestart=true

redirect_stderr=true
stdout_logfile=/var/www/project/log/supervisor.log

Самая важная строка здесь - та, в которой задаётся значение параметра environment. Именно там указывается, какие локали использовать Python'у для работы с файлами, языком и т.д. Именно эта небольшая строка предотвращает ошибки вида "Non Unicode character at position..." и "Non-ASCII character at position...". Не забудьте удалить переменные окружения, которые на самом деле вам не нужны. При необходимости к окружению можно добавить новые переменные, однако, после запятых не должно быть пробелов, а все значения должны быть заключены в кавычки или апострофы.

После того, как файл настройки будет изменён, следует уведомить об этом Supervisor:

supervisorctl update

Если при этом Supervisor будет выдавать сообщения об ошибках, первым делом следует проверить правильность расстановки кавычек и запятых.

Nginx + PHP-FPM в Debian 7

Введение

В статье рассматривается настройка сервера Debian 7 для размещения проектов PHP в связке с Nginx и PHP-FPM.

Долгое время мне вполне хватало возможностей Apache для разработки моих проектов на PHP. Были некоторые трудности с .htaccess и перенаправлением всех запросов на Front Controller, однако, чуть позже я понял, что Apache уже не может полностью удовлетворить моей тяги к максимальной производительности и начал искать другие пути. Почитав, я выяснил, что доля интернет-серверов под управлением Apache неуклонно снижается на протяжении уже нескольких лет, на замену ему приходят другие, которые дают бОльшую произодительность с меньшей затратой машинных ресурсов. Среди множества решений я выбрал PHP-FPM. Судя по тестам производительности, произведённым многими энтузиастами, именно он в связке с Nginx является наиболее перспективным способом размещения сайтов на PHP.

Цели

  • Увязка PHP-FPM с nginx
  • Конфигурирование параметров сайта для его корректной работы через Front Controller

Установка необходимого ПО

Добавим в список репозитории nginx, предварительно создав файл nginx.list в каталоге /etc/apt/sources.list.d/:

cd /etc/apt/sources.list.d/
touch nginx.list
/etc/apt/sources.list.d/nginx.list
deb http://nginx.org/packages/debian/ wheezy nginx
deb-src http://nginx.org/packages/debian/ wheezy nginx

Скачиваем ключ репозитория:

wget http://nginx.org/keys/nginx_signing.key

Установка ключей в deb-системах делается так:

apt-key add nginx_signing.key

Теперь можно выполнить установку всех необходимых программ:

apt-get update && apt-get install php5 php5-fpm nginx -y
Кратко по списку:
  • php5 и php5-fpm - интерпретатор и FastCGI-сервер для него
  • nginx - проксирующий сервер, будет нашим Front-End, т.е. сервером, принимающим запросы пользователя. Не путать с Front Controller, это совершенно разные вещи!

Настройка PHP и PHP-FPM

При установке PHP-FPM создаёт внутри каталога /etc/php5 подкаталог fpm. Внутри этого каталога находится несколько нужных нам файлов и подкаталогов. Первым делом вносим изменения в файл /etc/php5/fpm/php.ini

cd /etc/php5/fpm
nano php.ini

Здесь множество настроек, которые влияют на поведение PHP. В качестве символа комментария следует использовать точку с запятой. Самыми полезными я считаю следующие настройки:

  • short_open_tag = Off - использование коротких тегов считать ошибкой. Официальная документация по PHP рекомендует не использовать короткие теги.
  • asp_tags = Off - мы тут всё-таки на PHP пишем, а не на ASP.NET
  • max_execution_time = 60 - для некоторых CMS, например, Drupal, стандартных 30 секунд часто не хватает для выполнения некоторых скриптов, например, обновления
  • error_reporting = E_ALL - разработчику нужно видеть все ошибки. Если сервер боевой, нужно выставить в значение E_ALL & ~E_DEPRECATED & ~E_STRICT
  • display_errors = On - для разработки, для боевых условий - Off
  • display_startup_errors = On - аналогично
  • post_max_size = 16M - можно и больше, если через POST будут передаваться достаточно большие объёмы данных
  • default_charset = "UTF-8" - обязательно, если хочется избавиться от большинства проблем с кодировкой. Осторожно! Настройка влияет на весь сервер. Также кодировку можно задать в самом скрипте!
  • cgi.fix_pathinfo=1 - пригодится, если приложение работает через Front Controller
  • upload_max_filesize = 32M - можно и больше, если на сервер будут загружаться большие файлы
  • default_socket_timeout = 60 - в нашем случае связь с Nginx будет именно через сокет. Не стоит выставлять слишком большие значения, это приведёт к падению производительности.

Остальные настройки в этом файле можете делать по своему усмотрению.

Теперь нужно подредактировать файл www.conf в каталоге pool.d/www.conf

nano pool.d/www.conf

Следует изменить user и group на те, от имени которых будут выполняться скрипты. Не следует выполнять их от имени root, это дыра в безопасности. Я рекомендую указывать здесь владельца каталога /var/www

user = www-data
group = www-data

Не менее важная настройка:

listen = /var/run/php5-fpm.sock

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

После сохранения изменений следует перезапустить php-fpm:

service php5-fpm restart

Настройка Nginx

Перейдём в каталог настроек nginx:

cd /etc/nginx/

Здесь нам нужны 2 файла:

  • nginx.conf - основной файл конфигурации сервера
  • fastcgi_params - настройки Nginx для работы с FastCGI-серверами, например, PHP-FPM

Я привёл содержимое этих файлов к следующему виду:

nginx.conf
user nginx;
worker_processes 2;         # По числу ядер/процессоров, либо эмпирическим путём
worker_priority  -5;        # Отрицательные числа задают более высокий приоритет
worker_rlimit_nofile 2048;  # Можно открыть сразу 2048 подключений без изменения параметров ядра

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    tcp_nopush      on;
    tcp_nodelay     on;

    keepalive_timeout  60; #Поддерживать подключение 1 минуту

    client_max_body_size 20m; #Разрешить загрузку файлов до 20 МБ
    server_tokens off;

    #Сжатие передаваемых данных
    gzip  on;
    gzip_disable "msie6";
    gzip_comp_level 2;
    gzip_proxied any;
    gzip_types text/plain text/css application/x-javascript text/xml application/xml+rss text/javascript;

    include /etc/nginx/conf.d/*.conf;
}
В конец файла fastcgi_params нужно добавить всего одну строчку, вот эту:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

Теперь в каталоге /etc/nginx/conf.d/ создадим файл site.conf

nano /etc/nginx/conf.d/site.conf
index index.php;
server {
    server_name www.site.ru;
    rewrite ^ $scheme://site.ru$request_uri? permanent;
}
server {
    server_name site.ru;
    access_log /var/www/site.ru/log/access.log;
    error_log /var/www/site.ru/log/error.log;
    root /var/www/site.ru;

    location / {
        try_files $uri $uri/ /index.php?$request_uri;
        index index.php;
    }

    location ^~ /protected/ {
        deny all;
    }

    location ~ \.php$ {
        try_files $uri = 404;
        include fastcgi_params;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
    }
}

Разберём по частям этот файл:

index index.php;

Считать страницей по-умолчанию index.php

server {
    server_name www.site.ru;
    rewrite ^ $scheme://site.ru$request_uri? permanent;
}

Все запросы на http://www.site.ru автоматически переадресовывать к http://site.ru/

server_name site.ru;
access_log /var/www/site.ru/log/access.log;
error_log /var/www/site.ru/log/error.log;
root /var/www/site.ru;

Собственно наш сервер, с указанием его имени, логов и указанием корневого каталога

location / {
    try_files $uri $uri/ /index.php?$request_uri;
    index index.php;
}

Тут указано, что все запросы вида http://site.ru/login/auth следует переадресовывать к http://site.ru/index.php - как раз то, что нужно для Front Controller'а

location ^~ /protected/ {
    deny all;
}

Запрещаем любые обращения к папке protected нашего сайта. Там лежат исходные коды, к которым будет обращаться только index.php, веб-сервер их отдавать не должен.

location ~ \.php$ {
    try_files $uri = 404;
    include fastcgi_params;
    fastcgi_pass unix:/var/run/php5-fpm.sock;
}

Выдавать ошибку 404, если запрошенный php-файл не найден. В остальном - просто переадресовать запрос на наш PHP-FPM-сервер. Также в этих строках выполняется подключение файла настроек /etc/nginx/fastcgi_params.

После выполнения всех операций следует перезапустить сервис Nginx

service nginx restart

Если исходные файлы сайта размещены в каталоге /var/www/site.ru/, а также этот каталог содержит подкаталог log, владельцем которого является www-data, то при обращении к сайту мы увидим главную страницу.

Оптимизация PostgreSQL

В этой статье я хочу поделиться своими знаниями в области оптимизации PostgreSQL и ссылками на весьма авторитетные источники. Очень подробное руководство с полным описанием всех параметров настройки производительности (и не только) СУБД PostreSQL написал Алексей Васильев.

Вот его страничка.

А вот его замечательная книга.

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

Для оптимизации PostgreSQL я использую утилиту pgtune.

apt-get install pgtune

После её установки надо скопировать конфигурационный файл postresql.conf и запустить эту утилиту с некоторыми параметрами:

cd /etc/postgresql/9.3/main
cp postgresql.conf postgresql.conf.bak
pgtune -i postgresql.conf.bak -o postgresql.conf

Кратко по параметрам:

-i postgresql.conf.bak

Задаёт имя файла, настройки из которого нужно взять за основу

-o postgresql.conf

Имя файла, в который нужно вывести оптимизированные настройки.

Помимо этих двух параметров утилита pgtune имеет ещё кучу дополнительных опций. Самой полезной лично для меня оказалась директива

--type

Она позволяет указать, для каких целей планируется использовать СУБД, что влияет на параметры оптимизации. Для веб-сайтов, например, можно написать вот так:

pgtune -i postgresql.conf.bak -o postgresql.conf --type web

Другие ключи можно посмотреть в описании утилиты по команде

man pgtune