Get Rewarded! We will reward you with up to €50 credit on your account for every tutorial that you write and we publish!

Install a FEMP Stack on FreeBSD

profile picture
Author
youiopmop
Published
2024-08-28
Time to read
8 minutes reading time

Introduction

A FEMP Stack (FreeBSD, Nginx, MySQL, PHP) is a combination of FOSS software that can be used together in order to host dynamic websites and Content Management Systems such as Wordpress or Joomla.

This guide will help with the installation and configuration of a FEMP stack on FreeBSD 14.

Prerequisites

  • A server with FreeBSD
  • Access to the root user or a user with sudo permissions

Step 1 - Updating FreeBSD

By default, FreeBSD does not come with the pkg package manager, but comes with a tool to bootstrap it. If FreeBSD asks to install it, answer 'Yes'.

It is best to update the system beforehand to ensure you are getting the latest packages when installing the FEMP stack. You can do this by running the following command:

sudo pkg update ; sudo pkg upgrade

This will update the repositories of pkg, and then upgrade any installed packages that you may have.

Step 2 - Installing Nginx

To install Nginx, the web server we are using for this tutorial, use the following command:

sudo pkg install nginx
nginx -v

Before we can start nginx to test that it is working, we need to enable it to start on boot.

You can do this by appending nginx_enable="YES" to the end of /etc/rc.conf.

echo 'nginx_enable="YES"' | sudo tee -a /etc/rc.conf
sudo service nginx start
sudo service nginx status

Test that it is working by going to your IP address in a web browser. You can check your server's IP address by running curl -4 https://ip.hetzner.com, or by checking your control panel.

http://203.0.113.1/

You should see something like this:

Welcome To Nginx!

Step 3 - Installing PHP

Next, we need to install and configure PHP, which we'll be using to process PHP requests from nginx.

  • Check which versions are available:

    You can use either awk or grep.

    sudo pkg search ^php[0-9] | awk -F'-' 'NF==2 {print $0}'
    sudo pkg search ^php[0-9] | grep -E '^php[0-9]+-[0-9]+\.[0-9]+\.[0-9]+'
  • Install the latest version and some modules:

    sudo pkg install php83 php83-mysqli php83-curl php83-gd php83-intl php83-mbstring php83-xml php83-zip
    php -v
  • Like before, we need to enable it to start on boot before we can start the service.

    echo 'php_fpm_enable="YES"' | sudo tee -a /etc/rc.conf

Before we can start it, we need to make a few changes to the configuration file /usr/local/etc/php-fpm.d/www.conf

cd /usr/local/etc/
sudo vi php-fpm.d/www.conf

Look for the line:

listen = 127.0.0.1:9000

Replace it with the following, so that PHP listens under an unix socket:

listen = /var/run/php-fpm.sock

Further down in the file, look for these lines:

;listen.owner = www
;listen.group = www
;listen.mode = 0660

Uncomment them to change the unix socket owner to be the same as the nginx user:

listen.owner = www
listen.group = www
listen.mode = 0660

After you have completed that, save and close the file.

You need to create a php.ini file. You can use the example file php.ini-production with a slight modification for security:

Assuming you are still in /usr/local/etc/:

sudo cp php.ini-production php.ini
sudo sed -i -E 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/g' php.ini

Then finally, start the PHP service.

sudo service php-fpm start
sudo service php-fpm status

Step 3.1 - Configuring Nginx to use PHP

Nginx and PHP are both enabled now, however we need to configure Nginx to be aware of PHP, and to use it to process .php pages.

Open the file /usr/local/etc/nginx/nginx.conf in a text editor:

sudo vi /usr/local/etc/nginx/nginx.conf

Find the following in the file (commented out parts are removed):

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    server {
        listen       80;
        server_name  localhost;

        location / {
            root   /usr/local/www/nginx;
            index  index.html index.htm;
        }

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

The following changes need to be made to the nginx.conf file:

  • Replace localhost under server_name with your server's domain or IP address.
  • Remove the location / block.
  • Add index.php under index.
  • Edit nginx root directory to /var/www/html/.
  • Configure nginx for PHP processing.

Your nginx.conf file should look something like this:

    server {
        listen       80;
        server_name  example.com;
        root         /var/www/html;
        index        index.php index.html index.htm;

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

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

If your server uses IPv6, add the following line under listen 80;

listen [::]:80;

Then finally, create the nginx root directory, symlink the default nginx index.html page, and restart nginx.

sudo mkdir -p /var/www/html/
sudo ln -s /usr/local/www/nginx-dist/index.html /var/www/html/
sudo nginx -t
sudo service nginx restart
sudo service nginx status

Going to your server's domain or IP address, should still return the Welcome to nginx! page from before.

To test if PHP is working, create a file under /var/www/html/phpinfo.php with the following content:

<?php phpinfo(); ?>

Then, visit the test page you created at your server's IP address/domain.

http://example.com/phpinfo.php

It should return a page like this:

PHP Info

It is best to delete the file afterwards for security, as it can expose information about your PHP install to anyone.

sudo rm /var/www/html/phpinfo.php

Step 4 - Installing MySQL (MariaDB)

Now that we have Nginx and PHP setup and working together, the only thing left that we need to install and configure is MySQL.

  • Check which versions are available:

    We'll be using a community maintained drop-in replacement to MySQL, MariaDB; which is fully compatible with applications targeting MySQL.

    sudo pkg search '^mariadb[0-9]+-server' | grep -E '^mariadb[0-9]+-server-[0-9]+\.[0-9]+\.[0-9]+'
    sudo pkg search '^mariadb[0-9]+-client' | grep -E '^mariadb[0-9]+-client-[0-9]+\.[0-9]+\.[0-9]+'
  • Install the latest version:

    sudo pkg install mariadb114-server mariadb114-client
    sudo pkg info -x mariadb114-server
    sudo pkg info -x mariadb114-client
  • Like before, we need to enable the service to start on boot before we can start the service.

    echo 'mysql_enable="YES"' | sudo tee -a /etc/rc.conf
  • Add a configuration file

    sudo cp /usr/local/etc/mysql/my.cnf.sample /usr/local/etc/mysql/my.cnf
  • Start the service

    sudo service mysql-server start
    sudo service mysql-server status

Next, we need to secure the MariaDB installation.

sudo mysql_secure_installation
Enter current password for root (enter for none):

Since we are setting up MariaDB for the first time, the root account does not have a password, so just press the "ENTER" key here.

Enable unix_socket authentication? [Y/n]

Like before, press the "ENTER" key to answer yes to use unix_socket authentication.

Set root password? [Y/n]

Press the "ENTER" key here to answer yes, and then enter a secure password for your MariaDB root user.

Remove anonymous users? [Y/n]
Disallow root login remotely? [Y/n]
Remove test database and access to it? [Y/n]
Reload privilege tables now? [Y/n]

The last few questions you can just use the defaults by pressing the "ENTER" key, as they are sane defaults that the installer uses.

MariaDB already uses the changes we made, so there is no need to restart it.

Conclusion

Congrats! You should now have a fully working FEMP stack on your FreeBSD server, using Nginx to host webpages, PHP to process dynamic web pages, and using MySQL (MariaDB) to store data. These together are the basis for many different web apps, some examples include: Wordpress, Gitea, Joomla, and many more.

License: MIT
Want to contribute?

Get Rewarded: Get up to €50 in credit! Be a part of the community and contribute. Do it for the money. Do it for the bragging rights. And do it to teach others!

Report Issue

Discover our

Dedicated Servers

Configure your dream server. Top performance with an excellent connection at an unbeatable price!

Want to contribute?

Get Rewarded: Get up to €50 credit on your account for every tutorial you write and we publish!

Find out more