In this tutorial, 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 tutorial, I will install each package manually.
Table of Contents
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 using systemctl command:
#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
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
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
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.
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 <firstname.lastname@example.org> Original-Maintainer: Debian PHP Maintainers <email@example.com> 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 command
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.
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:
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 webmaster@localhost 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.
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.
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.
In this tutorial we leaned to build your LAMP stack and install WordPress (install wp-cli) blog on top of it using Ubuntu 18.04. I hope you enjoyed reading and please leave your suggestions in the below comment section.