How to Install LAMP Stack on Ubuntu 18.04

In this article, I'll explain how to install LAMP stack with WordPress on our latest Ubuntu 18.04 server. LAMP stands for Linux-Apache-MySQL-PHP. It's a group of free software which can be installed together to build a server to host dynamic, database-driven websites and web application. It uses Linux as the operating system, Apache as the Web server, MySQL as the relational database management system to store site data and PHP to process the dynamic contents.

There is an alternative easy way to install LAMP server using "tasksel" tool developed by Ubuntu/Debian. But in this article, I will install each package manually.

Install Apache

All the latest version of Apache, Mysql and PHP are present in the server repository itself. So we can use our package manager apt to install all packages without any third party repository. You can install the Apache by running this command below:

#apt-get update
#apt install apache2

We need to make sure to enable and start this service after the install just like this:

#systemctl enable apache2
#systemctl start apache2

We've installed with the latest Apache 2.4.29 version in our server.  Next, we can verify the Apache version installed and test it's working by accessing the server IP in the browser, just like this >> http://Server-IP/

Optimizing the web server performance

Please follow these steps to optimize your web server performance.

1. Optimizing the Apache directives

It is always important to ensure the server performance with the minimal resources available. KeepAlive is an apache directive,  it allows Apache to utilize server-side memory, reducing latency for users on the hosted site.  It provides long-lived HTTP sessions which allow multiple requests to be sent over the same TCP connection. KeepAlive will make a website faster if the host has enough memory to support it. Complimenting this directive comes the MaxKeepAliveRequests and KeepAliveTimeout.

The MaxKeepAliveRequests setting controls the maximum number of requests during a persistent connection. 50 is a conservative amount; we can set this number higher depending on our web traffic. The KeepAliveTimeout controls how long the server waits for new requests from already connected clients, setting this option to  5 will avoid wasting RAM. Higher its value more chance to cause performance problems in heavily loaded servers. The higher the timeout, the more server processes will be kept occupied waiting on connections with idle clients.

Taking these directives into consideration, I've optimized my default Apache configuration file located at /etc/apache2/apache.conf with these values to enhance my web server performance (you need tune based on your requirements).

KeepAlive On
MaxKeepAliveRequests 50
KeepAliveTimeout 5

2. Choosing the MPM Module

Apache 2 introduced Multi-Processing Modules or MPMs. Prefork, Worker, and Event are the three recommended MPMs available. By default, Apache picks the prefork MPM.  Since the LAMP stack requires PHP, it may be best to stick with the default. You can determine the current MPM status by running the following command on the command line.

Note: You need to tweak these values based on server performance and web server requests

# apache2 -V |grep -i 'version\|mpm'
Server version: Apache/2.4.29 (Ubuntu)
Server MPM: prefork

Open the mpm_prefork.conf file located in /etc/apache2/mods-available and edit the configuration.

# cat /etc/apache2/mods-available/mpm_prefork.conf
# prefork MPM
# StartServers: number of server processes to start
# MinSpareServers: minimum number of server processes which are kept spare
# MaxSpareServers: maximum number of server processes which are kept spare
# MaxRequestWorkers: maximum number of server processes allowed to start
# MaxConnectionsPerChild: maximum number of requests a server process serves

<IfModule mpm_prefork_module>
StartServers 4
MinSpareServers 3
MaxSpareServers 40
MaxRequestWorkers 200
MaxConnectionsPerChild 10000
</IfModule>

PS: You can even use these commands to switch between the MPMs as per your hosting requirements.

#a2dismod mpm_event
#a2enmod mpm_prefork

3. Restart Apache service

It's always advised to restart the Apache service after making any changes to its configuration to make the changes effective. So after making the above changes, make sure to restart the Apache service.

#systemctl restart apache2

Install MySQL

Secondly, we need to install our Database server. I've installed MySQL 5.7.22 on my server. You can install the latest version available by running the following command:

#apt install mysql-server
# mysql -V
mysql Ver 14.14 Distrib 5.7.22, for Linux (x86_64) using EditLine wrapper

Start/enable MySQL service and check its status.

# systemctl enable mysql
Synchronizing state of mysql.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable mysql
# systemctl start mysql
# systemctl status mysql

Next, you will need to run the security script which comes with the installation to secure your database server. You can run the following command to secure MySQL database and set root password:

# mysql_secure_installation

Securing the MySQL server deployment.

Connecting to MySQL using a blank password.

VALIDATE PASSWORD PLUGIN 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 plugin?

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
environment.

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

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
Success.

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
environment.

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

Success

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

Success
All done!

As you can see, during this secure installation phase, it will prompt you to set up PASSWORD PLUGIN . For security reasons, I'll definitely recommend you to opt for the strong password level to proceed with. Once it's done you can set up your administrative password. For rest of the questions, you can enter y for yes which will remove anonymous users and the test database, disable remote root logins, and reload the privilege tables with these new rules with immediate effect.

Install PHP

PHP is our scripting language which process code to display dynamic content. Basically, it runs the domain scripts, connects to their respective databases and serves the contents over to your web server to display.  To install latest PHP and some of its important modules use the following command from the terminal:

#apt install php libapache2-mod-php php-mysql
# php -v
PHP 7.2.3-1ubuntu1 (cli) (built: Mar 14 2018 22:03:58) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
with Zend OPcache v7.2.3-1ubuntu1, Copyright (c) 1999-2018, by Zend Technologies
# systemctl restart apache2

I have installed PHP 7.2.3 on my server. You can confirm it's version from the command line using the above command. There are a lot of other PHP modules available to enhance the functionality of PHP. To see the available module PHP modules list and libraries, pipe the results of apt search into less , a pager which lets you scroll through the output of the commands:

#apt search php- | less

You can use the arrow keys to scroll up and down, and press q to quit. To display more information about each module, you can use the command apt show package_name . For example, to know more about the use of the PHP-bz2 module, you can type this as below:

# apt show php7.2-bz2
Package: php7.2-bz2
Version: 7.2.3-1ubuntu1
Priority: optional
Section: universe/php
Source: php7.2
Origin: Ubuntu
Maintainer: Ubuntu Developers <[email protected]>
Original-Maintainer: Debian PHP Maintainers <[email protected]>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 52.2 kB
Provides: php-bz2
Depends: php-common (>= 1:35), ucf, php7.2-common (= 7.2.3-1ubuntu1), libbz2-1.0, libc6 (>= 2.14)
Homepage: http://www.php.net/
Download-Size: 10.2 kB
APT-Sources: http://mirrors.linode.com/ubuntu bionic/universe amd64 Packages
Description: bzip2 module for PHP
This package provides the bzip2 module(s) for PHP.
.
PHP (recursive acronym for PHP: Hypertext Preprocessor) is a widely-used
open source general-purpose scripting language that is especially suited
for web development and can be embedded into HTML.

The description part explains this module purpose in short. Depending on your requirement, you can choose the required module package and install it using the commandapt install .

You need to restart Apache to make these changes effective. Now you can create a PHP info page under the domain document root to confirm its version and modules list.

# cd /var/www/html
#echo "<?php phpinfo(); ?>" >> info.php

You can browse the URL >>http://ServerIP/info.php to confirm it's working.

PHP version

 

We've successfully completed the installation of LAMP stack on Ubuntu 18. Now, it's time to set up our WordPress blog. Let's install WordPress with the steps below:

Install WordPress

You can download the latest WordPress download from their Official Website and extract it to the document root /var/www/html to install it.

# apt install wget
# wget http://wordpress.org/latest.tar.gz
# tar -xvf latest.tar.gz -C /var/www/html/

Create MySQL Database for WordPress

Next, we’ll need to create a database and user for our WordPress installation, to do so, run the following command:

# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.7.22-0ubuntu18.04.1 (Ubuntu)

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> create database wpdatabase;
Query OK, 1 row affected (0.00 sec)

mysql> CREATE USER 'wpuser'@'localhost' IDENTIFIED BY '9RYiZ1fca$#RBrvaFpxwL&TYY';
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT ALL ON wpdatabase.* TO 'wpuser'@'localhost';
Query OK, 0 rows affected (0.00 sec)

We've connected to the MySQL shell and created a database named "wpdatabase" with a user "wpuser" for the WordPress installation. Next, you need to create the wp-config.php from the template wp-config-sample.php file and modify the MySQL settings in the configuration file with the one we created to start with our installation.

#cd /var/www/html/wordpress/
#cp wp-config-sample.php wp-config.php

I've modified the file settings with my created database details.

// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'wpdatabase');

/** MySQL database username */
define('DB_USER', 'wpuser');

/** MySQL database password */
define('DB_PASSWORD', '9RYiZ1fca$#RBrvaFpxwL&TYY');

/** MySQL hostname */
define('DB_HOST', 'localhost');

Configuring the Virtual Host

We can set up the virtual host for our WordPress site as below. By default, Apache listens on all IP addresses available to it. For all steps below, replace example.com with your domain name. I'm replacing it with my domain name mywordpressblog.com.

1. Create a copy of the default Apache configuration file for your site:

cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/mywordpressblog.com.conf

2. Edit the new mywordpressblog.com.conf configuration file by uncommenting ServerName and replacing example.com with your site’s IP or Fully Qualified Domain Name (FQDN). In my case, I've replaced with www.mywordpressblog.com. Enter the document root path and log directories as shown below, and add a Directory block before </VirtualHost> as below:

# cat mywordpressblog.com.conf

<Directory /var/www/html/wordpress>
Require all granted
</Directory>
<VirtualHost *:80>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
ServerName www.mywordpressblog.com

ServerAdmin [email protected]
DocumentRoot /var/www/html/wordpress

# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn

ErrorLog /var/www/html/mywordpressblog.com/error.log
CustomLog /var/www/html/mywordpressblog.com/access.log combined

# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf
</VirtualHost>

3. Create the directories referenced in the configuration file:

# mkdir -p /var/www/html/mywordpressblog.com/
# touch /var/www/html/mywordpressblog.com/access.log
# touch /var/www/html/mywordpressblog.com/error.log

4. Link your virtual host file from the sites-available directory to the sites-enabled directory and disable the default virtual host to minimize security risks:

# a2ensite mywordpressblog.com.conf
# a2dissite 000-default.conf

5. Reload Apache after making these changes.

# systemctl reload apache2

Now you can browse the following URL >> http://mywordpressblog.com/  to complete our installation.

WordPress › Installation

You can set your Admin credentials and Site title to complete the installation stage. Finally, you can access your admin area browsing the URL >>http://mywordpressblog.com/wp-login.php with the credentials created.

Admin Page

That's all! you have installed WordPress Successfully on your Ubuntu 18.04 server. Now you can go ahead and customize your WordPress Blog as per your requirements.

Read also :

I hope this article helped you to build your LAMP stack and install WordPress blog on top of it using Ubuntu 18.04. Please let us know your comments on this article.

Saheetha Shameer 12:50 am

About Saheetha Shameer

Self-motivated and dedicated Linux Administrator having 10 years of working experience on various web-hosting control panels and Unix distributions. I'm a quick learner and have a slight inclination towards following the current and emerging trends in the industry. I'm passionate about testing/reviewing new Linux applications and open source tools.

Author Archive Page

Have anything to say?

Your email address will not be published. Required fields are marked *

All comments are subject to moderation.