Nauris
LAMP Setup

Install LAMP Stack on FreeBSD

Install Apache, MySQL 8.4, PHP 8, PHP-FPM, and phpMyAdmin on FreeBSD with PF firewall rules, Apache virtual hosts, and a dedicated PHP-FPM pool.

This guide walks through a full LAMP stack setup on FreeBSD using Apache, MySQL 8.4, PHP 8, PHP-FPM, and phpMyAdmin.

By the end, you will have:

  • a sudo-enabled admin user
  • an updated FreeBSD base system and packages
  • Cloudflare DNS configured
  • SSH on a custom port
  • PF firewall rules in place
  • Apache, MySQL, PHP, and phpMyAdmin installed
  • a dedicated PHP-FPM pool and virtual host for a site

Create a New User

Skip this step if you already have a working sudo user.

Create a new user:

adduser

During the prompts:

  • choose a username such as newuser
  • add the user to the wheel group
  • set a password

Verify the user is in wheel:

id newuser

You should see wheel in the group list.

Install sudo if needed:

pkg install sudo

Allow the wheel group to use sudo:

sudo sed -i '' 's/^# %wheel ALL=(ALL:ALL) ALL/%wheel ALL=(ALL:ALL) ALL/' /usr/local/etc/sudoers
cat /usr/local/etc/sudoers | grep '%wheel ALL=(ALL:ALL) ALL'

Switch to the new user and verify sudo works:

su - newuser
sudo whoami

If the command returns root, sudo is configured correctly.

Upgrade FreeBSD

Check the currently installed version:

uname -ar

Update the base system:

sudo freebsd-update fetch
sudo freebsd-update install
sudo freebsd-update upgrade -r 14.2-RELEASE

Replace 14.2-RELEASE with the latest release available from https://www.freebsd.org/.

Update Packages

Update repository metadata and installed packages:

sudo pkg update && sudo pkg upgrade

Change DNS to Cloudflare

This step is optional but recommended.

Back up the current resolver config:

sudo cp /etc/resolv.conf /etc/resolv.conf.bak

Edit the resolver file:

sudo vim /etc/resolv.conf

Use Cloudflare DNS:

nameserver 1.1.1.1
nameserver 1.0.0.1
nameserver 2606:4700:4700::1111
nameserver 2606:4700:4700::1001

Change the SSH Port

This step is optional but recommended.

Edit the SSH daemon config:

sudo vim /etc/ssh/sshd_config

Set a custom port and disable root login:

Port 54445
PermitRootLogin no

Restart SSH:

sudo service sshd restart

Verify SSH is listening on the new port:

sudo sockstat -4 -6 | grep sshd

Enable the PF Firewall

This step is optional but recommended.

Edit the PF config:

sudo vim /etc/pf.conf

Use rules like these:

# Macros
ext_if = "eth0"

# Options
set skip on lo0

# Default deny all
block all

# Allow SSH
pass in on $ext_if proto tcp to port 54445

# Allow HTTP and HTTPS
pass in on $ext_if proto tcp to port 80
pass in on $ext_if proto tcp to port 443

# Allow outgoing traffic
pass out on $ext_if

# Allow MySQL only on localhost
pass in on lo0 proto tcp from 127.0.0.1 to 127.0.0.1 port 3306

# Block external MySQL access
block in on $ext_if proto tcp to any port 3306

Check your interface name with:

ifconfig

Enable PF on boot:

sudo sysrc pf_enable="YES"
sudo sysrc pf_rules="/etc/pf.conf"
sudo sysrc pflog_enable="YES"

Start PF and verify it:

sudo service pf start
sudo pfctl -sr
sudo pfctl -si

Reconnect using the custom SSH port:

ssh user@server_ip -p 54445

Starting the firewall can drop the current SSH session. Reconnect using the custom port if needed.

Install PHP 8 and PHP-FPM

List available PHP versions:

sudo pkg search php | egrep '^php[0-9]+-[0-9]'

Install PHP 8.3 and common extensions:

sudo pkg install php83 php83-extensions php83-mysqli php83-mbstring php83-bcmath php83-zip php83-gd php83-curl php83-xml php83-exif php83-gmp

Enable and start PHP-FPM:

sudo sysrc php_fpm_enable=YES
sudo service php_fpm start

Edit the default pool config:

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

Use:

user = www
group = www

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

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

Restart PHP-FPM:

sudo service php_fpm restart

Create the main PHP config:

sudo cp /usr/local/etc/php.ini-production /usr/local/etc/php.ini

Edit php.ini:

sudo vim /usr/local/etc/php.ini

Disable commonly abused functions:

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

Enable OPcache:

[opcache]
opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.use_cwd=1
opcache.validate_timestamps=1
opcache.revalidate_freq=60
opcache.save_comments=1
opcache.file_cache=/tmp/opcache

Restart PHP-FPM again:

sudo service php_fpm restart

Install Apache

Install Apache and enable it at boot:

sudo pkg install apache24
sudo sysrc apache24_enable="YES"

Generate a self-signed SSL certificate:

sudo openssl req -x509 -newkey rsa:2048 -nodes -keyout /usr/local/etc/apache24/server.key -out /usr/local/etc/apache24/server.crt -days 3650

Set a global ServerName:

sudo sed -i '' 's/^#ServerName www\.example\.com:80/ServerName localhost/' /usr/local/etc/apache24/httpd.conf
grep 'ServerName' /usr/local/etc/apache24/httpd.conf

Enable the required modules:

sudo sed -i '' 's/^#\(LoadModule rewrite_module.*\)/\1/' /usr/local/etc/apache24/httpd.conf
sudo sed -i '' 's/^#\(LoadModule ssl_module.*\)/\1/' /usr/local/etc/apache24/httpd.conf
sudo sed -i '' 's/^#\(LoadModule proxy_fcgi_module.*\)/\1/' /usr/local/etc/apache24/httpd.conf
sudo sed -i '' 's/^#\(LoadModule headers_module.*\)/\1/' /usr/local/etc/apache24/httpd.conf
sudo sed -i '' 's/^#\(LoadModule proxy_module.*\)/\1/' /usr/local/etc/apache24/httpd.conf
sudo sed -i '' 's/^#\(LoadModule setenvif_module.*\)/\1/' /usr/local/etc/apache24/httpd.conf
sudo sed -i '' 's/^#\(LoadModule socache_shmcb_module.*\)/\1/' /usr/local/etc/apache24/httpd.conf

Enable the SSL include:

sudo sed -i '' 's/^#\(Include etc\/apache24\/extra\/httpd-ssl\.conf\)/\1/' /usr/local/etc/apache24/httpd.conf

Test and start Apache:

sudo service apache24 configtest
sudo service apache24 start
sudo service apache24 status

Confirm the default page loads:

http://server_ip

Install and Configure MySQL 8.4

Install the server and client:

sudo pkg install mysql84-server mysql84-client

Enable and start MySQL:

sudo sysrc mysql_enable=YES
sudo service mysql-server start
sudo service mysql-server status

Run the secure setup:

sudo mysql_secure_installation

Recommended answers:

  • press Enter if no root password is set yet
  • answer Y to set a root password
  • choose password validation level 1 (MEDIUM) unless you need something stricter
  • answer Y to remove anonymous users
  • answer Y to disallow remote root login
  • answer Y to remove the test database
  • answer Y to reload privilege tables

Create the MySQL config:

sudo vim /usr/local/etc/mysql/my.cnf

Use:

[mysqld]
bind-address = 127.0.0.1
innodb_buffer_pool_size = 512M
max_connections = 10

Restart MySQL:

sudo service mysql-server restart

Watch the error log if needed:

sudo tail -f /var/db/mysql/freebsd.err

Install and Configure phpMyAdmin

Search for available phpMyAdmin packages and install the variant that matches your PHP version:

sudo pkg search phpmyadmin
sudo pkg install phpMyAdmin5-php83-5.2.1_1

Create the phpMyAdmin database and control user:

sudo mysql -u root -p

Run:

CREATE DATABASE phpmyadmin;
CREATE USER 'pma'@'localhost' IDENTIFIED BY 'strong_password_here';
GRANT SELECT, INSERT, UPDATE, DELETE ON phpmyadmin.* TO 'pma'@'localhost';
FLUSH PRIVILEGES;
exit

Generate a random blowfish secret:

openssl rand -base64 24

Copy the sample config and edit it:

sudo cp /usr/local/www/phpMyAdmin/config.sample.inc.php /usr/local/www/phpMyAdmin/config.inc.php
sudo vim /usr/local/www/phpMyAdmin/config.inc.php

Set the blowfish secret:

$cfg['blowfish_secret'] = 'your_code';

Hide system databases:

$cfg['Servers'][$i]['hide_db'] = '^information_schema|mysql|phpmyadmin|performance_schema|sys$';

Set the control user:

$cfg['Servers'][$i]['controluser'] = 'pma';
$cfg['Servers'][$i]['controlpass'] = 'strong_password_here';

Enable phpMyAdmin storage tables:

$cfg['Servers'][$i]['pmadb'] = 'phpmyadmin';
$cfg['Servers'][$i]['bookmarktable'] = 'pma__bookmark';
$cfg['Servers'][$i]['relation'] = 'pma__relation';
$cfg['Servers'][$i]['table_info'] = 'pma__table_info';
$cfg['Servers'][$i]['table_coords'] = 'pma__table_coords';
$cfg['Servers'][$i]['pdf_pages'] = 'pma__pdf_pages';
$cfg['Servers'][$i]['column_info'] = 'pma__column_info';
$cfg['Servers'][$i]['history'] = 'pma__history';
$cfg['Servers'][$i]['table_uiprefs'] = 'pma__table_uiprefs';
$cfg['Servers'][$i]['tracking'] = 'pma__tracking';
$cfg['Servers'][$i]['userconfig'] = 'pma__userconfig';
$cfg['Servers'][$i]['recent'] = 'pma__recent';
$cfg['Servers'][$i]['favorite'] = 'pma__favorite';
$cfg['Servers'][$i]['users'] = 'pma__users';
$cfg['Servers'][$i]['usergroups'] = 'pma__usergroups';
$cfg['Servers'][$i]['navigationhiding'] = 'pma__navigationhiding';
$cfg['Servers'][$i]['savedsearches'] = 'pma__savedsearches';
$cfg['Servers'][$i]['central_columns'] = 'pma__central_columns';
$cfg['Servers'][$i]['designer_settings'] = 'pma__designer_settings';
$cfg['Servers'][$i]['export_templates'] = 'pma__export_templates';

Create the phpMyAdmin tables:

sudo mysql -u root -p phpmyadmin < /usr/local/www/phpMyAdmin/sql/create_tables.sql

Create an Apache basic auth password file:

sudo htpasswd -c /usr/local/etc/apache24/.htpasswd pma

Create the phpMyAdmin virtual host:

sudo vim /usr/local/etc/apache24/Includes/phpmyadmin.conf

Use:

<VirtualHost *:443>
    ServerName pma.example.com
    DocumentRoot /usr/local/www/phpMyAdmin
    ErrorLog "/var/log/phpmyadmin-error.log"
    CustomLog "/var/log/phpmyadmin-access.log" combined

    SSLEngine on
    SSLCertificateFile /usr/local/etc/apache24/server.crt
    SSLCertificateKeyFile /usr/local/etc/apache24/server.key

    <FilesMatch "\.php$">
        SetHandler "proxy:unix:/var/run/php-fpm.sock|fcgi://localhost/"
    </FilesMatch>

    <Directory /usr/local/www/phpMyAdmin/>
        AddDefaultCharset UTF-8
        DirectoryIndex index.php

        AuthType Basic
        AuthName "Restricted Access"
        AuthUserFile /usr/local/etc/apache24/.htpasswd
        Require valid-user

        Options -Indexes
    </Directory>

    <Directory /usr/local/www/phpMyAdmin/setup/>
        Require all denied
    </Directory>

    <Directory /usr/local/www/phpMyAdmin/libraries/>
        Require all denied
    </Directory>

    <Directory /usr/local/www/phpMyAdmin/templates/>
        Require all denied
    </Directory>

    <Directory /usr/local/www/phpMyAdmin/setup/lib/>
        Require all denied
    </Directory>

    <Directory /usr/local/www/phpMyAdmin/sql/>
        Require all denied
    </Directory>

    <Directory /usr/local/www/phpMyAdmin/vendor/>
        Require all denied
    </Directory>
</VirtualHost>

Test and reload Apache:

sudo service apache24 configtest
sudo service apache24 reload

Create a database and user for your application:

sudo mysql -u root -p

Run:

CREATE USER 'example_user'@'localhost' IDENTIFIED BY 'password';
CREATE DATABASE example_db;
GRANT ALL PRIVILEGES ON example_db.* TO 'example_user'@'localhost';
FLUSH PRIVILEGES;
exit

You should now be able to sign in to phpMyAdmin at https://pma.example.com.

Create a Dedicated Site User

Create a separate user for the hosted application:

sudo adduser

When prompted for password-based authentication, choose no if you only want to switch to this user through your admin account.

Prepare the web root:

sudo chmod 711 /home/dolphin
sudo mkdir -p /var/www/dolphin/example.com
sudo chmod 711 /var/www/dolphin
sudo chown root:wheel /var/www
sudo chown -R dolphin:dolphin /var/www/dolphin/example.com
sudo chmod -R 755 /var/www/dolphin/example.com

Copy and edit the PHP-FPM pool config:

sudo cp /usr/local/etc/php-fpm.d/www.conf /usr/local/etc/php-fpm.d/dolphin.conf
sudo vim /usr/local/etc/php-fpm.d/dolphin.conf

Use:

[dolphin]
user = dolphin
group = dolphin

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

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

Restart PHP-FPM:

sudo service php_fpm restart

Create the site virtual host:

sudo vim /usr/local/etc/apache24/Includes/example.com.conf

Use:

<VirtualHost *:80>
    ServerAdmin [email protected]
    ServerName example.com
    ServerAlias www.example.com

    DocumentRoot /var/www/dolphin/example.com

    <FilesMatch "\.php$">
        SetHandler "proxy:unix:/var/run/php-fpm-dolphin.sock|fcgi://localhost/"
    </FilesMatch>

    ErrorLog /var/log/example.com_error.log
    CustomLog /var/log/example.com_access.log combined

    Redirect permanent / https://example.com/
</VirtualHost>

<VirtualHost *:443>
    ServerAdmin [email protected]
    ServerName example.com
    ServerAlias www.example.com

    DocumentRoot /var/www/dolphin/example.com

    <FilesMatch "\.php$">
        SetHandler "proxy:unix:/var/run/php-fpm-dolphin.sock|fcgi://localhost/"
    </FilesMatch>

    SSLEngine on
    SSLCertificateFile /usr/local/etc/apache24/server.crt
    SSLCertificateKeyFile /usr/local/etc/apache24/server.key

    ErrorLog /var/log/example.com_ssl_error.log
    CustomLog /var/log/example.com_ssl_access.log combined

    <Directory /var/www/dolphin/example.com>
        AddDefaultCharset UTF-8
        DirectoryIndex index.php
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

Test and reload Apache:

sudo service apache24 configtest
sudo service apache24 reload

Install WordPress

Switch to the site user:

sudo su - dolphin

Download and extract WordPress:

cd /var/www/dolphin/example.com
curl -O https://wordpress.org/latest.tar.gz
tar -xvzf latest.tar.gz
mv wordpress/* .
rm latest.tar.gz && rm -fr wordpress

Open https://example.com in your browser to continue the WordPress installer.

On this page