Nginx+php-fpm+dnsmasq. Локальное окружение для разработки.

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

Хватит редактировать /etc/hosts

Каков обычный сценарий веб-разработчика, начинающего писать новый проект? Правильно, настройка apache и внесение новой записи в /etc/hosts. До конфигурации самого сервера еще дойдем, а пока перестанем редактировать файл hosts. Для обработки запросов к нашим виртуальным хостам нам понадобится dnsmasq. Если Вы используете NetworkManager, то у Вас уже есть все что нужно, в противном случае необходимо установить dnsmasq средствами вашего дистрибутива. Я рассмотрю пример, когда используется NetworkManager.

Сперва включим поддержку dnsmasq в конфигурационном файле NetworkManager’а, добавив в файл /etc/NetworkManager/NetworkManager.conf следующее:

[main]
dns=dnsmasq

Далее, в директории /etc/NetworkManager/dnsmasq.d создадим файл конфигурации local-development.conf с таким содержанием:

address=/dev/127.0.0.1

Таким образом, мы привязали любой домен в зоне .dev к адресу 127.0.0.1, что избавляет нас от внесения новых записей в /etc/hosts. Для вступления настроек в силу, необходимо перезапустить NetworkManager.

Если вы не используете NetworkManager, то после установки необходимо сконфигурировать dnsmasq, внеся привязку Вашей тестовой зоны в файл /etc/dnsmasq.conf, пример можно посмотреть тут.

Настройка php-fpm

Я уже продолжительное время не использую apache, найдя ему замену в лице nginx + php-fpm. Раньше для каждого проекта я создавал отдельный pool, но на данный момент я решил перейти к универсальному конфигу, который бы работал для каждого добавляемого проекта. Собственно конфигурация fpm (/etc/php5/fpm/php-fpm.conf):

[global]
pid = /var/run/php-fpm.pid
error_log = /var/log/php/fpm/error.log
log_level = notice
emergency_restart_threshold = 10
emergency_restart_interval = 1m
process_control_timeout = 10s
daemonize = yes

[www]

listen = /var/run/php5-fpm.sock
listen.backlog = -1
listen.allowed_clients = 127.0.0.1

listen.owner = gwinn
listen.group = gwinn
listen.mode = 0666

user = gwinn
group = gwinn

pm = dynamic
pm.max_children = 5
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_spare_servers = 2
pm.max_requests = 200
pm.status_path = /status
request_terminate_timeout = 120s
request_slowlog_timeout = 10s
slowlog = /var/log/php/fpm/slow.log
rlimit_files = 131072
rlimit_core = unlimited
catch_workers_output = yes
env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp

php_flag[display_errors] = on
php_admin_value[error_log] = /var/log/php/fpm/error.log
php_admin_value[session.save_path] = /tmp
php_admin_flag[log_errors] = on
php_admin_value[memory_limit] = 32M

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

Настройка nginx

Nginx не обойдется одним файлом конфигурации, под каждый тип проектов, я создал свой конфиг, впрочем, это все равно делается только один раз, что собственно не плохо. Под типами проектов я подразумеваю следующее: Symfony2, CodeIgniter, WordPress, Ruby on Rails, Mojolicious и т.д. Помимо этого, nginx будет обрабатывать запросы к phpMyAdmin и phpPgAdmin, для которых так же я сделал отдельный конфиг.

Приведу примеры основного конфига nginx, а так же конфигурацию для менеджеров баз данных и проектов на Symfony2, остальное можно сделать по аналогии.

/etc/nginx/nginx.conf
user gwinn gwinn;
worker_processes 2;
timer_resolution 100ms;
worker_rlimit_nofile 8192;

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

events {
    worker_connections 2048;
    use epoll;
}

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;
    autoindex on;
    keepalive_timeout 65;
   
    gzip on;
    gzip_min_length 1100;
    gzip_buffers 64 8k;
    gzip_comp_level 3;
    gzip_http_version 1.1;
    gzip_proxied any;
    gzip_types text/plain application/xml application/x-javascript text/css;
   
    charset utf-8;
   
    client_body_temp_path /tmp/nginx_client_body_temp 1 2;
    fastcgi_temp_path /tmp/nginx_fastcgi_temp;
    scgi_temp_path /tmp/nginx_scgi_temp;
    proxy_temp_path /tmp/nginx_proxy_temp;
    uwsgi_temp_path /tmp/nginx_uwsgi_temp;
   
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}
/etc/nginx/sites-enabled/db.conf
upstream phpcgi {
    server unix:/var/run/php5-fpm.sock;
}

server {
    listen 127.0.0.1:80;
    server_name *.db.dev;
    root /usr/local/share/db/$http_host;
   
    if ( !-e $request_filename ) {
        rewrite ^ /index.php last;
    }
   
    location / {
        index index.html index.htm index.php;
        try_files $uri $uri/ /index.php;
    }
   
    location ~* ^.+\.(jpg|jpeg|JPEG|JPG|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar)$ {
        access_log off;
        expires max;
    }
   
    location ~ \.php$ {
        include /etc/nginx/fastcgi_params;
        fastcgi_pass phpcgi;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_script_name;
        fastcgi_param PHP_VALUE "error_log=/var/log/nginx/error.log";
        fastcgi_connect_timeout 60;
        fastcgi_send_timeout 180;
        fastcgi_read_timeout 180;
        fastcgi_buffer_size 128k;
        fastcgi_buffers 4 256k;
        fastcgi_busy_buffers_size 256k;
        fastcgi_temp_file_write_size 256k;
        fastcgi_intercept_errors on;
    }
   
    location ~ /\.ht {
        deny all;
    }
   
    location ~ /\.git {
        deny all;
    }
   
    error_log /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
}
/etc/nginx/sites-enabled/symfony.conf
upstream symfony {
    server unix:/var/run/php5-fpm.sock;
}

server {
    listen 127.0.0.1:80;
    server_name *.sym.dev;
    root /home/gwinn/Code/$http_host/web;
   
    if ( !-e $request_filename ) {
        rewrite ^ /app_dev.php last;
    }
   
    location / {
        index app_dev.php
        try_files $uri $uri/ /app_dev.php;
    }
   
    location ~* ^.+\.(jpg|jpeg|JPEG|JPG|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar)$ {
        access_log off;
        expires max;
    }
   
    location ~ ^/(app|app_dev|config)\.php(/|$) {
        include /etc/nginx/fastcgi_params;
        fastcgi_pass symfony;
        fastcgi_index app_dev.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_script_name;
        fastcgi_param PHP_VALUE "error_log=/var/log/nginx/error.log";
        fastcgi_connect_timeout 60;
        fastcgi_send_timeout 180;
        fastcgi_read_timeout 180;
        fastcgi_buffer_size 128k;
        fastcgi_buffers 4 256k;
        fastcgi_busy_buffers_size 256k;
        fastcgi_temp_file_write_size 256k;
        fastcgi_intercept_errors on;
    }
   
    location ~ /\.ht {
     deny all;
    }
   
    location ~ /\.git {
        deny all;
    }
   
    error_log /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
}

Обратите внимание на директиву server_name. Для всех локальных ресурсов используется зона .dev, все проекты, например на Symfony2, размещаются по адресу project_name.sym.dev, а менеджеры баз данных по адресу manager_name.db.dev, то есть каждый тип проекта размещается по схеме project.type.dev, все поддомены обрабатываются автоматически. Теперь достаточно создать директорию, например, myproj.sym.dev, и nginx автоматически будет применять к данной директории конфиг для Symfony. Для любого другого типа проектов, все делается аналогично.

Nginx+php-fpm+dnsmasq. Локальное окружение для разработки.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *