Saturday 27 Jun 2015

Install a lightweight web server on a VPS or small server

Install a web server

Many people today prefer Nginx instead of Apache for resource reasons. However Apache is easier to install, configure and .htaccess are a convenient way to change the configuration of a folder, to put a password or some URL rewriting. I prefer to keep the good old Apache which is solid as a rock and proven!

Here is a guide to install a LAMP Linux, Apache, PHP, MySQL web server on Debian 7. I chose Apache mod-event and PHP-FPM, which will give the best performance without taking up too much memory and it should work well on a relatively small machine, up to a certain number of visitors obviously!

I took actually 2 VPS servers to 4€ a month in the best current French hosting Firstheberg. One for the database, the other for the "front" web server, FTP, email. That makes a lot more economical and powerful solution than one VPS even 3 times more expansive. It has also the advantage of allowing automatic backups from one server to another and, with an "failover IP", the operation even if one of the servers fails.

However, in all hosts, VPS products are profitable for them, but little interest in value. I advise you rather 1 or 2 small dedicated servers or shared hosting, which will often be better than these mini-VPS even if it works. :-)


Be careful, sometimes at the installation, there is a large partition for /home but we often put the sites in /var. If necessary move /var in /home.

I will not detail each line, please look for what you do not understand rather than just copy and paste! ;-) The command lines are on a black background, the codes on a gray background are to paste into files.

First, the protection! We allow only a few IP to connect in SSH. Add in /etc/hosts.allow:

and in /etc/hosts/deny:
sshd: ALL

To add dotdeb (very update packets of PHP extensions) in the sources of apt-get, edit /etc/apt/sources.list and add:

# packages for PHP
deb wheezy all
deb-src wheezy all

apt-get update
apt-get upgrade
apt-get install apache2 apache2-mpm-event apache2-utils apache2.2-common ssl-cert libapache2-mod-fastcgi php5 php5-fpm php5-common php5-gd php5-mysqlnd php-pear php5-curl php5-memcache php5-xcache memcached mysql-client mysql-server openssl

I use xcache, you can install apc just by replacing the word. I have done a lot a researches, both are almost equals.
I use memcache because I need it and we can put the PHP sessions in it. Up to you to decide.
I use curl because I need it, up to you to decide.


a2enmod fastcgi actions expires headers rewrite include negotiation alias ssl
php5dismod pdo pdo_mysql
a2ensite default-ssl
apt-get install vlogger


Uncomment in /etc/apache2/conf.d/charset the line: AddDefaultCharset UTF-8

I use vlogger to make Apache logs rotations and manage all websites in a single line. To do this, comment all in /etc/apache2/conf.d/other-vhost-access-log (vlogger will take care of all vhosts)

Uncomment the 37 last lines in /etc/apache2/conf.d/localized-error-pages to put the international Apache error pages.

In /etc/apache2/apache2.conf change in LogLevel error to reduce the logs, and add at the end to use the caches of browsers ( and are requeted but we already install them):

Header unset ETag
FileETag None
# cache 30 days
<FilesMatch "\.(jpg|jpeg|png|gif|swf|js|css|png|ico|ttf)$">
Header set Cache-Control "max-age=1296000, public"
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 1 week"
ExpiresByType application/x-httpd-php "access plus 1 day"
ExpiresByType text/html "access plus 1 day"
ExpiresByType text/css "access plus 1 week"
ExpiresByType text/javascript "access plus 1 week"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/jpg "access plus 2 weeks"
ExpiresByType image/png "access plus 1 month"
ExpiresByType application/x-shockwave-flash "access plus 1 month"
# if your sites send .ttf fonts
AddType application/x-font-ttf .ttf
# compression
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css application/javascript application/x-javascript application/rss+xml application/atom_xml text/javascript application/x-font-ttf
# Logfile configuration for vlogger:
LogFormat "%v %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined_ispconfig
CustomLog "| /usr/sbin/vlogger -s access.log -t \"%Y%m%d-access.log\" /var/log/apache2" combined_ispconfig env=!statique_sauf_jpeg
ErrorLog ${APACHE_LOG_DIR}/error.log

Create the file etc/apache2/conf.d/php5-fpm.conf with inside:

Action php5-fcgi /php5-fcgi
Alias /php5-fcgi /var/www/cgi-bin/php5-fcgi-www
FastCgiExternalServer /var/www/cgi-bin/php5-fcgi-www -socket /var/run/php5-fpm.sock
<FilesMatch "\.php$">
SetHandler php5-fcgi

Change in /etc/php5/fpm/pool.d/www.conf the lines to put on the "ondemand" mode to allow PHP-FPM to manage alone the necessary resources and significantly reduces memory usage by losing only insignificant response for queries:

pm = ondemand
;pm.start_servers = 2
;pm.min_spare_servers = 1
;pm.max_spare_servers = 3
pm.max_requests = 500

Add in /etc/php5/mods-available/xcache.ini: xcache.size = 64M
(or if APC: apc.shm_size = 64M)

Change in /etc/php5/fpm/php.ini (not add, change!):

expose_php = Off
display_errors = On
log_errors = Off
log_errors = Off
date.timezone = "Europe/London" <--- your zone!
session.save_handler = memcache <--- if you have installed it, or don't change
session.save_path = "tcp://localhost:11211"

Especially if your database is a separate server, you should consider installing the PHP extension mysqlnd_qc to put SQL queries in cache with PHP.


2 small tools to see the use of hard drives and automatically block the attempts of various attacks (if installed, modify /etc/fail2ban/jail.conf to enable Apache filters):

apt-get install iotop
apt-get install fail2ban

To see and manage locales, especially for GetText if your sites have several languages:

locale -a
dpkg-reconfigure locales
apt-get install awstats

AWStats to create statistics for the web sites visits. In /etc/awstats/awstats.conf and in awstats.conf.local write:


Modify /etc/mysql/my.cnf to external connection and cache value:

bind-address = (only if your database is external)
key_buffer_size = 128M
# 25% of the memory is recommended
max_connections = 30
query_cache_type = ON
query_cache_limit = 256K
query_cache_size = 8M


Possibly install a failover IP (French).

Finally, create a user for each website by security, and create the corresponding vhost files in /etc/apache2/sites-available and the "pool" files for PHP-FPM in /etc/php5/fpm/pool.d
I don't explain more because we are not really anymore in the server installation but here are 2 minimalist models for these files:

<VirtualHost *:80>
DocumentRoot /var/www/site_web1
ServerAlias *

user = site_web1
group = sites_web

The files sent in /var/www/site_web1 must belong to the owner of site_web1 from group sites_web.

café Did this article help you? 
Buy me a coffee!

Leave a comment (all comments are moderated, don't waste time with spam)

Azure Dev