Convenient web server on Virtualbox

nginx
When you make simple sites on WordPress, then with a web server everything is simple, I installed Xampp and work quietly.

But the moment comes when you start to engage in serious projects, and there the configuration on the server is not quite ordinary and using Xampp is not very convenient, besides, I'm allergic to Apache.

I wanted a good, live webserver as a dedicated server, but on my computer, while it was convenient to use it locally.

What exactly do you want:
  • Support for normal urls like sitename.ru
  • Do not edit / etc / hosts
  • Do not edit nginx configs
  • Work in local folder
  • Convenient administration of server configuration
  • Isolated environment
  • Set and forget


There is another option - just pick everything up at home, but there’s a catch, if something breaks, the hard drive falls, or something else, then it will be too lazy to collect everything again, and you can just backup the file of the virtual machine, we also get independent environment.

Therefore, I picked up the debian in a virtual machine (virtualbox) and configured nginx + phpfpm in a couple of hours, but this is not yet another how-to for the nginx + phpfpm bundle, we are making a ready-made solution of the xampp type.

Training



So, we have a freshly installed Debian 7 (wheezy). The virtual machine is named webserver. Debian wheezy is also installed on the local machine.

First of all, I would like to get rid of the dialog box and use ssh.

Turn off the virtual machine and write:

$ VBoxManage modifyvm "webserver" --natpf1 "guestssh,tcp,127.0.0.1,2222,10.0.2.15,22"


At the same time we will forward the 80th port for the web server.

Only root can open ports less than 1024 (Thanks to or10n ), so I just forwarded port 8888 and redirected from port 80 to 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


Insert until exit 0

iptables -t nat -A OUTPUT -d 127.0.0.1 -p tcp --dport 80 -j REDIRECT --to 8888


Here instead of 10.0.2.15 there may be another ip, see the output of the ifconfig command on eth0.

We start the virtual machine in the background, it is very convenient, please note that we run as a regular user who has the webserver virtual machine.

$ (vboxheadless -s webserver &)


Click enter.

Everything, we forwarded port 2222 to 22 internal, port 80 will work, we'll see later. We try to connect:

# ssh root@127.0.0.1 -p 2222


Install packages:

# apt-get install nginx php5 php5-fpm php5-mysql php5-gd php5-mcrypt mysql-server mysql-utilities


Configure php-fpm.



Since here we don’t need to take a steam bath with security, therefore everything will work from one www-data user.
We will also handle through the socket. I offer a ready-made config, in fact, I didn’t add anything special there, do not forget to make backups.

# mv /etc/php5/fpm/php-fpm.conf /etc/php5/fpm/php-fpm.conf.default
# nano /etc/php5/fpm/php-fpm.conf


Insert the following:

[global]
pid = /var/run/php5-fpm.pid
error_log = /var/log/php5-fpm.log
include = /etc/php5/fpm/pool.d/*.conf


Here again, default, you can not do this at all, because this is the same config only without comment, but it’s easier for me to re-establish in the config.

Now we need to prepare a pool that will process our php requests. We bring the config to the following form.

# nano /etc/php5/fpm/pool.d/www.conf


Insert the following

[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 = /


The pm parameters are well described on other resources, so here I will not explain anything, just keep it ready.

It remains to fix php.ini. In fact, someone may be satisfied with the default, it’s not bad. But I will bring mine.

# nano /etc/php5/fpm/php.ini


The config is large and optional, so I post pastebin.com/AAudu4sh here

Reboot php-fpm

# service php5-fpm restart


Configure nginx.



In general, there remains a problem with configs, too lazy to go to the server every time, add a config, reboot nginx. Therefore, I assembled a universal config.
After that, you can simply create a folder, upload files and work. No sooner said than done. Here is the ready nginx config for you:

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


We insert the above config.

I do not pretend that the config is good and perfect, but it works for me and has not yet had any problems. I will be very happy if there are people who have something to add here.

Well that's all, it remains only to configure the directory. Let me explain a little how everything will happen with us.

  • / web folder where the whole server will lie, with the exception of the configs of course
  • / web / utils - there we will add all our additional, auxiliary scripts like phpmyadmin, until I figured out what else to put there, because while nothing more is needed.
  • / web / sites - here are all our sites.


There will also be logs, access and error.

Create folders

# mkdir /web && mkdir /web/sites && mkdir /web/utils


We set the rights

# chmod -R a-rwx,u+rwX,g+rX /web && chown www-data:www-data -R /web


Reboot nginx.

# service nginx restart


It remains to install phpmyadmin.

On the server we execute

# 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


That's it, phpmyadmin is ready for work and defense. you can now find it at phpmyadmin.l.

So, the web server is ready for us, it remains to make it start at boot time, saved at shutdown and reboot, and there was no status window.

I’ll describe the strategy a bit, after the virtual machine boots up, we use sshfs to mount the directory with sites, and I did this automatically.

I am also too lazy to edit the / etc / hosts file every time I add another site, so we will automate all this.

Automation



Making authorization by key

On the server, you need to:

Stop the nginx and php5-fpm daemons, and set the home directory for the www-data user.

# 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


Generate the root key, and then put the public key in the file /home/www-data/.ssh/authorized_keys

On the client we check:

# ssh www-data@127.0.0.1 -p 2222


If you entered without a password, then everything is fine, if not, then you did something wrong with the keys.

Now it remains to create 2 scripts.

1) The script for checking the availability of the virtual machine and automatic mounting, as well as the generation of the / etc / hosts file.

# nano /usr/bin/webserver


Paste the following code

#!/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


I do not pretend to the correctness of the code, and I will be glad to those who find bugs there. But it works fine for me.
The convenience of the script is that even if you reboot the virtual machine, nothing will break and everything will be fine.

Now make it executable

# chmod -x /usr/bin/webserver


2) A small script that will start and stop the web server.

# nano /etc/init.d/webserverd


Paste the following code

#!/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 - replace with your user, as the created machine is subordinate to him, and not to the root.
Again, I'm not a pro here, I would be grateful if they correct me, but it works.

We set the rights, and add to the list of services

# chmod -x /etc/init.d/webserverd && update-rc.d webserverd defaults


It remains to create a directory where our sites will be visible

# mkdir /mnt/webserver && chmod 777 /mnt/webserver


Restart our server

# service webserverd stop
# service webserverd start


Everyone, now everyone is happy and satisfied, we create for the test:

$ mkdir /mnt/webserver/testsite.ru.l && echo " /mnt/webserver/testsite.ru.l/index.php

We wait 60 seconds, and go to the browser at testsite.ru.l

Well, that's it, we're done! You can forget about the fact that we have a virtual machine in general, until of course you do not need to put some sort of lib or something else may be needed.

Now, to work with the new site, I just create a folder with the domain name in / mnt / webserver, and just work without distraction.

PS

Here it is more or less clearly described about php-fpm, about pools and other manualpages.pro/node/31

UPD.
Whoever doesn’t like my bike can use Vagrant (thanks zvirusz ). References:


The rest of the information was taken bit by bit from Google.

Thanks a lot to the one who gave me an invite! Yes, unfortunately I did not understand who it is.
Thanks UFO for invite!

Also popular now: