Verification: a143cc29221c9be0

Nginx apache php mysql ubuntu server

Nginx apache php mysql ubuntu server


Before beginning the LEMP installation on Ubuntu:

  • A running Ubuntu 20.04 system
  • Login as sudo proviledged account on your system. To create it follow initial server setup tutorial.
  • A domain/subdomain name pointed to your server

Installing Nginx Web Server

Next, you need to install Nginx web server on your system. The Nginx packages are are available under the default apt repositories.

Run the following commands to install it:

sudo apt update
sudo apt install nginx

Installing PHP with PHP-FPM

PHP 7.4 packages are available under the default repositories on Ubuntu 20.04 LTS. Use the following command to update apt cache and install PHP on your system.

sudo apt update
sudo apt install -y php7.4 php7.4-fpm

Also install additional PHP modules required for your application.

sudo apt install php7.4-curl php7.4-gd php7.4-json php7.4-mbstring php7.4-xml

You have installed PHP 7.4 with PHP FPM package on your system. Let’s check the status of the PHP FPM service by running below command:

sudo systemctl status php7.4-fpm

● php7.4-fpm.service - The PHP 7.4 FastCGI Process Manager
     Loaded: loaded (/lib/systemd/system/php7.4-fpm.service; enabled; vendor preset: enabled)
     Active: active (running) since Tue 2020-06-16 05:15:57 UTC; 34s ago
       Docs: man:php-fpm7.4(8)
    Process: 882716 ExecStartPost=/usr/lib/php/php-fpm-socket-helper install /run/php/php-fpm.sock /etc/php/7.4/fpm/pool.d/www.conf 74>
   Main PID: 882699 (php-fpm7.4)
     Status: "Processes active: 0, idle: 2, Requests: 0, slow: 0, Traffic: 0req/sec"
      Tasks: 3 (limit: 2283)
     Memory: 10.3M
     CGroup: /system.slice/php7.4-fpm.service
             ├─882699 php-fpm: master process (/etc/php/7.4/fpm/php-fpm.conf)
             ├─882714 php-fpm: pool www
             └─882715 php-fpm: pool www

Jun 16 05:15:57 tecadmin systemd[1]: Starting The PHP 7.4 FastCGI Process Manager...
Jun 16 05:15:57 tecadmin systemd[1]: Started The PHP 7.4 FastCGI Process Manager.

Installing MySQL

The default Ubuntu 20.04 apt repositories contains MySQL server 8.0. Finally, install mysql-server packages for the MySQL database. Also, install the php-mysql package to use MySQL support using PHP. Use the following command to install it.

sudo apt install mysql-server php7.4-mysql

The installer will prompt for the root password, This password will work for your MySQL root user. After installing MySQL execute the following command for initial settings of MySQL server. You will see that script will prompt for more settings than earlier MySQL versions like password validation policy etc.

sudo mysql_secure_installation
Securing the MySQL server deployment.

Connecting to MySQL using a blank password.

VALIDATE PASSWORD COMPONENT can be used to test passwords
and improve security. It checks the strength of password
and allows the users to set only those passwords which are
secure enough. Would you like to setup VALIDATE PASSWORD component? 

Press y|Y for Yes, any other key for No: y

There are three levels of password validation policy:

LOW    Length >= 8
MEDIUM Length >= 8, numeric, mixed case, and special characters
STRONG Length >= 8, numeric, mixed case, special characters and dictionary  file

Please enter 0 = LOW, 1 = MEDIUM and 2 = STRONG: 2
Please set the password for root here.

New password:

Re-enter new password:

Estimated strength of the password: 100
Do you wish to continue with the password provided?(Press y|Y for Yes, any other key for No) : y
By default, a MySQL installation has an anonymous user,
allowing anyone to log into MySQL without having to have
a user account created for them. This is intended only for
testing, and to make the installation go a bit smoother.
You should remove them before moving into a production

Remove anonymous users? (Press y|Y for Yes, any other key for No) : y

Normally, root should only be allowed to connect from
'localhost'. This ensures that someone cannot guess at
the root password from the network.

Disallow root login remotely? (Press y|Y for Yes, any other key for No) : y

By default, MySQL comes with a database named 'test' that
anyone can access. This is also intended only for testing,
and should be removed before moving into a production

Remove test database and access to it? (Press y|Y for Yes, any other key for No) : y
 - Dropping test database...

 - Removing privileges on test database...

Reloading the privilege tables will ensure that all changes
made so far will take effect immediately.

Reload privilege tables now? (Press y|Y for Yes, any other key for No) : y

All done!

Configure Nginx with PHP-FPM

Let’s create a Nginx virtual host to run with FPM/FastCGI. For this tutorial, we use default VirtualHost. Edit VirtualHost host configuration file in text editor. You can create new VirtualHost as per your requirements, so make sure to enable any new VirtualHost.

sudo vim /etc/nginx/sites-available/

Use the below basic Nginx Virtual host configuration with php fpm settings. Update the configuration as followings.

server {

        listen 80;

        root /var/www/html;

        index index.php index.html index.htm;


        location / {

            try_files $uri $uri/ =404;


        location ~ \.php$ {

            include snippets/fastcgi-php.conf;

            fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;



Save your changes to the configuration file and create a link to site enabled directory.

sudo ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled/ 

Then restart Nginx service to reload the changes.

sudo systemctl restart nginx

Step 5 – Manage Services

We have done with the installation of LAMP stack on Ubuntu 20.04 LTS system. The below commands will help you to start/stop or restart Nginx and MySQL services running with systemd.

To restart Nginx and MySQL services, type:

sudo systemctl restart nginx
sudo systemctl restart mysql

To start Nginx and MySQL services, type:

sudo systemctl start nginx
sudo systemctl start mysql

To stop Nginx and MySQL services, type:

sudo systemctl stop nginx
sudo systemctl stop mysql


  • The latest version of the Debian 10 operating system, which can be obtained from the following link, installed from scratch on a VPS, virtual machine or directly on a self-dedicated machine.
  • Direct access to the server’s console or a remote SSH connection.
  • A network interface configured with a static IP address for the machine
  • A registered public domain name with A and CNAME (www) DNS records configured on the name server side. In this guide, we use the domain as an example.

Step 1: Initial Configuration

The first step is to log in with root or with a user with root privileges in your system and update Debian 10 components (kernel upgrades, package updates, and security patches) by issuing the following commands.

sudo apt  update
sudo apt upgrade
sudo apt dist-upgrade

Next, you make sure you add a descriptive name for your machine hostname by running the below command. Subsequently, you should restart the system in order to apply the new hostname accordingly.

sudo hostnamectl set-hostname
sudo init 6

Next, go ahead and install net-tools wget, curl and bash-completion utilities in order to use them later to easily administer your Debian server.

sudo apt install net-tools sudo wget curl bash-completion

Step 2: Install the Nginx Web Server

Nginx is a modern and resources efficient web server used to display web pages to visitors on the internet. Install Nginx webserver from Debian 10 repository by running the below command in your server’s console.

sudo apt-get install nginx

Installation of Nginx web server

As shown in the above image the apt package manager will check additional dependencies for the package and ask you if you agree to continue with the installation process. Answer with yes (y) in order to install Nginx.

Next, run netstat command in order to display network sockets on your system and verify if nginx daemon is listening on port 80/TCP. Alternatively, you might want to issue systemctl command in order to check the status of nginx daemon as illustrated in the below image.

sudo netstat -tlp
sudo netstat –tlpn
sudo systemctl status nginx.service

Check nginx service

Once the nginx server is up and running in your system, issue ifconfig command in order to display network interfaces information and list the IP addresses of your machine.  Then, open a browser and visit Nginx default web page via HTTP protocol by adding the IP address in your browser. The message “Wellcome to Nginx!” should be displayed in your browser window.



Nginx welcome page

Step 3: Activate Nginx HTTP/2.0 Protocol

By default, the latest versions of the Nginx binaries provided by the Debian 10 repositories are built with the HTTP/2.0 protocol. HTTP/2.0 is integrated with TSL/SSL protocols and can improve web page loading speed via secured transactions.

All modern browsers, such as Chrome or Firefox, should support this protocol by default. However, note that Microsoft Internet Explorer and Microsoft Edge browsers cannot yet parse the http2 protocol.

To enable the HTTP/2.0 protocol in Nginx on Debian 10, you need to make some changes to the default Nginx configuration file or create a new configuration file and add the TLS code block for 443 servers. To accomplish this, first create a backup of the default Nginx sites-available configuration by running the following command. Confirm that the backup was successful by listing the contents of the sites-available directory.

sudo cp /etc/nginx/sites-available/default{,.backup}
ls /etc/nginx/sites-available/

Next, create an Nginx TLS configuration file using a text editor and add the following content.

sudo nano /etc/nginx/sites-available/default-ssl

default-ssl file excerpt:

    server {
                listen 443 ssl http2 default_server;
                listen [::]:443 ssl http2 default_server;
                #server_name  www.domain.tld;
                server_name _;
                root /var/www/html;
                access_log /var/log/nginx/access.log;
                error_log /var/log/nginx/error.log;
                #SSL Certificates
                ssl_certificate "/etc/nginx/ssl/cert.pem";
                ssl_certificate_key "/etc/nginx/ssl/privekey.pem";
                ssl_dhparam /etc/nginx/ssl/dhparam.pem;
                ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
                #ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
                ssl_session_cache shared:SSL:1m;
                ssl_session_timeout 10m;
                ssl_ciphers HIGH:!aNULL:!MD5;
                ssl_prefer_server_ciphers  on;
                add_header Strict-Transport-Security "max-age=31536000;
                #includeSubDomains" always;
                location / {
                index index.php index.html index.htm;
                    try_files $uri $uri/ /index.php?$args $uri/ =404;
                                set $cache_uri $request_uri;
                location ~ /.well-known {
                allow all;
               location ~ \.php$ {
                                include snippets/fastcgi-php.conf;
                #             # With php-fpm (or other unix sockets):
                              fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
                #             # With php-cgi (or other tcp sockets):
                #             fastcgi_pass;
                # deny access to .htaccess files, if Apache's document root
                # concurs with nginx's one
                #location ~ /\.ht {
                #             deny all;

The statement that enables the use of HTTP/2.0 protocol is represented by the word http2 from the below line.

 listen 443 ssl http2 default_server;

In case your visitor’s browsers don’t support HTTP2 protocol, remove the http2 word from your server configurations in order to disable the protocol and restart nginx service to apply changes.

In case you have a registered domain or you use virtual hosting based on IP addresses you should add your domain name or IP address after the server_name directive as shown in the below example.


Once you finished editing Nginx default configuration file with the above settings

Configure SSL in Nginx

In the above TSL configuration file of nginx, we have specified the path for the TLS certificate and key. Since we have not yet installed the keys in your system, enter the following command to generate the self-signed SSL certificate file and key. During the generation of the SSL certificate, you will be asked a series of questions. Enter the two-digit code for your country, state, or province, the name of your city, the name of your organization, the name of your organization’s unit, the Common Name of your server, and a valid email address.  You should make sure to set the Common Name so that it matches the FQDN record of your computer from the DNS server or the IP address of your server used to access the website. The certificate and key are stored in a new directory under the nginx directory named ssl, as shown in the following screenshot.

sudo mkdir /etc/nginx/ssl
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/privekey.pem -out /etc/nginx/ssl/cert.pem
ls /etc/nginx/ssl/

Create SSL certificate

Also, generate a new strong Diffie-Hellman cipher, which can be found in the above configuration file on ssl_dhparam statement line, by issuing the below command:

sudo openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048

SSL Cert created

Finally, after you’ve generated the Diffie-Hellman key, activate the TLS configuration file by creating a symbolic link for default-ssl configuration file from sites-available directory to sites-enabled directory by issuing the following command.

ln -s /etc/nginx/sites-available/default-ssl /etc/nginx/sites-enabled/

Next, test Nginx configuration file for syntax errors and, if everything is ok, restart Nginx daemon in order to apply all changes by running the below commands.

sudo nginx -t
sudo systemctl restart nginx.service

Check if SSL Configuration succeeded

In order to confirm if Nginx web server is binding on SSL port, issue netstat command and check if port 443 is displayed in listening mode.

netstat -tlpn | grep nginx

The below screenshot illustrated the above steps.

Check service with netstat

Then, navigate to your domain name or your server’s IP address via HTTP protocol from a browser to display nginx default page. Because you’re using self-signed certificates, an error should be displayed in your browser. Confirm the error in order to pass to the nginx default main page.

Self signed SSL certificate warning

In case Nginx doesn’t provide a default index.html page in webroot directory, issue the following command to create the index page.

echo "test page" | tee /var/www/html/index.html

SSL test page

In order to confirm the presence of HTTP/2.0 protocol advertised by Nginx, issue the below command. Look for h2 word in protocols advertised by the server.

 openssl s_client -connect localhost:443 -nextprotoneg ''

Test SSL certificate with openssl command

You can also visualize the state of the connection and check if the http2 protocol is advertised by Nginx from the Chrome browser by pressing F12 function key and request the page. In order to show the protocol used by the request, go to the Network tab, right-click on the Type menu and check Protocol filed. HTTP2 protocol should be displayed as h2 in the current protocol column, as illustrated in the below screenshot.

Test certificate in browser

Step 4: Install PHP 7

Nginx web server can serve dynamic web content with the help of PHP programming language interpreter via PHP FastCGI process manager to which Nginx passes the requests for processing. FastCGI process manager can be obtained by installing the php-fpm pre-compiled package offered by Debian 9 official repositories.

In order to install php-fpm process manager and PHP7.0 interpreter in the system alongside with the additional packages that will allow PHP to communicate with Nginx web server, issue the below command on your server console:

sudo apt install php7.3 php7.3-fpm php7.3-curl php7.3-gd


Once the PHP 7.3 interpreter has been successfully installed on your system, start and check php7.3-fpm daemon by issuing the below command:

sudo systemctl start php7.3-fpm
sudo systemctl status php7.3-fpm

In the above TLS configuration file of Nginx, we’ve already added the block configurations for PHP FastCGI process manager in order to serve dynamic content. The block of code that enables Nginx to use PHP interpreter is shown in the below excerpt, so no steps are needed further to modify Nginx TSL configuration file. The hashtag # sign from the beginning of the lines in the below screenshot are comments. Commented lines from configuration files are ignored by default by Nginx web server.

location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.3-fpm.sock;

Test PHP Configuration

In order to test and validate if Nginx can correctly pass php files to PHP processor, create a PHP info.php test configuration file by issuing the below command

sudo su -c 'echo "" > /var/www/html/info.php'

Then, visit php info page in your web browser by navigating to your server’s domain name or public IP address followed by /info.php as shown in the below image.


You can also check if HTTP/2.0 protocol is advertised by the server by searching for the line $_SERVER[‘SERVER_PROTOCOL’] on PHP Variables.

To install other PHP7.3 modules, run the apt search php7.3 command to find a specific PHP module and install it. If you are planning to install a Content Management System, such as WordPress, then install these extra modules:

sudo apt install php7.3-mcrypt php7.3-mbstring

However, the newly installed PHP modules are not enabled by default on your system. In order to activate them, restart the PHP-FPM service.

sudo systemctl restart php7.3-fpm.service