Install LAMP (Linux, Apache, MySQL, PHP) on Ubuntu 20.04 LTS

LAMP (Linux, Apache, MySQL, PHP) is a very common example of a web service stack, named as an acronym of the names of its original four open-source components: the Linux operating system, the Apache HTTP Server, the MySQL relational database management system (RDBMS), and the PHP programming language. The LAMP components are largely interchangeable and not limited to the original selection. As a solution stack, LAMP is suitable for building dynamic web sites and web applications.

In this guide, we’ll install a LAMP stack on an Ubuntu 20.04 server.

1. Installing Apache web server

We can install apache using ubuntu’s package manager apt.

sudo apt update
sudo apt install apache2

You’ll be prompted to confirm Apache’s installation by pressing Y, then ENTER.

2. Updating the firewall (optional)

UFW is default ubuntu’s firewall manager. If it is enabled or you want to enable it later then it’s better to adjust the firewall setting for Apache web server.

You can check the status of UFW by using below command.

sudo ufw status

To adjust your firewall settings to allow HTTP traffic. UFW has different application profiles that you can leverage for accomplishing that. To list all currently available UFW application profiles, you can run:

sudo ufw app list

You’ll see output like this

Available applications:
  Apache
  Apache Full
  Apache Secure
  OpenSSH

You can see, there are three profiles avilable for apache. here is what it all means.

  • Apache: This profile opens only port 80 (normal, unencrypted web traffic).
  • Apache Full: This profile opens both port 80 (normal, unencrypted web traffic) and port 443 (TLS/SSL encrypted traffic).
  • Apache Secure: This profile opens only port 443 (TLS/SSL encrypted traffic).

For now, we will use Apache Full to enable both traffic from port 80 & 443.

sudo ufw allow in "Apache Full"

You can verify the changes with

sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere                                
Apache Full                ALLOW       Anywhere                  
OpenSSH (v6)               ALLOW       Anywhere (v6)                    
Apache Full (v6)           ALLOW       Anywhere (v6)

Test your apache installation by opening http://your_server_ip in your browser.

You’ll see the default Ubuntu 20.04 Apache web page, which is there for informational and testing purposes. It should look something like this:

If you see this page, then your web server is now correctly installed and accessible through your firewall.

Note : you also need to whitelist port 80/443 for incoming/outgoing traffic in security group of your instance if you are using AWS or any other cloud service.

Getting your server’s public IP Address.

You can check your cloud console for the assigned public IP of your server or else you can run below command to get your public ip.

curl http://icanhazip.com

3. Installing MySQL

MySQL is an open-source relational database management system. MySQL is a popular database management system used within PHP environments.

In order to install MySQL we will be using Ubuntu’s package manager

sudo apt install mysql-server

When prompted, confirm installation by typing Y, and then ENTER.

When the installation is finished, it’s recommended that you run a security script that comes pre-installed with MySQL. This script will remove some insecure default settings and lock down access to your database system. Start the interactive script by running:

sudo mysql_secure_installation

This will ask if you want to configure the VALIDATE PASSWORD PLUGIN.

Answer Y for yes, or anything else to continue without enabling. If you answer “yes”, you’ll be asked to select a level of password validation.

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: 1

When you’re finished, test if you’re able to log in to the MySQL console by typing:

sudo mysql

This will connect to the MySQL server as the administrative database user root, which is inferred by the use of sudo when running this command.

Notice that you didn’t need to provide a password to connect as the root user, even though you have defined one when running the mysql_secure_installation script. That is because the default authentication method for the administrative MySQL user is unix_socket/auth_socket instead of password. Even though this might look like a security concern at first, it makes the database server more secure because the only users allowed to log in as the root MySQL user are the system users with sudo privileges connecting from the console or through an application running with the same privileges.

If you prefer to use a password when connecting to MySQL as root, you will need to switch its authentication method from auth_socket to mysql_native_password.

mysql> SELECT user,authentication_string,plugin,host FROM mysql.user;
+------------------+-------------------------------------------+-----------------------+-----------+
| user             | authentication_string                     | plugin                | host      |
+------------------+-------------------------------------------+-----------------------+-----------+
| root             |                                           | auth_socket           | localhost |
| mysql.session    | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost |
| mysql.sys        | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost |
| debian-sys-maint | *CC744277A401A7D25BE1CA89AFF17BF607F876FF | mysql_native_password | localhost |
+------------------+-------------------------------------------+-----------------------+-----------+
4 rows in set (0.00 sec)

Here you can see that the root user does in fact authenticate using the auth_socket plugin. To configure the root account to authenticate with a password, run the following ALTER USER command. Be sure to change password to a strong password of your choosing.

mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'ur_strong_password';

Then, run FLUSH PRIVILEGES which tells the server to reload the grant tables and put your new changes into effect.

mysql> FLUSH PRIVILEGES;

Verify the changes by running again select command.

mysql> SELECT user,authentication_string,plugin,host FROM mysql.user;

You will get output like this.

+------------------+-------------------------------------------+-----------------------+-----------+
| user             | authentication_string                     | plugin                | host      |
+------------------+-------------------------------------------+-----------------------+-----------+
| root             | *3636DACC8616D997782ADD0839F92C1571D6D78F | mysql_native_password | localhost |
| mysql.session    | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost |
| mysql.sys        | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost |
| debian-sys-maint | *CC744277A401A7D25BE1CA89AFF17BF607F876FF | mysql_native_password | localhost |
+------------------+-------------------------------------------+-----------------------+-----------+
4 rows in set (0.00 sec)

4. Installing PHP

PHP is a general-purpose scripting language especially suited to web development. In addition to the php package, you’ll need php-mysql, a PHP module that allows PHP to communicate with MySQL-based databases. You’ll also need libapache2-mod-php to enable Apache to handle PHP files. Core PHP packages will automatically be installed as dependencies.

In addition to this we will also install some common php extensions.

sudo apt install php libapache2-mod-php php-mysql php-common php-curl php-json php-mbstring php-xml php-zip

Once the installation is finished, you can run the following command to confirm your PHP version.

php -v
PHP 7.4.3 (cli) (built: Mar 26 2020 20:24:23) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.3, Copyright (c), by Zend Technologies

Incaselater if you are going to use wordpress you can look below list of required php extensions.

Required Extensions;

  • curl – Performs remote request operations.
  • dom – Used to validate Text Widget content and to automatically configuring IIS7+.
  • exif – Works with metadata stored in images.
  • fileinfo – Used to detect mimetype of file uploads.
  • hash – Used for hashing, including passwords and update packages.
  • json – Used for communications with other servers.
  • mbstring – Used to properly handle UTF8 text.
  • mysqli – Connects to MySQL for database interactions.
  • libsodium – Validates Signatures and provides securely random bytes.
  • openssl – Permits SSL-based connections to other hosts.
  • pcre – Increases performance of pattern matching in code searches.
  • imagick – Provides better image quality for media uploads. See WP_Image_Editor is incoming! for details. Smarter image resizing (for smaller images) and PDF thumbnail support, when Ghost Script is also available.
  • xml – Used for XML parsing, such as from a third-party site.
  • zip – Used for decompressing Plugins, Themes, and WordPress update packages.

Recommended Extensions;

  • filter – Used for securely filtering user input.
  • gd – If Imagick isn’t installed, the GD Graphics Library is used as a functionally limited fallback for image manipulation.
  • iconv – Used to convert between character sets.
  • mcrypt – Generates random bytes when libsodium and /dev/urandom aren’t available.
  • simplexml – Used for XML parsing.
  • xmlreader – Used for XML parsing.
  • zlib – Gzip compression and decompression.

5. Creating Virtual Host for your website

When using the Apache web server, you can create virtual hosts to encapsulate configuration details and host more than one domain from a single server.

By default apache installation will create a default virtual host server block which is configured to serve documents from the /var/www/html directory.

In our case we’ll create a directory structure within /var/www for the example.com site, leaving /var/www/html in place as the default directory to be served if a client request doesn’t match our sites.

Note: You can choose any path as your application home directory instead of /var/www. here we will be using /var/www/example as our application home directory.

First create the directory for example.com domain as follows:

sudo mkdir /var/www/example

Next, assign ownership of the directory with the $USER environment variable, which will reference your current system user. By default in Ubuntu apache will be running as user www-data.

sudo chown -R www-data:$USER /var/www/example

Now we will create a new virtual host configuration for our domain in Apache’s sites-available directory.

sudo nano /etc/apache2/sites-available/example.com.conf

This will create a new blank file. Paste in the following basic configuration:


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

    # Custom log files, to differentiate from root server
    ErrorLog ${APACHE_LOG_DIR}/example-error.log
    CustomLog ${APACHE_LOG_DIR}/example-access.log combined

    <Directory /var/www/example>
        Options -Indexes -FollowSymLinks
        AllowOverride Limit Options FileInfo
        DirectoryIndex index.php
        Require all granted
    </Directory>
</VirtualHost>

Save and close the file when you’re done. You can now use a2ensite to enable the new virtual host:

sudo a2ensite example.com.conf

If you want to disable the default website that comes installed with Apache. You can use a2dissite to disable virtual host site config.

sudo a2dissite 000-default.conf

To make sure your configuration file doesn’t contain syntax errors, run:

sudo apache2ctl configtest

Finally, restart Apache so these changes take effect:

sudo systemctl restart apache2

Your new website is now active, but the web root /var/www/example is still empty. You can create a html file with name index.html in /var/www/example directory and test your server by typing domain name in your browser. ex – http://example.com

Note : Before this it is important to point your dns A record to this server ip address.

6. Test php processing along with db connection on web server.

We’ll create a PHP test script to confirm that Apache is able to handle and process requests for PHP files.

Create a new file named info.php inside your custom web root folder.

nano /var/www/example/info.php

This will open a blank file. Add the following text, which is valid PHP code, inside the file.

<?php
phpinfo();
?>

To test this script, go to your web browser and access your server’s domain name or IP address, followed by the script name, which in this case is info.php. It will give you output like this.

http://example.com/info.php

Note: Above script which we created list all server related configuration. This page provides information about your server from the perspective of PHP. It is useful for debugging and to ensure that your settings are being applied correctly.
After checking the relevant information about your PHP server through that page, it’s best to remove the file you created as it contains sensitive information about your PHP environment -and your Ubuntu server.

It’s better to remove this page after testing php is working fine. To remove using terminal use below command.

sudo rm /var/www/example/info.php

7. simple php script to test connection with database

Incase if you need to test/troubleshoot your php connection with database, you can below php script.

<?php
/* change the variables mentioned below with the database details.*/
$dbname = 'testdb';
$dbuser = 'testuser';
$dbpass = 'testpass';
$dbhost = 'localhost';

//Do not change below
$link = mysqli_connect($dbhost, $dbuser, $dbpass) or die("Unable to Connect to '$dbhost'");
mysqli_select_db($link, $dbname) or die("Could not open the db '$dbname'");

$test_query = "SHOW TABLES FROM $dbname";
$result = mysqli_query($link, $test_query);

$tblCnt = 0;
while($tbl = mysqli_fetch_array($result)) {
  $tblCnt++;
  #echo $tbl[0]."<br />\n";
}

if (!$tblCnt) {
  echo "There are no tables<br />\n";
} else {
  echo "There are $tblCnt tables<br />\n";
}
?>

As an immediate next step, you should ensure that connections to your web server are secured, by serving them via HTTPS. In order to accomplish that, you can use Let’s Encrypt to secure your site with a free TLS/SSL certificate.

Additionally if you are going to use this setup for production it’s better to secure Apache / MySQL / PHP with some security settings. I’ll update the same in my next article.

0 0 votes
Article Rating
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments