How to Install Nginx, MySQL, PHP (FEMP Stack) on FreeBSD 14.0
Introduction
FreeBSD, Nginx, MySQL, and PHP (FEMP stack) is a collection of open-source applications that enable the development, hosting, and delivery of dynamic web applications on a server. FreeBSD works as the deployment operating system, Nginx as the web server, MySQL or MariaDB as the database backend, and PHP as the server-side scripting processor.
This article explains how to install Nginx, MySQL, and PHP (FEMP stack) on FreeBSD 14.0, and configure the packages to enable the delivery of dynamic web applications on your server.
Prerequisites
Before you begin:
- Deploy a FreeBSD 14.0 instance on Vultr.
- Create a new domain A record pointing to the instance IP address. For example,
app.example.com
. - Access the server using SSH as a non-root user with sudo privileges.
Before installing any packages, update and Upgrade FreeBSD
- Update the package repository.
sudo pkg update
- Upgrade the installed packages.
sudo pkg upgrade
Install Nginx
- Install Nginx using the package manager.
sudo pkg install nginx
- Enable Nginx.
sudo sysrc nginx_enable=yes
- Start Nginx.
sudo service nginx start
- Verify that Nginx is running.
sudo service nginx status
Output:
nginx is runuing as pid 2273.
Install MySQL
- Install the MySQL server package.
sudo pkg install mysql80-server
- Enable MySQL.
sudo sysrc mysql_enable=yes
- Start MySQL.
sudo service mysql-server start
- Verify that MySQL is running.
sudo service mysql-server status
Output:
mysql is runuing as pid 4044.
- Secure MySQL installation.
sudo mysql_secure_installation
This script will guide you through setting up the basic security configuration of your MySQL installation. You will be prompted to:
-
VALIDATE PASSWORD component: Press
Y
. -
Password Validation Policy: Enter
2
forSTRONG
. - New password: Enter the new password.
- Re-enter new password: Confirm the new password.
-
Do you wish to continue with the password provided? Enter
Y
. -
Remove anonymous users? Enter
Y
. -
Disallow root login remotely? Enter
Y
. -
Remove test database and access to it? Enter
Y
. -
Reload privilege tables now? Enter
Y
.
Install PHP and PHP-FPM
- Install PHP and PHP-FPM.
sudo pkg install php83
- Enable PHP-FPM.
sudo sysrc php_fpm_enable=yes
- Start PHP-FPM.
sudo service php-fpm start
- Verify that PHP-FPM is running.
sudo service php-fpm status
Output:
php_fpm is runuing as pid 5524.
Install PHP Modules
- Install common PHP modules.
sudo pkg install php83-mysqli php83-curl php83-gd php83-intl php83-mbstring php83-xml php83-zip
- Enable
mysqli
in PHP configuration.
sudo nano /usr/local/etc/php.ini-production
- Uncomment the line
;extension=mysqli
.
extension=mysqli
- Restart PHP-FPM to apply changes.
sudo service php-fpm restart
Access the MySQL Database Server
- Log in to the MySQL shell as the root user.
sudo mysql -u root -p
- Create a new MySQL Database.
Create a new database named example_db
:
mysql> CREATE DATABASE example_db;
- List Existing MySQL Databases.
mysql> SHOW DATABASES;
You should see example_db
listed in the output.
+--------------------+
| Database |
+--------------------+
| example_db |
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
- Exit the MySQL Shell.
Run \q
to exit:
mysql> \q
Create a new Nginx Virtual Host Configuration
- Create the directory for virtual hosts.
sudo mkdir -p /usr/local/etc/nginx/vhosts/
- Create a new configuration file for your virtual host.
sudo nano /usr/local/etc/nginx/vhosts/app.example.com.conf
Attention: Replace
app.example.com
with the actual domain name you've set up for your server. Ensure that your domain is configured and points to your cloud server instance's IP address.
- Add the following content to the file.
server {
listen 80;
server_name app.example.com;
root /usr/local/www/app.example.com;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/local/www/app.example.com;
}
}
- Enable the virtual host configuration.
sudo nano /usr/local/etc/nginx/nginx.conf
- Add the following line inside the
http
context.
include /usr/local/etc/nginx/vhosts/*.conf;
- Verify Nginx configuration.
sudo nginx -t
- Restart Nginx to apply changes.
sudo service nginx restart
Create a sample Dynamic Web Application
- Create a directory for your website.
sudo mkdir -p /usr/local/www/app.example.com
- Create a PHP file to test the setup.
sudo touch /usr/local/www/app.example.com/index.php
Testing the FEMP Stack
Now that your FEMP stack is set up, let's test if everything is working as expected. Create a web page that displays a greeting message fetched from your MySQL database, demonstrating that your PHP code can communicate with the database.
- Connect to your MySQL database.
Open your terminal and log in to your MySQL server as the root user:
sudo mysql -u root -p
Enter your root password when prompted.
- Select the Database.
Select the database created for this purpose:
mysql> use example_db;
- Create a table for your greeting message.
Inside the MySQL shell, create a table called greetings
to store the message:
mysql> CREATE TABLE greetings (
id INT AUTO_INCREMENT PRIMARY KEY,
message VARCHAR(255)
);
- Add the greeting message to the table.
Insert your message into the greetings
table:
mysql> INSERT INTO greetings (message) VALUES ('Greetings from Vultr');
- Exit the MySQL Shell.
Run \q
to exit:
mysql> \q
- Test the PHP-MySQL connection.
Open the index.php
file you created earlier in the /usr/local/www/app.example.com
directory using your preferred text editor (such as nano
):
sudo nano /usr/local/www/app.example.com/index.php
Note: Replace
app.example.com
with your own domain name in all instructions.
Replace the existing content with this PHP code:
<?php
$servername = "localhost";
$username = "test_user";
$password = "Strong)P@ssword123";
$dbname = "test_db";
// Create database connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check database connection
if ($conn->connect_error) {
die("Database Connection Failed." . $conn->connect_error);
}
echo "<h4 align='center'> Below is the message retrieved from the test_db Mysql database on your server</h4>";
// Retrieve the record from greetings Table
$sql = "SELECT message FROM greetings";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
$row = $result->fetch_assoc();
echo "<h1 align='center'>" . $row["message"]. "</h1>";
} else {
echo "<h1 align='center'>No message found.</h1>";
}
$conn->close();
?>
Save and close the file.
- Restart the Nginx web server to apply changes.
sudo service nginx restart
- Verify your test page.
- Access your domain using a web browser such as Chrome and verify that a Greetings from Vultr message displays in your browser.
http://app.example.com
Secure the Server
- Install Certbot.
sudo pkg install py39-certbot py39-certbot-nginx
- Generate Trusted SSL Certificates with Let's Encrypt.
sudo certbot --nginx -d app.example.com
- Verify Nginx configuration.
sudo nginx -t
- Restart Nginx to apply changes.
sudo service nginx restart
- Set up a cron job to renew SSL certificates automatically.
echo "0 0 * * * /usr/local/bin/certbot renew --quiet" | sudo tee -a /etc/crontab
Verify SSL Certificate
-
Open your web browser and navigate to
https://app.example.com
. -
Check the padlock icon in the address bar to ensure the connection is secure.
Conclusion
You have installed Nginx, MySQL, and PHP (FEMP stack) on your FreeBSD server and set up a sample web application to deliver dynamic web content on your server. You can use the FEMP stack to securely develop and deliver high-performance web applications on your server using virtual host configurations. For more information and configuration options for each application in the stack, please visit the following documentation resources:
- FreeBSD.
- Nginx.
- MySQL.
- PHP.
- Vultr's guides.