Introduction
In this post, I will go over details of how to install NGINX web server, MySQL Server and PHP on an Ubuntu Server. I will also go over the details of setting up SSL and Virtual Host Configuration for NGINX.
Let’s start with our installation on the Ubuntu version of Linux.
NGINX HTTPD Web Server
NGINX webserver files and all related documentation is located on the NGINX Server website.
Since NGINX is an open source server, you can download the NGINX source code and browse user, admin and developer documentation on the NGINX website.
Before starting to install run update the package manager using the following command.
root@d1:~# sudo apt update
Install NGINX Web Server
Once the update is done use the command below to install the NGINX web server.
root@d1:~# sudo apt install nginx
Once the above command completes, the default install of NGINX web server will be installed. You can check NGINX version using the command:
root@d1:~# nginx -v
To validate the installation you can use one of the following two methods.
Validate Install with CURL
Use the following curl
command to check if the NGINX web server is installed and working.
root@d1:~# curl http://localhost -i
The output should be similar to what is shown below.
HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Date: Wed, 08 Feb 2023 02:04:39 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Wed, 08 Feb 2023 01:04:05 GMT
Connection: keep-alive
ETag: "63e2f505-264"
Accept-Ranges: bytes
......
Note: After line 11 will be the content of the index.html installed with NGINX. I have deleted those lines for brevity.
Validate Install with Browser
Open your favorite browser and enter the URL http://localhost. The default webpage will open.
NGINX Important Files and Folders
Now that I have gone over the steps of installing the NGINX web server and ensuring it is working, let’s take a few moments to review the important files and folders installed.
NGINX configuration files are installed in the folder /etc/nginx. During ls
shows the following structure.
oot@d1:/etc/nginx# ls
conf.d fastcgi_params koi-win modules-available nginx.conf scgi_params sites-enabled uwsgi_params
fastcgi.conf koi-utf mime.types modules-enabled proxy_params sites-available snippets win-utf
conf-* Folders
The conf-available folder has all files that are available for you to configure NGINX behavior. You will find the PHP fpm configuration and security files.
Do note that not all files in this folder are currently being used. The enabled configuration files are linked through the conf-enabled folder.
modules-* Folders
modules-available
contains configuration files of all modules available for configuration. With the default this folder usually has no configuration files.
modules-enabled
contains configuration files of all available modules.
sites-* Folders
sites-* folders are used to manage virtual server configurations for multiple websites. Available virtual host (domain a server will be hosting) configuration will be in the sites-available folder and activated (aka live) virtual hosts are in the sites-enabled folder.
For NGINX activating or enabling a virtual host needs a symbolic link to be created from /etc/nginx/sites-enabled
to a config file in /etc/nginx/sites-available
folder.
Important Files
- nginx.conf: This file has many server level configuration parameters. These allow you to configure server level configuration options. For example to turn on gzip compression for all sites you will add the line
gzip on;
tonginx.conf
. - fastcgi_params: In this file you setup variables that will be passed from NGINX to backend dynamic processing modules such as PHP.
- proxy_params: When NGINX is configured to work as a proxy server then instead of setting those in each of the
server{}
block you can add the headers in this file and it will forward those to all backend servers.
HTML Files Folder
Ubuntu installs all web files below the /var/www/
folder, which is the root of all virtual host site folders.
The default localhost files are located in the folder /var/www/html
.
When you set up a new virtual host example.com
, then you may want to copy the files in the folder /var/www/example
and use this path in the virtual host configuration. I will go over this in a later section.
Log Folder
Ubuntu installs the log file in /var/log/nginx
folder. When configuring a new virtual host on NGINX you should point all access
and error
log files to be stored in this folder.
Starting and Stop NGINX Web Server
When you install the server using the apt command, the script automatically starts the NGINX web server.
But during routine management and configuration changes, you will need to manually start or stop the NGINX web server. There are also cases where you don’t need to restart the NGINX web server but simply need the configuration changes to be reloaded.
The following commands are available for you to manage the NGINX web server.
root@d1:/etc/nginx# sudo service nginx stop
root@d1:/etc/nginx# sudo service nginx start
root@d1:/etc/nginx# sudo service nginx restart
root@d1:/etc/nginx# sudo service nginx reload
NGINX SSL Configuration
To use SSL with NGINX I will need to have a SSL certificate. Luckily with Ubuntu in the /etc/ssl/certs folder there are a few available that I can use for testing.
The default install did create a virtual server with the name default that serves all requests for localhost and 127.0.0.1 IP address.
root@d1:/etc/nginx# ls -l sites-available/
total 4
-rw-r--r-- 1 root root 2412 Jul 26 2022 default
root@d1:/etc/nginx# ls -l sites-enabled/
total 0
lrwxrwxrwx 1 root root 34 Feb 7 17:03 default -> /etc/nginx/sites-available/default
As I have mentioned above there is a default config in the sites-available folder. Then a link from sites-enabled was created to this file.
To create a secure SSL NGINX server I will create a new webserver configuration file default-ssl in the /etc/nginx/sites-available
folder.
The contents of this file will be:
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
gzip off;
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
root /var/www/html;
index index.html;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
}
Let me go over the important parts of the server block in the configuration file.
- Line 2 & 3: NGINX listening port is set with the
listen
directive. Here I have configured NGINX to serve all requests for default server, localhost in this case coming in on secure port 443 to be served as configured for this server. - Line 5: NGINX documentation suggests that gzip is disabled for SSL secured websites.
- Line 6 & 7: Using the
ssl_certificate
andssl_certificate_key
directive, I use file system paths to the actual certificate and key. - Line 9: Specifies the document root folder for this domain. Static files and other static content such as media files can be located here. You can also use this folder to store dynamic PHP script files will be stored here.
- Line 11: Specify the index files with the
index
directive. In case of multiple index files, as with using PHP, separate multiple values with acomma
(,). - Lines 15-18: Define how to process requests coming to the root of the domain. You can have multiple location blocks. Later I will be setting up another location block to process dynamic web requests for PHP.
After creating the SSL server config file, I will create a symbolic link from the sites-available
folder to this file.
The location block in the server block is pointing to the root from which NGINX will be serving static files from.
root@d1:/etc/nginx/sites-enabled# ln -s /etc/nginx/sites-available/default-ssl default-ssl
Restart NGINX after enabling the mods and the SSL VirtualHost site.
root@d1:~$ sudo service nginx restart
Run the curl
command from the shell to ensure everything is running.
root@d1:~# curl -I https://localhost -k
This will show the headers only. If you want to view all headers with data on TLS
including the contents of the page being served then use the following.
root@d1:~# curl -v https://localhost -k
Note, that if you opened the URL in the browser then you will get the following error message.
This is normal because the SSL certificate used is not for production. To bypass this message click on Advanced button and click on the Accept the Risk and Continue
button.
This will take you to the actual page.
Install MySQL on Ubuntu Server
After installing NGINX, the next step is to install MySQL. Run the following command.
root@d1:~# sudo apt install mysql-server
Once MySQL server install completes you can check the version using the command,
root@d1:~# mysql Ver 8.0.32-0ubuntu0.20.04.2 for Linux on x86_64 ((Ubuntu))
How to Login to new MySQL Install on Ubuntu
In the latest versions of MySql, there is no built-in account that you can log in using username
/password
combo. There is however a root account created with auto login enabled for the current user.
To login to MySQL user the following command:
root@d1:~# sudo mysql
Create MySQL Test Database and New User
Now that I have installed MySQL and have logged in to the MySQL shell, I will create a new user and database for testing with PHP.
Run the following SQL commands.
mysql> CREATE DATABASE fsmtest CHARACTER SET UTF8MB4;
Query OK, 1 row affected (0.01 sec)
mysql> CREATE USER 'fsmuser'@'localhost' IDENTIFIED BY 'nopass';
Query OK, 0 rows affected (0.02 sec)
mysql> GRANT ALL ON fsmtest.* to 'fsmuser'@'localhost';
Query OK, 0 rows affected (0.01 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
Basically, with the SQL commands shown above I first create a database, then a new user and after that I grant the user all privileges or access on the newly created database.
I also issue the flush SQL command, which is optional.
Now I am ready to install PHP to complete the software stack.
Installing PHP FPM on Ubuntu Server
To install PHP run the following command.
root@d1:~# sudo apt install php-fpm
This will install or configure PHP to run in FPM mode.
To check if PHP-FPM is running, use the command below:
root@d1:~# ps -eaf | grep fpm
root 20966 1 0 18:42 ? 00:00:00 php-fpm: master process (/etc/php/8.1/fpm/php-fpm.conf)
www-data 20967 20966 0 18:42 ? 00:00:00 php-fpm: pool www
www-data 20968 20966 0 18:42 ? 00:00:00 php-fpm: pool www
root 21027 19370 0 18:42 pts/1 00:00:00 grep --color=auto fpm
Enabling Additional PHP Extensions
To make sure PHP can talk with MySQL you will need to install the relevant extension.
root@d1:~# sudo apt install php-mysql
Once the MySQL extension is installed run the following command to ensure that the extension is loaded by PHP.
root@d1:~# php -i | grep mysql
The output will show in multiple lines configuration settings for MySQL extension.
Although PHP MySQL is installed, you will need to restart PHP-FPM to pickup the new changes.
root@d1:~# sudo systemctl restart php8.1-fpm.service
Other commands for PHP-FPM are:
root@d1:~# sudo systemctl start php8.1-fpm.service
root@d1:~# sudo systemctl stop php8.1-fpm.service
root@d1:~# sudo systemctl reload php8.1-fpm.service
With this our basic setup of NGINX, MySQL and PHP are complete.
PHP Configuration Files
PHP configuration files are in the folder /etc/php/{version}
. Form example if PHP version 8.1 is installed then the path will be /etc/php/8.1
. Doing an ls
show the following:
root@d1:~# /etc/php/8.1$ ls
apache2 cli fpm mods-available
The apache2
folder has the php.ini
file when PHP is being used as a module with Apache. If PHP is being used in FPM mode then the fpm
folder has the relevant php.ini
file.
Setup NGINX and PHP Integration in Server
Here I am going to modify the virtual server file default-ssl and add lines to support NGINX to forward .php file requests to the PHP-FPM process.
The content of the final defaul-ssl will be:
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
gzip off;
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
root /var/www/html;
index index.html;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
# pass PHP scripts to FastCGI server
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
}
One change you will see in the above server configuration is the addition on a new block (lines 22-25). This tells NGINX to forward all PHP script requests to the PHP FPM process.
Now I will restart the NGINX web server process.
root@d1:~# sudo service nginx restart
Create a PHP Test File
With the changes in place, let’s create a PHP test file to view PHP configuration.
Go to the folder /var/www/html
and create a new file config.php
and copy the following text and save it.
<?php
phpinfo();
In this file I am using a built-in PHP funtion phpinfo()
, which prints PHP configuration as HTML text.
Testing Complete NGINX, MySQL & PHP Setup
Now that NGINX, MySQL and PHP correctly installed and configured with validation that all needed extensions and modules are installed and configured correctly, I will now create a PHP script to get some data from MySQL.
Add Table and Data to MySQL
Earlier while setting up MySQL I created a database fsmtest for validating integration of my setup.
First I will create a new table.
user@d1:~$ mysql -u fsmuser -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
mysql> use fsmtest;
Database changed
mysql> CREATE TABLE city ( name varchar(255));
Query OK, 0 rows affected (0.01 sec)
With the table in place let’s add a single record.
mysql> INSERT INTO city (name) VALUES ('San Francisco');
I have added a single record to the database.
Now create a PHP page to get this data from MySQL and display in a browser.
Add a file at /var/www/html/ and name it mysqltest.php. Copy the following content and save the changes.
<?php
// Create connection
$connection = mysqli_connect("localhost","fsmuser","nopass","fsmtest");
// Check connection
if ($connection->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$result = mysqli_query($connection,"SELECT * FROM city");
while($row = mysqli_fetch_array($result))
print_r($row['name']);
mysqli_close($connect);
If everything is configured correctly a web page similar to the one below displays the single city name I entered earlier. will be shown.
NGINX Configure and Enable Virtual Host aka Server(Bonus)
In this section, I will go over an example of how to create a new NGINX VirtualHost server configuration in Ubuntu.
First, I need to add a domain to the local hosts
file. The path is /etc/hosts
.
Add the following line to the end.
127.0.0.1 mydomain.local
Let’s create a new webserver configuration for our new domain.
In the folder /etc/nginx/sites-available
and create a file mydomain
and copy the below contents to it and save all changes.
server {
listen 80;
listen [::]:80;
server_name mydomain.local;
root /var/www/mydomain;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
Note: In this configuration, I have setup the server_name
directive to serve my custom domain.
Next you will have to link to this file from the /etc/nginx/sites-enabled folder and then restart NGINX.
root@d1:/etc/nginx/sites-enabled# ln -s /etc/nginx/sites-available/mydomain mydomain
root@d1:/etc/nginx/sites-enabled# ls -l
total 0
lrwxrwxrwx 1 root root 34 Feb 7 17:03 default -> /etc/nginx/sites-available/default
lrwxrwxrwx 1 root root 38 Feb 7 18:35 default-ssl -> /etc/nginx/sites-available/default-ssl
lrwxrwxrwx 1 root root 35 Feb 7 19:08 mydomain -> /etc/nginx/sites-available/mydomain
root@d1:/etc/nginx/sites-enabled# sudo service nginx restart
Create the website folder for this domain in the path /var/www
. I will be naming the folder mydomain
. Inside this folder create a file index.html. In this file, I will add only the text “MyDomain.local”.
Once the folder is created I will restart the NGINX web server.
You can use the following set of commands to do all of the above changes.
root@d1:~# sudo mkdir /var/www/mydomain
root@d1:~# sudo echo MyDomain.local > /var/www/mydomain/index.html
root@d1:~# sudo service nginx restart
Open the browser and enter the URL http://mydomain.local and view the index.html page contents.
Conclusion
This completes the setup of NGINX, MySQL and PHP FPM on the Ubuntu platform. In addition, I went over the details of how you can set up a virtual host on NGINX.
This is only a start and there is a lot more you can do. I have many tutorial posts on my NGINX page. Check out my post on how to scale your NGINX install with Load Balancing, reverse proxy and caching, read the post on our website as well.
NGINX server is an excellent choice for a low memory usage web server providing high concurrency using an event driven approach.