
Удобный веб сервер на Virtualbox

Когда делаешь простые сайты на WordPress, то с вебсервером все просто, поставил себе Xampp и спокойно работаешь.
Но приходит момент когда начинаешь заниматься серьезными проектами, а там уже конфигурация на сервере не совсем обычная и пользоваться Xampp не совсем удобно, к тому же у меня аллергия на Apache.
Захотелось хороший, живой вебсервер по типу выделеного сервера, но на своем компе, при этом чтобы пользоваться было удобно, локально.
Что именно хочется:
- Поддержку нормальных url типа sitename.ru
- Не редактировать /etc/hosts
- Не редактировать конфиги nginx
- Работать в локальной папке
- Удобное администрирование конфигурации сервера
- Изолированое окружение
- Поставить и забыть
Есть еще вариант — просто у себя поднять все, но есть загвоздка, если что нибудь сломается, упадет жесткий диск, или еще что нибудь, то потом опять все собирать будет лень, а так просто можно сделать бэкап файла виртуальной машины, так же получаем независимое окружение.
Поэтому я поднял дебиан на виртуальной машине (virtualbox) и настроил nginx+phpfpm за пару часов, но это не очередное хау ту по связке nginx+phpfpm, мы делаем готовое решение по типу xampp.
Подготовка
Итак, мы имеем свежеустановленный Debian 7 (wheezy). Виртуальная машина имеет имя webserver. На локальной машине установлен так же Debian wheezy.
Первым делом хотелось бы избавиться от диалогового окна и использовать ssh.
Выключаем виртуальную машину и пишем:
$ VBoxManage modifyvm "webserver" --natpf1 "guestssh,tcp,127.0.0.1,2222,10.0.2.15,22"
Заодно пробросим 80 порт для вебсервера.
Порты меньше 1024 может открывать только root (Спасибо or10n), поэтому я просто пробросил 8888 порт и перенаправил с 80 порта на 8888.
$ VBoxManage modifyvm "webserver" --natpf1 "web,tcp,127.0.0.1,8888,10.0.2.15,80"
# iptables -t nat -A OUTPUT -d 127.0.0.1 -p tcp --dport 80 -j REDIRECT --to 8888
# nano /etc/rc.local
Вставляем до exit 0
iptables -t nat -A OUTPUT -d 127.0.0.1 -p tcp --dport 80 -j REDIRECT --to 8888
Тут вместо 10.0.2.15 может быть другой ip, смотрите вывод команды ifconfig на eth0.
Запускаем виртуальную машину в фоне, это очень удобно, прошу заметить, что запускаем под обычным пользователем, у которого находится виртуальная машина webserver.
$ (vboxheadless -s webserver &)
Жмем энтер
Все, мы пробросили 2222 порт на 22 внутренний, 80 порт будет работать, позже увидим. Пробуем коннектиться:
# ssh root@127.0.0.1 -p 2222
Устанавливаем пакеты:
# apt-get install nginx php5 php5-fpm php5-mysql php5-gd php5-mcrypt mysql-server mysql-utilities
Настраиваем php-fpm.
Поскольку тут нам париться с безопасностью не надо, поэтому все будет работать от одного юзера www-data.
Так же мы будем обращаться через сокет. Предлагаю готовый конфиг, на самом деле я там особо своего ничего не добавлял, не забываем делать бэкапы.
# mv /etc/php5/fpm/php-fpm.conf /etc/php5/fpm/php-fpm.conf.default
# nano /etc/php5/fpm/php-fpm.conf
Вставляем следующее:
[global]
pid = /var/run/php5-fpm.pid
error_log = /var/log/php5-fpm.log
include = /etc/php5/fpm/pool.d/*.conf
Здесь опять же дефолт, можете вообще этого не делать, т.к. это тот же конфиг только без комментариев, но мне так проще ореинтироваться в конфиге.
Теперь надо подготовить пулл, который будет обрабатывать наши php запросы. Приводим конфиг к следующему виду.
# nano /etc/php5/fpm/pool.d/www.conf
Вставляем следующее
[www]
user = www-data
group = www-data
listen = /tmp/php5-fpm.sock
pm = dynamic
pm.max_children = 10
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
chdir = /
Параметры pm хорошо описаны на других ресурсах, поэтому тут я ничего не буду объяснять, просто держите готовое.
Осталось поправить php.ini. На самом деле кого то может устроить и дефолтный, он неплохой. Но я все же приведу свой.
# nano /etc/php5/fpm/php.ini
Конфиг большой и необязательный, поэтому выкладываю сюда pastebin.com/AAudu4sh
Перезагружаем php-fpm
# service php5-fpm restart
Настраиваем nginx.
В общем остается проблема с конфигами, лень каждый раз лезть на сервер, добавлять конфиг, перезагружать nginx. Поэтому собрал универсальный конфиг.
После можно будет просто создать папку, залить файлы и работать. Сказано, сделано. Вот Вам готовый конфиг nginx:
user www-data;
worker_processes 4;
pid /var/run/nginx.pid;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Базовые настройки
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# При ошибках не говорим врагу версию nginx
server_tokens off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# Настройка логов
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Настройки сжатия
##
gzip on;
gzip_disable "msie6";
##
# Настройка виртуальных доменов
##
include /etc/nginx/conf.d/*.conf;
server {
server_name phpmyadmin.l;
listen 80;
root /web/utils/phpmyadmin.l;
index index.php index.html index.htm;
access_log /web/access.log;
error_log /web/error.log;
location / {
try_files $uri $uri/ /index.php?q=$uri&$args;
}
location ~* ^.+.(js|css|png|jpg|jpeg|gif|ico)$ {
access_log off;
expires max;
}
location ~ \.php$ {
# fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_pass unix:/tmp/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_intercept_errors off;
fastcgi_ignore_client_abort off;
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;
}
}
server {
server_name ~^(.*)$;
listen 80;
set $p $host;
if ($host ~ www\.(.*)) { set $p $1; }
root /web/sites/$p;
index index.php index.html index.htm;
access_log /web/access.log;
error_log /web/error.log;
location / {
try_files $uri $uri/ /index.php?q=$uri&$args;
}
location ~* ^.+.(js|css|png|jpg|jpeg|gif|ico)$ {
access_log off;
expires max;
}
location ~ \.php$ {
# fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_pass unix:/tmp/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param SERVER_NAME $p;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_intercept_errors off;
fastcgi_ignore_client_abort off;
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;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
}
}
# mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.default
# nano /etc/nginx/nginx.conf
Вставляем вышеприведеный конфиг
Я не претендую на то что конфиг хорош и идеален, но он у меня работает и проблем пока не возникало. Я буду очень рад если тут найдутся люди которым есть что сюда добавить.
Ну все, осталось только настроить дериктории. Немного поясню как у нас будет все происходить.
- /web папка где будет лежать весь сервер, за исключением конфигов конечно же
- /web/utils — туда мы будем складывать все наши дополнительные, вспомогательные скрипты типа phpmyadmin, пока я не придумал что туда еще положить, т.к. пока больше ничего не надо.
- /web/sites — тут наши все сайты.
Так же будут логи, access и error.
Создаем папки
# mkdir /web && mkdir /web/sites && mkdir /web/utils
Задаем права
# chmod -R a-rwx,u+rwX,g+rX /web && chown www-data:www-data -R /web
Перезагружаем nginx.
# service nginx restart
Осталось поставить phpmyadmin.
На сервере выполняем
# su www-data
# cd /web/utils/phpmyadmin.l && wget http://jaist.dl.sourceforge.net/project/phpmyadmin/phpMyAdmin/4.0.4.2/phpMyAdmin-4.0.4.2-all-languages.zip && unzip phpMyAdmin-4.0.4.2-all-languages.zip && mv phpMyAdmin-4.0.4.2-all-languages/* ./ && rm -r phpMyAdmin-4.0.4.2-all-languages/ && rm phpMyAdmin-4.0.4.2-all-languages.zip
# exit
Все, phpmyadmin готов к труду и обороне. можно его теперь найти по адресу phpmyadmin.l
Итак, вебсервер у нас готов, осталось сделать так чтобы он стартовал при загрузке, сохранялся при выключении и перезагрузке, и при этом не было окна состояния.
Немного опишу стратегию, после того как виртуальная машина загрузится, мы при помощи sshfs маунтим директорию с сайтами, и я сделал это автоматом.
Так же мне лень каждый раз редактировать файл /etc/hosts при добавлении очередного сайта, поэтому мы все это автоматизируем.
Автоматизация
Делаем авторизацию по ключу
На сервере надо:
Остановить демоны nginx и php5-fpm, и установить домашнюю дерикторию для юзера www-data.
# service nginx stop && service php5-fpm stop
# mkdir /home/www-data && usermod -d /home/www-data www-data
# service nginx start && service php5-fpm start
Сгенерировать ключ от рута, и после поместить публичный в файл /home/www-data/.ssh/authorized_keys
На клиенте проверяем:
# ssh www-data@127.0.0.1 -p 2222
Если зашли без пароля, то все хорошо, если нет, то что-то Вы сделали не так с ключами.
Теперь осталось создать 2 скрипта.
1) Скрипт проверки доступности виртуальной машины и автоматический маунтинг, так же генерация файла /etc/hosts.
# nano /usr/bin/webserver
Вставляем следующий код
#!/bin/bash
sleep=60 # Интервал
when_mount='/mnt/webserver' # Дериктория куда все это будет маунтиться
directories=`ls -p $when_mount | grep "/" | sed 's/\///g'`
while true; do
if ! $(mount | grep "$when_mount" > /dev/null); then
if [ "$(nmap -p 2222 -sT 127.0.0.1 | awk '{print $2}' | grep open)" = "open" ]; then
sshfs -o allow_other -o port=2222 www-data@127.0.0.1:/web/sites "$when_mount"
fi;
elif ! [ "$directories" = $(ls -p $when_mount | grep "/" | sed 's/\///g') ]; then
hosts=$(grep -v "127.0.0.1" /etc/hosts)
directories=$(ls -p $when_mount | grep "/" | sed 's/\///g')
if ! [ "$directories" = "" ]
then
echo "$hosts" > /etc/hosts
echo "127.0.0.1 localhost phpmyadmin.l "$directories >> /etc/hosts
fi;
fi
sleep "$sleep"
done
На правильность кода я не претендую, и буду рад тому кто найдет там баги. Но у меня он работает исправно.
Удобство скрипта в том что даже если перезагрузите виртуальную машину, ничего не поломается и все будет хорошо.
Теперь делаем его исполняемым
# chmod -x /usr/bin/webserver
2) Небольшой скрипт который будет запускать и останавливать вебсервер.
# nano /etc/init.d/webserverd
Вставляем следующий код
#!/bin/bash
case "$1" in
start)
echo -n "Starting webserver: "
(su - darkrain -c 'vboxheadless -s webserver' &)
(webserver &)
;;
stop)
echo -n "Stopping webserver: "
(su - darkrain -c 'VBoxManage controlvm webserver savestate' &)
killall webserver
;;
esac
exit 0
darkrain — заменить на вашего юзера, т.к. созданая машина находится в подчинении у него, а не у рута.
Опять же я тут не профи, буду признателен если меня поправят, но это работает.
Выставляем права, и добавляем в список сервисов
# chmod -x /etc/init.d/webserverd && update-rc.d webserverd defaults
Осталось создать каталог где будут видны наши сайты
# mkdir /mnt/webserver && chmod 777 /mnt/webserver
Рестартуем наш сервер
# service webserverd stop
# service webserverd start
Все, теперь все счастливы и довольны, создаем для теста:
$ mkdir /mnt/webserver/testsite.ru.l && echo "<?php phpinfo();" > /mnt/webserver/testsite.ru.l/index.php
Ждмем 60 секунд, и идем в браузер по адресу testsite.ru.l
Ну все, мы закончили! Можно забыть про то что у нас есть вообще виртуальная машина, пока конечно не понадобиться поставить какую нибудь либу или еще что-то может понадобиться.
Теперь чтобы работать с новым сайтом я просто создам папку с именем домена в /mnt/webserver, и просто буду работать не отвлекаясь.
P.S.
Здесь более менее понятно описано про php-fpm, про пулы и прочее manualpages.pro/node/31
UPD.
Кому не понравится мой велосипед, может использовать Vagrant (спасибо zvirusz ). Ссылки:
- Официальный сайт
- Быстрое развертывание среды разработки
- Создание новой виртуальной машины за одну минуту или «vagrant up!»
Остальная информация была взята по крупицам из Google.
Спасибо НЛО за инвайт!
Comments 15
Only users with full accounts can post comments. Log in, please.