Apache2, PHP, SuEXEC configuration on CentOS

There are plenty of tutorials on the web. Tons and tons.

However when I had to create working configuration and put together Virtualmin template most of these instruction just didn’t work properly. After some time I’ve came up with my own working configuration and proper Virtualmin apache template for CentOS.

As a bonus we’ll have per-user php.ini and apache2 worker MPM which is a little bit faster and less resource hungry then traditional prefork MPM.

First, I turned for instructions to HowTo Forge, which is proven to be an excellent resource, but unfortunately, instructions they provided are a little bit incomplete. Below is my instructions collected from various sources and tested numerous times.

  1. Install rpms – httpd, php-common, mod_fcgid, additional php modules you might need.
  2. Open /etc/httpd/conf.d/php.conf in your favorite editor and comment out everything. As an alternative you can rename php.conf into php.conf.bak which will prevent apache from loading this config file.
  3. Here is my variant of /etc/httpd/conf.d/fcgid.conf – your can customize it as you see fit
  4. Lets create example virtual host web1.com (manually for now – later on I will explain how to do it automatically with virtualmin). We have system user web1(503) in group web1(503). First we have to create proper fcgi wrapper for php – suExec executes scripts from /var/www/cgi-bin while usually user virtual hosts contents are located in /home.

    # mkdir -p /var/www/cgi-bin/web1
    # cat > /var/www/cgi-bin/web1/php-web1
    #!/bin/sh
    export PHPRC=/home/web1
    export PHP_FCGI_MAX_REQUESTS=5000
    export PHP_FCGI_CHILDREN=1
    exec /usr/bin/php-cgi
    ^D
    # chmod 755 /var/www/cgi-bin/web1/php-web1
    # chown -R web1.web1 /var/www/cgi-bin/web1

    We will also need to create default fcgi wrapper, specified in fcgid.conf.

    # cat > /var/www/cgi-bin/php-fcgi
    #!/bin/sh
    export PHPRC=/etc
    export PHP_FCGI_MAX_REQUESTS=5000
    export PHP_FCGI_CHILDREN=1
    exec /usr/bin/php-cgi
    ^D
    # chmod 755 /var/www/cgi-bin/php-fcgi

    This part is finished.
  5. Now, apache virtual host config file in /etc/httpd/conf.d/web1.conf
  6. Copy php.ini file into /home/web1.

    # cp /etc/php.ini /home/web1/
    # chown web1.web1 /home/web1/php.ini

    Restart apache. In /home/web1/public_html create simple test script and chown it to web1.web1

    If you will see this

    Then virtual host is configured correctly
  7. Finishing touches:
    • On CentOS session information is stored in /var/lib/php/session, that is owned by apache.apache. Since suEXEC’ed PHP creates session files owned by user that owns the script, session dir permissions should be adjusted:
      # chown 1777 /var/lib/php/session
    • Since we are not running thread-unsafe mod_php now we can swtich apache to worker MPM:

      # sed -i '/worker/s/^#//' /etc/sysconfig/httpd
      # service httpd restart
    • After switching to PHP FCGI mode, all “php_” options in .htaccess files will result in 500 server error, because without mod_php apache doesn’t understand them. Majority of this configuration options could be done via user php.ini file.

      # find /home -name .htaccess -exec grep -nH php_ {} \;
    • Switching PHP into CGI/FCGI mode breaks some php scripts that do basic http auth, phpMyAdmin in particular. This could be fixed with the followinng .htaccess file in phpMyAdmin directory
  8. And last – Virtualmin apache virtual host template.

    Note – Suexec option in virtualmin should be disabled.
    Along with this template we need to add post-install custom script that will create fcgi wrapper and copy/chown php.ini into the user homedir.

    Copy this script into /usr/local/sbin/ and in Virtualmin add it to “script run after creation of virtual host” settings field.
    Try to create test virtual host and verify that all structure was created properly and has proper permissions /ownership. In case of problems refer to server logs (/var/log/httpd/suexec.log could be very useful).
  1. This is excellent! Thank you so very much!

    Since I’ve switched off shared hosting to VPS, I’ve frustrated myself entirely over this issue. Everything I’ve seen always suggests your users are setup in /var/www/vhost(etc) – which I’ve despised. One little misstep and you could be in trouble. I never got my setup working 100% correctly with suPHP either, as it would mess up my “system” stuff like phpmyadmin and Zarafa (or fail spectacularly).

    • You are welcome. I’ve had my share of trial and error on this and finally got it nailed. There are still some nuances in this configuration.

Leave a Comment

NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">