Local web server under Linux, with automatic raising of hosts and switching versions of PHP

Most likely, some parts of this article are already familiar to many havers, but in connection with buying a new working laptop, I decided to put all the grains together and create a convenient tool for development. I often have to work with many small projects, with different versions of PHP, often transfer old projects to new versions. In the distant past, when I was a Windows user, I used OpenServer. But with the transition to Linux, I lacked the simplicity of creating hosts and switching versions that were in it. So I had to make an even more convenient solution on Linux =)


  1. Use the current software at the time of this writing.
  2. To differentiate local domains, we will use a special domain .loc
  3. We switch PHP versions through a subdomain using fast-cgi
  4. Automatically create a host using vhost_alias and dnsmasq

What we have in the end. When going to
Apache will start with PHP version 5.6.36
/ var / www / test.loc /public_html/index.php
By changing the subdomain to
72 .test.loc
the same file will be launched but with PHP 7.2.7.

Other versions are delivered in the same way as described below.

To create another site, simply create in / var / www / a folder with the ending .loc , inside which there must be a public_html folder that is the root of the site

That's all. As without additional torment, restarts, and editing of configs, we have an automatic system for working with sites.

All this I will check on LinuxMint19, it is based on Ubuntu18.04, so everything will be the same with it.

First, put the necessary packages

sudo apt update
sudo apt installbuild-essential pkg-config libxml2-dev libfcgi-dev apache2 libapache2-mod-fcgid postfix

Postfix set as a bun, as a simple solution (in the installation wizard, everything is selected by default) to send mail from the local machine.

Since this is a local development and I am the only user. It is more convenient for me to move the project folder to my home directory. It is mounted on a separate disk and migrates when you reinstall the system. The easiest way is to create a link, then you do not need to change the path in the settings and the path is familiar to all.

Copy the folder created by the apache into the home directory, create a link in its place, not forgetting to change the user to yourself and exchange the groups with the apache.

sudo mv /var/www/ ~/www
sudo ln -s ~/www /var/www
sudo chown $USER:$USER -R ~/www
sudo usermod -a -G www-data $USER
sudo usermod -a -G $USER www-data

Create a folder in which we will collect the PHP source for different versions

sudo mkdir /usr/local/src/php-build

We also need folders for CGI scripts.

sudo mkdir /var/www/cgi-bin

And runtime folder for the same scripts, with rights

sudo mkdir /var/run/mod_fcgid
sudo chmod 777 /var/run/mod_fcgid

And since the directory we have is in RAM, we will add its creation when the system starts, for this we will add to /etc/tmpfiles.d/fcgid.conf
 #TypePathMode UID      GID       Age Argument
 d     /var/run/mod_fcgid  0755 www-data www-data  -   -

My dnsmasq-base comes from the box, if not then it can always be delivered.
sudo apt install dnsmasq

Add a rule to its configuration. You can find the dnsmasq.conf configuration file
sudo updatedb
locate dnsmasq.conf

Or, if he, like me, is part of NetworkManager, then create a new configuration file in /etc/NetworkManager/dnsmasq.d/local.conf
Add a line to it to redirect our local domain to the local machine.


You also need to include the necessary Apache modules.

sudo a2enmod fcgid vhost_alias actions rewrite

Preliminary preparation is complete, we start assembly of various local PHP versions. For each version of PHP we perform the following 4 steps. Using the example 5.6.36

1. Download the sources of the required version and unpack them

cd /usr/local/src/php-build
sudo wget http://pl1.php.net/get/php-5.6.36.tar.bz2/from/this/mirror -O php-5.6.36.tar.bz2
sudo tar jxf php-5.6.36.tar.bz2

2. Collect the necessary version of PHP from source, and put it in /opt/php-5.6.36

sudo mkdir /opt/php-5.6.36cd php-5.6.36
sudo ./configure --prefix=/opt/php-5.6.36 --with-config-file-path=/opt/php-5.6.36 --enable-cgi
sudo make
sudo make install
sudo make clean

3. Create a CGI to handle this version in /var/www/cgi-bin/php-5.6.36.fcgi

export PHPRC
exec /opt/php-5.6.36/bin/php-cgi

4. Making the file executable

sudo chmod +x /var/www/cgi-bin/php-5.6.36.fcgi

5. Add an action to handle each version in /etc/apache2/mods-available/fcgid.conf

<IfModule mod_fcgid.c>AddHandler fcgid-script fcg fcgi fpl
  Action application/x-httpd-php-5.6.36 /cgi-bin/php-5.6.36.fcgi
  AddType application/x-httpd-php-5.6.36 .php
  #Action application/x-httpd-php-7.2.7 /cgi-bin/php-7.2.7.fcgi#AddType application/x-httpd-php-7.2.7 .phpFcgidIPCDir /var/run/mod_fcgid
  FcgidProcessTableFile /var/run/mod_fcgid/fcgid_shm
  FcgidConnectTimeout 20
  <IfModule mod_mime.c>AddHandler fcgid-script .fcgi

6. Add a rule to handle each version in /etc/apache2/sites-available/000-default.conf

<VirtualHost *:80>#Универсальный ServerNamеServerAlias *.loc
        #Алиас для CGI скриптовScriptAlias /cgi-bin /var/www/cgi-bin
        #Универсальный DocumentRootVirtualDocumentRoot /var/www/%2+/public_html
        #Директория тоже должна быть универсальной<Directory /var/www/*.loc/>Options +ExecCGI -Indexes
            AllowOverrideAllOrder allow,deny
            Allow from all<FilesMatch \.php$>#Ниже все условия для каждой из версий<If "%{SERVER_NAME} =~ /56\..*?\.loc/">SetHandler application/x-httpd-php-5.6.36
                </If><Else>#По умолчанию, если версия не указанна, запускаем на последнейSetHandler application/x-httpd-php-7.2.7
        CustomLog${APACHE_LOG_DIR}/access.log combined

Well that's all. It remains only to restart apache and dnsmasq and use

sudo service apache2 restart
sudo service network-manager restart

Put in index.php a new test site phpinfo () and check that everything works.

Also popular now: