Aumont.fr

Nginx / PHP with FreeBSD.

4 min read.
Nov 2024
  1. Home
  2. › Posts
  3. › Nginx / PHP with FreeBSD.

How to install Nginx + php8.x + plugins on Freebsd #

FreeBSD with jails are perfects for hosting HTTPS services.

Tested with FreeBSD 13.x / 14.x and PHP8.3 but should be exactly the same how to with another version.

Create a new jail with bastille #


Let's use the classic configuration with bastille0 setting , consult Bastille Documentation bastille documentation for specifics setup.

bastille create nginx-php-jail
bastille console nginx-php-jail

Install the usual stuff #


Note : with FreeBSD php packet are named like this , php8X-extension . So it will be same on php83 on the futur.

pkg install nginx vim
pkg install php82 php82-curl php82-dom php82-exif php82-mbstring php82-xm php82-zip \
php82-session php82-xml-8.2.7 php82-xml-8.2.7 php82-mysqli

# Plugin for perfs : 
pkg install php82-pecl-APCu php82-opcache

Configure PHP #


Copy the php.ini-production file to a .ini file.

# cp -p /usr/local/etc/php.ini-production /usr/local/etc/php.ini

Configure php-fpm. #

99% of the config within the php-fpm.d/www.conf is commented by default and only needed to for specifics settings, you can create your own file with this.

# grep -v -e '^;' /usr/local/etc/php-fpm.d/www.conf | cat -s
[www-blog]
user = www
group = www
listen = /var/run/php-fpm/php-fpm.sock
listen.owner = www
listen.group = www
listen.mode = 0660
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3

Create the directory for the php socket

# mkdir /var/run/php-fpm/
# chown www:www /var/run/php-fpm/

Enable Jit + Opcache #

There are 3 "famous" performances addon for PHP : APCu, Opcache and JIT.
To enable opcache and Jit compiler. Add the following lines to this file.

# cat /usr/local/etc/php/ext-10-opcache.ini
zend_extension=opcache.so
opcache.enable=1
opcache.jit=1255
opcache.jit_buffer_size=100M

On Latest PHP Version APCu is automatically enabled you juste have to install the package.

Same for JIT on php8.3 it is now upstream.

Nginx minimal config #


Not a production configuration.
Missing a lot of header security, https, upstream ... Just for test.

user  www;
worker_processes 2;

events {
worker_connections 1024;
}

http {
include mime.types;
default_type application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;

sendfile on;
keepalive_timeout 65;
#gzip on;

server {
listen 44000;
server_name blog-test.fr;
root /usr/local/www/my-blog;
index index.php index.html;

#charset koi8-r;

location / {
try_files $uri $uri/ /index.php?q=$uri&$args;
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/local/www/nginx-dist;
}

location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $request_filename;
include fastcgi_params;
}

}
}

Create the log directory #

# mkdir /var/log/nginx
# chown www:www /var/log/nginx/

Don't forget to rotate the logs
Add this in newsyslog /etc/newsyslog.conf

/var/log/nginx/access.log                       600  10    500  $W0D23  J  /var/run/nginx.pid
/var/log/nginx/error.log                        600  10    100  $W0D23  J  /var/run/nginx.pid

Create a php.info file and check that all is working fine. #

mkdir /usr/local/www/my-blog
chown www:www /usr/local/www/my-blog

Then add a file index.php filled with

<?php phpinfo(); ?>

Enable the services and reboot the jail from your host. #

# sysrc nginx_enable=YES
# sysrc php_fpm_enable="YES"

Reboot the jail #

Leave the jail and from the host :

bastille restart jail-blog

Test the url through the port defined on the nginx config. #

Check that Opcache / Jit / APCu are correctly enabled.

#FreeBSD #jails #infrastructure

Mathieu Aumont - 2026

Posts | Tags | About

Last build : Mar 2026