Admin... by accident!

You may have chosen to be an admin. I didn't!

  • Home
  • FreeBSD
  • GNU/Linux
  • Security
  • Network
  • Virtualization
  • Politics
  • Github
  • Donate
  • Me

How to set Apache’s MPM Event and PHP-FPM on FreeBSD

April 1, 2019 by Albert Valbuena

As explained in another article the default Apache’s configuration at compile time sets its multi-processing module (MPM for short) to the pre-fork configuration setting. This is not the best performant configuration for Apache. Out of the box Apache comes compiled in its safest form, from the processing mode perspective since the pre-fork setting will open a process for each connection, so that process will run independently from others; as well as from the legacy perspective because old perl or shell scripts sill surely run.

However it is quite possible you want to squeeze the maximum of your web server as well as from your hardware. So if you happen to have a threading capable CPU (any modern hardware does this) and your operating system has some sort of support for thread-safe polling (kqueue or epoll), just change the configuration of your Apache and use the mpm_event module instead of the pre-fork one.

This is a how to set Apache’s MPM Event and PHP-FPM on FreeBSD, so you do not only get the best of Apache but you configure your FAMP stack to run PHP applications with it. In this article we will basically recreate that FAMP stack (similar to the LAMP) but with a faster configuration.

If you find the articles in Adminbyaccident.com useful to you, please consider making a donation.

You may be confused by the threading capability of your CPU. Let’s check that out first and forget about it. Almost every CPU on the AMD64 world (that includes Intel’s x86-64) since 2005 has that capability. But there is a command you can use to clear the doubt. Why this? Read Apache’s official documentation on the matter or skip this first part entirely.

root@Event:~ # dmesg | grep 'SMP'

FreeBSD/SMP: Multiprocessor System Detected: 4 CPUs

FreeBSD/SMP: 1 package(s) x 4 core(s)

SMP: AP CPU #3 Launched!

SMP: AP CPU #1 Launched!

SMP: AP CPU #2 Launched!

root@Event:~ #

This CPU in use here has got SMP (symmetrical multi-processing) and it’s got 4 cores. Chances are this CPU is threading capable. Let’s see if the CPU is Hyper-Threading capble.

[root@Event ~]$ dmesg | grep 'HTT'

Features=0xbfebfbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,

SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CLFLUSH,DTS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE>

Features=0xbfebfbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,

PAT,PSE36,CLFLUSH,DTS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE>

[root@Event ~]$

Yes, indeed. But just in case you want it to see before your eyes. Let’s grab a process ID and see if there are threads into that process. That would be the deffinitive indicator of a threading capable CPU. If you have an Apache already running it’s as easy as find the number of httpd processes running and then looking for threads.

We will first look for one process.

root@Event:~ # ps aux | grep httpd

root 7795 0,0 0,0 11124 5852 - SsJ 17:44 0:00,06 /usr/local/sbin/httpd -DNOHTTPACCEPT

www 7796 0,0 0,0 18680 7060 - IJ 17:44 0:00,00 /usr/local/sbin/httpd -DNOHTTPACCEPT

www 7797 0,0 0,0 16632 6612 - IJ 17:44 0:00,00 /usr/local/sbin/httpd -DNOHTTPACCEPT

www 7798 0,0 0,0 16632 6640 - IJ 17:44 0:00,00 /usr/local/sbin/httpd -DNOHTTPACCEPT

root 7956 0,0 0,0 6740 2596 0 S+J 18:20 0:00,00 grep httpd

root@Event:~ #

Let’s now look for threads inside one of those processes. Let’s grab the ID 7797.

root@Event:~ # procstat -t 7797

PID TID COMM TDNAME CPU PRI STATE WCHAN

7797 100595 httpd - -1 152 sleep piperd

7797 100719 httpd - -1 152 sleep uwait

7797 100722 httpd - -1 152 sleep uwait

7797 100767 httpd - -1 152 sleep uwait

7797 100783 httpd - -1 152 sleep uwait

7797 100805 httpd - -1 152 sleep uwait

7797 100809 httpd - -1 152 sleep uwait

7797 100814 httpd - -1 152 sleep uwait

7797 100817 httpd - -1 152 sleep uwait

7797 100819 httpd - -1 152 sleep uwait

7797 100827 httpd - -1 152 sleep uwait

7797 100898 httpd - -1 152 sleep uwait

7797 100901 httpd - -1 152 sleep uwait

7797 100905 httpd - -1 152 sleep uwait

7797 100957 httpd - -1 152 sleep uwait

7797 101074 httpd - -1 152 sleep uwait

7797 101094 httpd - -1 152 sleep uwait

7797 101095 httpd - -1 152 sleep uwait

7797 101099 httpd - -1 152 sleep uwait

7797 101203 httpd - -1 152 sleep uwait

7797 101229 httpd - -1 152 sleep uwait

7797 101548 httpd - -1 152 sleep uwait

7797 101668 httpd - -1 152 sleep uwait

7797 101692 httpd - -1 152 sleep uwait

7797 101705 httpd - -1 152 sleep uwait

7797 101707 httpd - -1 152 sleep uwait

7797 101709 httpd - -1 152 sleep kqread

root@Event:~ #

The TID column are all the threads associated with the process 7797. So as you can see this is a threading capable CPU. Again, almost every CPU from 2005 onwards is capable of this.

Now the very fundamental CPU capabilities that make the mpm_event module profitable have been confirmed on our hardware let’s really go for this how to set Apache’s MPM Event and PHP-FPM on FreeBSD.

Again, since I am a fan of FreeBSD Jails I will demonstrate this configuration running on a Jail. As those already familiar with this kind of OS virtualization technology know, the same configuration applies to a bare-metal, one OS instance installation, the only difference will be in creating the jail and loggin in to it. The rest remains exactly the same.

Let’s create a Jail.

[Free@Catalonia ~]$ sudo iocage create -r 11.2-RELEASE -n Event ip4_addr="em0| 192.168.1.180/24"

Password:

Event successfully created!

[Free@Catalonia~]$

Let’s now fire it up and login to it.

[Free@Catalonia ~]$ sudo iocage start Event

* Starting Event

+ Started OK

+ Using devfs_ruleset: 5

+ Starting services OK

+ Executing poststart OK

[Free@Catalonia ~]$ sudo iocage console Event

FreeBSD 11.2-RELEASE-p9 (GENERIC) #0: Tue Feb 5 15:30:36 UTC 2019

Welcome to FreeBSD!

Release Notes, Errata: https://www.FreeBSD.org/releases/

Security Advisories: https://www.FreeBSD.org/security/

FreeBSD Handbook: https://www.FreeBSD.org/handbook/

FreeBSD FAQ: https://www.FreeBSD.org/faq/

Questions List: https://lists.FreeBSD.org/mailman/listinfo/freebsd-questions/

FreeBSD Forums: https://forums.FreeBSD.org/

Documents installed with the system are in the /usr/local/share/doc/freebsd/

directory, or can be installed later with: pkg install en-freebsd-doc

For other languages, replace "en" with a language code like de or fr.

Show the version of FreeBSD installed: freebsd-version ; uname -a

Please include that output and any error messages when posting questions.

Introduction to manual pages: man man

FreeBSD directory layout: man hier

Edit /etc/motd to change this login announcement.

root@Event:~ #

If you are interested on checking FreeBSD Jails out, you can read this other guide and make your own testing.

From here on, you can follow the very same steps if you are not using a Jail and you are using a single OS instance, be your server at home, a VM on your favourite cloud provider, etc.

Let’s install the first piece, the Apache HTTP server.

root@Event:~ # pkg install apache24

Updating FreeBSD repository catalogue...

pkg: Repository FreeBSD load error: access repo file(/var/db/pkg/repo-FreeBSD.sqlite) failed: No such file or directory

[Event] Fetching meta.txz: 100% 944 B 0.9kB/s 00:01

[Event] Fetching packagesite.txz: 100% 6 MiB 556.9kB/s 00:12

Processing entries: 100%

FreeBSD repository update completed. 32026 packages processed.

All repositories are up to date.

Updating database digests format: 100%

The following 12 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:

apache24: 2.4.38

libnghttp2: 1.37.0

libxml2: 2.9.8

expat: 2.2.6_1

perl5: 5.28.1_1

pcre: 8.43

apr: 1.6.5.1.6.1_1

gdbm: 1.18.1

indexinfo: 0.3.1

readline: 7.0.5

gettext-runtime: 0.19.8.1_2

db5: 5.3.28_7

Number of packages to be installed: 12

The process will require 151 MiB more space.

35 MiB to be downloaded.

Proceed with this action? [y/N]: y

Some output later...

/!\ ================================================================== /!\

Message from apache24-2.4.38:

To run apache www server from startup, add apache24_enable="yes"

in your /etc/rc.conf. Extra options can be found in startup script.

Your hostname must be resolvable using at least 1 mechanism in

/etc/nsswitch.conf typically DNS or /etc/hosts or apache might

have issues starting depending on the modules you are using.

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

- apache24 default build changed from static MPM to modular MPM

- more modules are now enabled per default in the port

- icons and error pages moved from WWWDIR to DATADIR

If build with modular MPM and no MPM is activated in

httpd.conf, then mpm_prefork will be activated as default

MPM in etc/apache24/modules.d to keep compatibility with

existing php/perl/python modules!

Please compare the existing httpd.conf with httpd.conf.sample

and merge missing modules/instructions into httpd.conf!

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

root@Event:~ #

It’s been installed but it is not running yet. To make it run at boot time we need to at one line into the /etc/rc.conf file. We can do that manually with our favourite editor or just do as shown below:

root@Event:~ # sysrc apache24_enable="YES"

apache24_enable: -> YES

root@Event:~ #

The second piece of the stack is a MySQL database. I am, as many others, fan of MariaDB, developed by the main author of the former.

root@Event:~ # pkg install mariadb103-server

Updating FreeBSD repository catalogue...

FreeBSD repository is up to date.

All repositories are up to date.

The following 8 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:

mariadb103-server: 10.3.13

libedit: 3.1.20181209_2,1

unixODBC: 2.3.7

mariadb103-client: 10.3.13

libiconv: 1.14_11

galera: 25.3.25_1

boost-libs: 1.69.0_1

icu: 63.1_1,1

Number of packages to be installed: 8

The process will require 456 MiB more space.

54 MiB to be downloaded.

Proceed with this action? [y/N]: y

Some output later...

Message from mariadb103-server-10.3.13:

************************************************************************

Remember to run mysql_upgrade (with the optional --datadir=<dbdir> flag)

the first time you start the MySQL server after an upgrade from an

earlier version.

MariaDB respects hier(7) and doesn't check /etc and /etc/mysql for

my.cnf. Please move existing my.cnf files from those paths to

/usr/local/etc and /usr/local/etc/mysql.

This port does NOT include the mytop perl script, this is included in

the MariaDB tarball but the most recent version can be found in the

databases/mytop port

************************************************************************

root@Event:~ #

We will now add the start up capacity for MariaDB at boot time.

root@Event:~ # sysrc mysql_enable="YES"

mysql_enable: -> YES

root@Event:~ #

Now, let’s go install the third layer of the stack, the PHP language.

root@Event:~ # pkg install php73

Updating FreeBSD repository catalogue...

FreeBSD repository is up to date.

All repositories are up to date.

The following 3 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:

php73: 7.3.3

libargon2: 20171227_1

pcre2: 10.32

Number of packages to be installed: 3

The process will require 31 MiB more space.

5 MiB to be downloaded.

Proceed with this action? [y/N]: y

Some output later...

root@Event:~ #

Since it is very possible you need some extensions on PHP for the particular application you want to run on this server we’ll also install the related package.

root@Event:~ # pkg install php73-extensions

Updating FreeBSD repository catalogue...

FreeBSD repository is up to date.

All repositories are up to date.

The following 20 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:

php73-extensions: 1.0

php73-session: 7.3.3

php73-opcache: 7.3.3

php73-xmlwriter: 7.3.3

php73-xmlreader: 7.3.3

php73-dom: 7.3.3

php73-xml: 7.3.3

php73-simplexml: 7.3.3

php73-ctype: 7.3.3

php73-posix: 7.3.3

php73-hash: 7.3.3

php73-filter: 7.3.3

php73-tokenizer: 7.3.3

php73-json: 7.3.3

php73-sqlite3: 7.3.3

sqlite3: 3.27.1

php73-pdo_sqlite: 7.3.3

php73-pdo: 7.3.3

php73-iconv: 7.3.3

php73-phar: 7.3.3

Number of packages to be installed: 20

The process will require 8 MiB more space.

2 MiB to be downloaded.

Proceed with this action? [y/N]: y

Some output later...

root@Event:~ #

And let’s configure the whole thing to be able to work with FastCGI, the PHP-FPM (PHP-FastCGI Process Manager) part of this how to set Apache’s MPM Event and PHP-FPM on FreeBSD.

First we will set up PHP-FPM to be run at boot time.

root@Event:~ # sysrc php-fpm_enable="YES"

php_fpm_enable: fpm_enable -> fpm_enable

root@Event:~ #

Then we will edit one file to load the FastCGI module into Apache. First read the README file so you know better.

root@Event:~ # cat /usr/local/etc/apache24/modules.d/README_modules.d

# ===================================================

# Directory for third party module config files.

#

# Modules can be disabled by adding a '#' in front

# of the "LoadModule" line e.g. "#LoadModule"

#

# Files are automatically included if the name

# begins with a three digit number followed by '_'

# and ending in '.conf' e.g. '080_mod_php.conf'

#

# Maintainers can also include instructions how to

# use the module (instead pkg-message).

#

root@Event:~ #

Let’s add the file.

root@Event:~ # vi /usr/local/etc/apache24/modules.d/030_php-fpm.conf

This is what we're going to put into that file:

<IfModule proxy_fcgi_module>

<IfModule dir_module>

DirectoryIndex index.php

</IfModule>

<FilesMatch "\.(php|phtml|inc)$">

SetHandler "proxy:fcgi://127.0.0.1:9000"

</FilesMatch>

</IfModule>

root@Event:~ #

Now we do enable the FastCGI module in the main Apache HTTP configuration file. We look for its entry:

root@Event:~ # cat /usr/local/etc/apache24/httpd.conf | nl -ba | egrep 'fcgi'

82 #LoadModule authnz_fcgi_module libexec/apache24/mod_authnz_fcgi.so

133 #LoadModule proxy_fcgi_module libexec/apache24/mod_proxy_fcgi.so

root@Event:~ #

We now edit Line 133 and remove the # sign at the beginning of the line.

root@Event:~ # vi +133 /usr/local/etc/apache24/httpd.conf

Before:

#LoadModule proxy_ftp_module libexec/apache24/mod_proxy_ftp.so

#LoadModule proxy_http_module libexec/apache24/mod_proxy_http.so

#LoadModule proxy_fcgi_module libexec/apache24/mod_proxy_fcgi.so

#LoadModule proxy_scgi_module libexec/apache24/mod_proxy_scgi.so

#LoadModule proxy_uwsgi_module libexec/apache24/mod_proxy_uwsgi.so

After:

#LoadModule proxy_ftp_module libexec/apache24/mod_proxy_ftp.so

#LoadModule proxy_http_module libexec/apache24/mod_proxy_http.so

LoadModule proxy_fcgi_module libexec/apache24/mod_proxy_fcgi.so

#LoadModule proxy_scgi_module libexec/apache24/mod_proxy_scgi.so

#LoadModule proxy_uwsgi_module libexec/apache24/mod_proxy_uwsgi.so

We do also edit line 129 in order to load the proxy_module:

root@Event:~ # cat /usr/local/etc/apache24/httpd.conf | nl -ba | egrep 'proxy_module'

129 #LoadModule proxy_module libexec/apache24/mod_proxy.so

root@Event:~ #

root@Event:~ # vi +129 /usr/local/etc/apache24/httpd.conf

Before:

#LoadModule remoteip_module libexec/apache24/mod_remoteip.so

#LoadModule proxy_module libexec/apache24/mod_proxy.so

#LoadModule proxy_connect_module libexec/apache24/mod_proxy_connect.so

After:

#LoadModule remoteip_module libexec/apache24/mod_remoteip.so

LoadModule proxy_module libexec/apache24/mod_proxy.so

#LoadModule proxy_connect_module libexec/apache24/mod_proxy_connect.so

Last, but not least, after having enabled the PHP-FPM bit of this configuration, we will now swith the MPM configuration from the ‘pre-fork’ setting to the ‘event’ one.

Let’s first find out the exact location of these directives in the main Apache’s HTTP config file:

root@Event:~ # cat /usr/local/etc/apache24/httpd.conf | nl -ba | egrep 'mpm'

66 #LoadModule mpm_event_module libexec/apache24/mod_mpm_event.so

67 LoadModule mpm_prefork_module libexec/apache24/mod_mpm_prefork.so

68 #LoadModule mpm_worker_module libexec/apache24/mod_mpm_worker.so

164 <IfModule !mpm_prefork_module>

167 <IfModule mpm_prefork_module>

490 #Include etc/apache24/extra/httpd-mpm.conf

root@Event:~ #

As we can see in line 67 we find the mpm_prefork activated. We want to change this to event.

root@Event:~ # vi +66 /usr/local/etc/apache24/httpd.conf

#

# Example:

# LoadModule foo_module modules/mod_foo.so

#

#LoadModule mpm_event_module libexec/apache24/mod_mpm_event.so

LoadModule mpm_prefork_module libexec/apache24/mod_mpm_prefork.so

#LoadModule mpm_worker_module libexec/apache24/mod_mpm_worker.so

LoadModule authn_file_module libexec/apache24/mod_authn_file.so

#LoadModule authn_dbm_module libexec/apache24/mod_authn_dbm.so

Result should be like:

LoadModule mpm_event_module libexec/apache24/mod_mpm_event.so

#LoadModule mpm_prefork_module libexec/apache24/mod_mpm_prefork.so

#LoadModule mpm_worker_module libexec/apache24/mod_mpm_worker.so

Let’s test our configuration before firing things up.

root@Event:~ # apachectl configtest

Performing sanity check on apache24 configuration:

Syntax OK

root@Event:~ #

It is possible you see some ‘silly’ error showing up like:

root@Event:~ # apachectl configtest

Performing sanity check on apache24 configuration:

AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 192.168.1.180. Set the 'ServerName' directive globally to suppress this message

Syntax OK

root@Event:~ #

As you can read the syntax is ok and Apache will start up correctly. If you want to get rid of this ‘silly’ error just do as follows:

Look for the ‘SeverName’ directive in the main configuration file.

root@Event:~ # cat /usr/local/etc/apache24/httpd.conf | nl -ba | egrep 'ServerName'

219 # ServerName gives the name and port that the server uses to identify itself.

225 #ServerName www.example.com:80

root@Event:~ # vi +225 /usr/local/etc/apache24/httpd.conf

Edit the file so it doesn’t bother again because it is correctly configured. Just replace the www.example.com with the website name or the IP you’re serving the content from.

root@Event:~ # vi +225 /usr/local/etc/apache24/httpd.conf

219 # ServerName gives the name and port that the server uses to identify itself.

225 ServerName 192.168.1.180:80

root@Event:~ #

It’s time to fire up things. First we’ll start Apache, then MariaDB and last but not least PHP-FPM.

root@Event:~ # service apache24 start

Performing sanity check on apache24 configuration:

Syntax OK

Starting apache24.

root@Event:~ #

root@Event:~ # service mysql-server start

Starting mysql.

root@Event:~ #

root@Event:~ # service php-fpm start

Performing sanity check on php-fpm configuration:

[24-Mar-2019 19:05:38] NOTICE: configuration file /usr/local/etc/php-fpm.conf test is successful

Starting php_fpm.

root@Event:~ #

No error messages should appear. Read carefully if any appear. Now, since everything is ok, let’s look if Apache is really running with the mpm_event module enabled.

root@Event:~ # apachectl -M | grep event

mpm_event_module (shared)

root@Event:~ #

And yes it is.

To now check if PHP is really running on PHP-FPM we will make a little test with a very small PHP script.

We’ll add a file called ‘info.php’ in the Apache’s content path, where ‘<?php phpinfo(); ?>’ is the content of the file.

root@Event:~ # vi /usr/local/www/apache24/data/info.php

<?php phpinfo(); ?>

root@Event:~ #

We’ll now visit our website through a web browser.

By visiting http://192.168.1.180/info.php I get this result, where the important line to read is ‘Server API’.

As you can see PHP with FPM capability is now enabled, along with the MPM Event this concludes this How to set Apache’s MPM Event and PHP-FPM on FreeBSD.

Now, if you are doing this over the internet, I recommend you first enable SSL/TLS on your Apache, and then do this configuration here.

This same setup can be built in DigitalOcean. Use this link to get 100 $ credit at DOcean and support Adminbyaccident.com hosting costs.

Filed Under: FreeBSD, How To's

Recent Posts

  • How to install Mate on FreeBSD 12/13
  • How to install Nessus 10 on FreeBSD 12
  • How to enable TLS traffic from the origin server on Cloudflare Argo Tunnel
  • How to use Cloudflare’s Argo Tunnel service to publish a website on FreeBSD 12/13
  • How to setup MariaDB master-slave replication on FreeBSD
  • How to upload a FreeBSD custom image on DigitalOcean
  • How to install Drupal 9 on FreeBSD 13.0
  • How to manage site visitors based on IP Geolocation
  • How to enable Geolocation in AWStats on FreeBSD 13.0
  • How to install AWStats on FreeBSD 13.0
  • How to configure Modsecurity 3 for WordPress on FreeBSD
  • How to configure Apache HTTP with a TLS reverse proxy backend on FreeBSD
  • How to detect a WAF – Web Application Firewall
  • How to install Matomo 4 on FreeBSD
  • How to test SSL/TLS configurations
  • How to configure Apache HTTP as a reverse proxy on FreeBSD
  • How to install Nextcloud on FreeBSD 12
  • How to install ModSecurity 3 on FreeBSD
  • How to replace a disk on a ZFS mirror pool
  • How to install Webmin on FreeBSD 12

Archives

  • February 2023
  • January 2023
  • December 2022
  • April 2022
  • March 2022
  • October 2021
  • September 2021
  • June 2021
  • May 2021
  • April 2021
  • March 2021
  • February 2021
  • January 2021
  • December 2020
  • July 2020
  • June 2020
  • May 2020
  • April 2020
  • March 2020
  • February 2020
  • January 2020
  • December 2019
  • November 2019
  • October 2019
  • August 2019
  • July 2019
  • June 2019
  • May 2019
  • April 2019
  • March 2019
  • February 2019
  • January 2019
  • September 2018
  • June 2018
  • May 2018
  • April 2018
  • February 2018
  • January 2018
  • November 2017
  • April 2017

RSS Admin… by accident!

  • How to install Mate on FreeBSD 12/13
  • How to install Nessus 10 on FreeBSD 12
  • How to enable TLS traffic from the origin server on Cloudflare Argo Tunnel
  • How to use Cloudflare’s Argo Tunnel service to publish a website on FreeBSD 12/13
  • How to setup MariaDB master-slave replication on FreeBSD
  • How to upload a FreeBSD custom image on DigitalOcean
  • How to install Drupal 9 on FreeBSD 13.0
  • How to manage site visitors based on IP Geolocation
  • How to enable Geolocation in AWStats on FreeBSD 13.0
  • How to install AWStats on FreeBSD 13.0

Copyright © 2023 · Magazine Pro Theme on Genesis Framework · WordPress · Log in