Convenient web server on Virtualbox
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:
- Official site
- Rapid Deployment of a Development Environment
- Creating a new virtual machine in one minute or “vagrant up!”
The rest of the information was taken bit by bit from Google.
Thanks UFO for invite!