Use OpenBSD to serve PHP applications

by on under tech
3 minute read

OpenBSD makes a very solid - if not the most solid - platform for hosting websites and webapplications. This goes for PHP too. The defaults are somewhat conservative and can be tweaked to offer a more performing setup. This guide should at the very least offer some insights in these tweaks.

PHP

The PHP scripts and applications I manage run either on PHP 7.2 or PHP 7.3. Previously, PHP 7.0 offered a massive performance gain over PHP 5.6; which both have reached the End of Life status. I haven’t personally experienced any breakage between the PHP 7.x series. Though there can be some breaking when count() is not properly implemented. As a database backend, I vastly prefer PostgreSQL over MySQL/MariaDB/Percona, because of stricter SQL standardization and increased performance with complex queries (have experienced this first-hand - but that is a completely different topic.

Edit in /etc/php-$VER.ini:

[PHP]
expose_php = Off

max_execution_time = 600

memory_limit = 512M

disable_functions = show_source, system, shell_exec, passthru, exec, popen, proc_open

[opcache]
opcache.enable=1

opcache.enable_cli=1

opcache.memory_consumption=128

opcache.interned_strings_buffer=8

opcache.max_accelerated_files=10000

opcache.max_wasted_percentage=5

opcache.use_cwd=1

opcache.validate_timestamps=1

opcache.revalidate_freq=1

opcache.revalidate_path=0

Edit in /etc/php-fpm.conf:

[www]
user = www
group = www

listen = 127.0.0.1:9000

listen.allowed_clients = 127.0.0.1

chroot = /var/www

Softupdates

Softdep mounts the file system using soft dependencies. Instead of metadata being written immediately, it is written in an ordered fashion to keep the on-disk state of the file system consistent. This results in significant speedups for file create/delete operations. Noatime does not update atime on files in the system unless the mtime or ctime is being changed as well. This option is useful for laptops and news servers where one does not want the extra disk activity associated with updating the atime.

Setting these two ‘bits’ is fairly easy with sed:

sed -i 's/rw/rw,softdep,noatime/g' /etc/fstab

Sysctl

Sysctl can be used to increase the performance of the system itself and the network stack. The manpages offer further reading. Create /etc/sysctl.conf and add:

###
# System
###
ddb.panic=0                      # Do not enter ddb console on kernel panic, reboot if possible

###
# Kernel
###
kern.bufcachepercent=90          # Allow the kernel to use up to 90% of the RAM for cache (default 10%)
kern.shminfo.shmall=536870912    # Shared memory limits
kern.shminfo.shmmax=2147483647   # Shared memory limits
kern.shminfo.shmmni=1024         # Shared memory limits
kern.shminfo.shmseg=1024         # Semaphores
kern.seminfo.semmns=4096         # Semaphores
kern.seminfo.semmni=1024         # Semaphores
kern.maxproc=32768               # Raise the maximum number of simultaneous processes the system will allow
kern.maxfiles=65535              # Raise the maximum number of simultanous open files the system will allow
kern.maxvnodes=262144            # Raise the maximum available vnodes available to the system
kern.somaxconn=2048              # Raise the number of allowed half-open connections

###
# Network
###
net.inet.ip.ifq.maxlen=512       # Maximum allowed output queue length (256*number of physical interfaces)
net.inet.ip.mtudisc=0            # TCP MTU (Maximum Transmission Unit) discovery off since our mss is small enough
net.inet.tcp.rfc3390=1           # Enable RFC3390 TCP window increasing so larger CWND can take affect
net.inet.tcp.mssdflt=1440        # Maximum segment size (1440 from scrub pf.conf match statement)
net.inet.udp.recvspace=131072    # Increase UDP "receive" buffer size. Good for 200Mbit without packet drop.
net.inet.udp.sendspace=131072    # Increase UDP "send" buffer size. Good for 200Mbit without packet drop.

Login.conf

Not the best practice; normally I just change the default group - the limites that are enforced upon all users. Especially the datasize, maxproc and openfiles values are critical. Edit these values in /etc/login.conf:

default:\
        :path=/usr/bin /bin /usr/sbin /sbin /usr/X11R6/bin /usr/local/bin /usr/local/sbin:\
        :umask=022:\
        :datasize-max=8192M:\
        :datasize-cur=8192M:\
        :maxproc-max=1024:\
        :maxproc-cur=1024:\
        :openfiles-max=16384:\
        :openfiles-cur=16384:\
        :stacksize-cur=4M:\
        :localcipher=blowfish,a:\
        :tc=auth-defaults:\
        :tc=auth-ftp-defaults:

Credits

The knowledge for these tweakers is mostly gathered from Calomel and C0ffee. Furthermore, Peter Hansteen’s tinkering and pondering have proven to be invalueable as a resource.

Last but not least, the focus required to write this article was powered by Luca Turilli’s Rhapsody - Ascending To Infinity.

openbsd, php, performance