Pull to refresh

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

Reading time 8 min
Views 65K
nginx
Когда делаешь простые сайты на 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 ). Ссылки:


Остальная информация была взята по крупицам из Google.

Спасибо огромное тому кто мне дал инвайт! Да, к сожалению я так и не понял кто это.
Спасибо НЛО за инвайт!
Tags:
Hubs:
+2
Comments 15
Comments Comments 15

Articles