четверг, 17 октября 2013 г.

Настройка nginx тестового и боевого сервера для php разработчиков

Задача:
Есть несколько проектов написанных на php (хотя это не принципиально, но у нас именно так.), есть несколько разработчиков, работающих с этими проектами совместно и есть nginx. Нужно обеспечить разработчиков тестовыми серверами и сделать "боевой" (продакшн ) сервер. Все это происходит на FreeBSD 9.0

Решение:

Было решено завести на сервере для разработчиков учетные записи с домашними директориями (как обычно во FreeBSD) и у каждого делаем директорию projects. То есть:

/home/user1/projects/

/home/user2/projects/

/home/user3/projects/

Далее делаем общую директорию для главных репозиториев проектов. Ну например в /usr/local/dev_www (development www).
Заводим там проекты:

/usr/local/dev_www/project1/

/usr/local/dev_www/project2/

/usr/local/dev_www/project3/

Создаем в проектах репозитории и разработчики user1, user2,.. сначала клонят проекты к себе в projects/,  а потом пушат, резолвятся как им вздумается, но важно чтобы не правили ничего в /usr/local/dev_www. Лучше им туда вообще доступ закрыть на правку, оставить только push allow в .hg/hgrc. Главное чтобы конфликты у себя в домашних директориях разрешали.

Затем делаем конфиг для тестового сервера nginx:

server {
        listen       80;
        server_name  dev-servername;
        access_log  /var/log/nginx/dev-servername.access.log;
        error_log  /var/log/nginx/dev-servername.error.log;
        location / {
            root   /usr/local/dev_www;
            index  index.html index.htm index.php;
            }
# Девелоперский код php
        location ~ /(user1|user2|user3).*(\.php$|/$) {
            set $user $1;
            allow   IP_user1;
            allow   IP_user2;
            allow   IP_user3;
            #...........
            index   index.php;
            rewrite ^/user1/(.*$) /$user/projects/$1 break;
            rewrite ^/user2/(.*$) /$user/projects/$1 break;
            rewrite ^/user3/(.*$) /$user/projects/$1 break;
            #..........
            deny    all;
            fastcgi_pass    unix:/var/run/php5-fpm.sock;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /usr/home$fastcgi_script_name;
            fastcgi_param  PHP_VALUE  "include_path=/usr/home/$user/projects/include";
            include        fastcgi_params;
            }
# Девелоперская статика
        location ~ /(user1|user2|user3).*\.(htm|html|jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|wav|bmp|rtf|js|sw
f)$ {
            set $user $1;
            root    /usr/home;
            allow   IP_user1;
            allow   IP_user2;
            allow   IP_user3;
            #...........
            index  index.html index.htm index.php;
            rewrite ^/user1/(.*$) /$user/projects/$1 break;
            rewrite ^/user2/(.*$) /$user/projects/$1 break;
            rewrite ^/user3/(.*$) /$user/projects/$1 break;
            #...........
            deny        all;
            }
#Раздел для корневых репозиториев     
        location ~ \.php$ {
            fastcgi_pass    unix:/var/run/php5-fpm.sock;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /usr/local/dev_www$fastcgi_script_name;
            fastcgi_param  PHP_VALUE  "include_path=/usr/local/dev_www/include";
            include        fastcgi_params;
            }
#Статика корневых репозиториев
        location ~* ^.+\.(htm|html|jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|wav|bmp|rtf|js|swf)$ {
            root /usr/local/dev_www;
            error_page   404  =  @back;
        }
# Файлы заливаемые пользователями.
        location /media {
            root /var/media/dev_www;
            error_page   404  =  @back;
        }
    }



Этот конфиг инклудим в основной nginx.conf и перезапускаем /usr/local/etc/rc.d/nginx restart

Получаем вот что:

Девелопер user1 заходит на http://dev-servername/user1/project1 и видит свой обрабатываемый  проект, с ошибками и косяками. И так любой из девелоперов с любым проектом.

Далее когда все слито в /usr/local/dev_www мы может зайти на http://dev-servername/project1 и наблюдать как живет разрабатываемый проект в целом.

Если разработчики постоянно пулят друг друга и разрешают конфликты оперативно, то может и не нужно отслеживать  http://dev-servername/project1.

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

В чем суть всего этого спросите вы?

А главное, что отлаживается проект на том же сервере, где и будет эксплуатироваться. Здесь используется один nginx на всех. И если вы ставите какой-то модуль для него или для php, то голова не будет болеть поставить то же самое на "боевом сервере".

Готовый код складываем в /usr/local/www/project1, /usr/local/www/project2 и т.д. То есть в стандартное www пространство. По мере готовности (по этапно) делаются hg push из /usr/local/dev_www/project1, в /usr/local/www/project1, . При этом в .hg/hgrc прописываем :

[hooks]
changegroup = hg update

Чтобы код репозитория /project1 автоматически апдейтился до последней версии. Тоже самое можно сделать и проектах в /usr/local/dev_www

Далее делаем простой и понятный конфиг боевого сервера.

server {
        server_name  nameserver;
        listen 80;
        client_max_body_size 100m;
        access_log  /var/log/nginx/nameserver.access.log;
        error_log  /var/log/nginx/nameserver.error.log;
        keepalive_timeout 3;

        location / {
            root   /usr/local/www;
            index  index.html index.htm index.php;
            }
        location ~ \.php$ {
            root           html;
            fastcgi_pass    unix:/var/run/php5-fpm.sock;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /usr/local/www$fastcgi_script_name;
            fastcgi_param  PHP_VALUE  "include_path=/usr/local/www/include";
            include        fastcgi_params;
            }
   location ~* ^.+\.(htm|html|jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|wav|bmp|rtf|js|swf)$ {
            root /usr/local/www/nginx;
            }
      location /media {
            root  /var/media/www;
            }
    }

Ну и еще на закуску берем и прикручиваем девелоперские проекты к системе управления проектами Redmine. Создаем там проекты, создаем тех самых пользователей - разработчиков (если аутентификация сделана и на сервер и в redmine через LDAP каталог, то вообще ничего делать не нужно) и указываем для проектов хранилища из /usr/local/dev_www/

Красота  - вся движуха по разработке видна в изменениях проекта, все ветки и коммиты видны в хранилище. Ссылка на проект указывает на http://dev-servername/project1 - где сразу видно его функционирование.

И последнее украшение - перекидывание сообщений из системы логирования например Sentry прямо в Redmine в новые задачи с меткой error.

Правда это последнее украшение пока не удалось корректно реализовать, Что-то Sentry  не то делает, но это отдельная тема, расскажу потом.

В общем как то так!

Это схема запущена и работает, пока все довольны.

Что хотелось бы улучшить?

Хотелось бы иметь отдельные логи для отдельных разработчиков и пересылку сообщений об ошибках каждому разработчику свои ошибки. Ну с боевого сервера конечно все получают и потом решают кто и что будет править (Это реализовано через raven-php и Sentry - сервер).

Хотелось бы в конфигах nginx в регулярки  rewrite ^/user1/(.*$) подствлять переменную $user которая берется из url. Пока не знаю как это сделать и поэтому приходится писать столько строк, сколько разработчиков. Немножко не универсально получается...

Вот так! Критикуйте! хвалите или что там еще...




Комментариев нет:

Отправить комментарий