Tuesday, February 19, 2013

Installing LAMP with FastCGI, PHP-FPM and APC

If you are looking for a way how to utilize your Rasberry PI as a cheap web server, this article is written just for you. Although Raspberry's computation power isn't as good as your phone or even laptop, it is still enough to host a small website. To be more precise, small website with a low traffic.

In this blog post I would like to show you step by step tutorial how to set up web server with PHP and optionally MySQL on your Raspberry to gain the most possible performance.

This guide has been tested on Raspbian Wheezy operating system, but it should work with any other version of Raspbian as well.

Installing Apache with PHP

First you need to switch yourself to root:

sudo su

Install packages for Apache and PHP:

apt-get install apache2-mpm-worker php5-fpm

Installing FastCGI

Then you need to install FastCGI module for Apache, but because this one is not available as binary (.deb) package in Rasbian repository, it is needed to be compiled from the source.

Install all dependencies first:

apt-get install debhelper cdbs apache2-threaded-dev dpatch libtool libapr1-dev pkg-config

Add line to /etc/apt/sources.list to enable sourca packages repository:

deb-src http://mirrordirector.raspbian.org/raspbian/ wheezy main contrib non-free rpi
Then download libapache-mod-fastcgi source package, compile and then install from binary package:
apt-get update
apt-get -b source libapache-mod-fastcgi
dpkg -i libapache2-mod-fastcgi*.deb

Configuring Apache and PHP

Enable mod_actions:

a2enmod actions

Create directory /var/www/fastcgi and make sure it's accessible for user www-data

mkdir /var/www/fastcgi
chown www-data:www-data /var/www/fastcgi

Edit file /etc/apache2/mods-available/fastcgi.conf to look following way:

<IfModule mod_fastcgi.c>
  AddHandler fastcgi-script .fcgi
  #FastCgiWrapper /usr/lib/apache2/suexec
  FastCgiIpcDir /var/lib/apache2/fastcgi

  Alias /php5.fastcgi /var/www/fastcgi/php5.fastcgi
  AddHandler php-script .php
  FastCGIExternalServer /var/www/fastcgi/php5.fastcgi -socket /var/run/php5-fpm.sock
  Action php-script /php5.fastcgi virtual

  # This part is not necessary to get it to work, but it stops anything else from being
  # accessed from it by mistake or maliciously.
  <Directory "/var/www/fastcgi">
    Order allow,deny
    <Files "php5.fastcgi">
      Order deny,allow
    </Files>
  </Directory>
</IfModule>

Installing APC

Your server will work even without this module, but usage of APC can significantly speed up your PHP applications. I personally tried with default Wordpress installation and with APC the response time was about 200 % faster. The APC (Alternative PHP Cache) is a free and open opcode cache for PHP. Its goal is to provide a free, open, and robust framework for caching and optimizing PHP intermediate code. It just mean that the PHP code isn't parsed everytime is needed again and again, but instead it's saved in cache and parsed only first time. Which is of course huge performance improvement.

The only drawback is that APC is not very well compatible with common php-cgi setup, because the cache is not shared among all spawned PHP processes. That's reason I used mod_fastcgi and PHP-FPM instead.

Let's install APC:

apt-get install php-apc

Installing MySQL

When needed you can optionally install MySQL server. Installation is straightforward:

apt-get install mysql-server mysql-client php5-mysql

Finishing up

Restart Apache and PHP-FPM to reload new configuration:

service apache2 restart && service php5-fpm restart

Add your website source code to /var/www

10 comments:

  1. service apache2 restart
    /usr/sbin/apache2ctl: 87: ulimit: error setting limit (Operation not permitted)
    Syntax error on line 4 of /etc/apache2/mods-enabled/fastcgi.conf:
    FastCgiIpcDir /var/lib/apache2/fastcgi: access for server (uid 1000, gid 1000) failed: write not allowed
    Action 'configtest' failed.

    I changed the permissions to 777
    service apache2 restart
    [....] Restarting web server: apache2/usr/sbin/apache2ctl: 87: ulimit: error setting limit (Operation not permitted)
    apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName
    /usr/sbin/apache2ctl: 87: ulimit: error setting limit (Operation not permitted)
    apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName
    (13)Permission denied: make_sock: could not bind to address 0.0.0.0:80
    no listening sockets available, shutting down
    Unable to open logs
    Action 'start' failed.

    ReplyDelete
  2. For people with failing dependancies, check apt-get install build-essential

    ReplyDelete
  3. another dependency:
    apt-get install pkg-config
    before compiling libapache-mod-fastcgi

    ReplyDelete
  4. For any using Jessie (8.0) don't forget to install libtool-bin and of course the repository for compiling FastCGI.

    #apt-get install libtool-bin

    ReplyDelete
  5. There seems to be something wrong with the source packet
    libapache-mod-fastcgi. Hope it gets fixed.

    #apt-get -b source libapache-mod-fastcgi

    dpkg-checkbuilddeps: Unmet build dependencies: apache2-threaded-dev (>= 2.2.4) | apache2-prefork-dev (>= 2.2.4)
    dpkg-buildpackage: warning: build dependencies/conflicts unsatisfied; aborting
    Build command 'cd libapache-mod-fastcgi-2.4.7~0910052141 && dpkg-buildpackage -b -uc' failed

    ( Raspberry pi model 2, Minibian Jessie )

    ReplyDelete
    Replies
    1. try to use, to remove those dependencies..
      #apt-get install apache2-dev

      tested on armbian 8 (in banana pi)

      Delete
    2. I had the same issue and I solved it by just uncommenting in etc/apt/sources.list the line that says "uncomment to enable apt-get source" (instead of adding the line as stated above)

      (Raspberry Pi 3)

      Delete
  6. Hi,

    Nice tutorial, it really helped me. Everything worked fine for me on a Raspbian Wheezy install - Pi 1. Now I think you should add a post on how to run RRDTool database in a ram disk so the SD card doesn't get wasted by all this data being rewritten on it all the time. I think it could be as simple as changing a directory option in the Path config file but I could be missing other things going on, like the images/graphs recreated on every report that would be nice to have on a ram disk too. Also, would be nice if you could show us how to keep a hard copy of the db, maybe like after 24h, save the database on the SD card so if a shutdown happens, all the fetched data is not lost. I think these are features in the RRDTool readily available but haven't found how to tinker SmokePing to work like that yet. I will share if I find something. Nice work again, thank you very much.

    ReplyDelete
    Replies
    1. This webpage explains everything about the configurations of the directories in the ***General*** section, which are the files in the /etc/smokeping/config.d/ . I guess i just have to add/replace the 'imgcache' and 'datadir' parameters with the path of the ram disk I have mounted.

      http://oss.oetiker.ch/smokeping/doc/smokeping_config.en.html

      This seems a good tutorial on Ram Disks:

      http://www.zdnet.com/article/raspberry-pi-extending-the-life-of-the-sd-card/

      This one is good too:

      http://www.cyberciti.biz/faq/howto-create-linux-ram-disk-filesystem/

      Now just looking for a way to save on the SD card daily dumps/images of the .rrt file used by SmokePing. Im thinking of using a SVN or Hg or maybe even GIT to compress/backup daily snapshots.

      Delete
    2. This was helpful to:

      https://github.com/motoz/PellMon/wiki/How-to-set-up-ramdisk-for-the-rrd-database-on-a-Rasperry-Pi

      Im thinking of using BackupNinja for daily snapshots but maybe good ol' rsync in a cron would do the trick...

      Delete