LAMP is an acronym that historically referred to a certain stack of software, namely Linux, Apache, MySQL, and PHP. Nowadays, any component in the acronym could be swapped out with an alternative, but it’s my feeling that a Linux system is incomplete without a LAMP environment, to include desktop workstations as well as headless servers. It isn’t just that the platform was used for most of the early web and is still a competitive platform for the web, today, but also that it makes an excellent application platform for the home or office network.

This howto is going to demonstrate how to begin to set up the LAMP development environment on an Ubuntu 16.04 desktop system. It is important to note that this means the package selection and the configuration are driven by the need to have a wide set of libraries and tools for development and a permissive configuration, and is not concerned with the kind of security hardening required for a server that would be directly accessible from the Web. In fact, this article assumes the reader wants a system that can perform double-duty as a development workstation and a functional node on a home or business network with controlled access. We will configure our apps to use a secure connection over HTTPS, despite having created a walled garden, simply because web applications that are developed for the Web must be secure, these days. It is best to develop against that standard by default.



Just one convention. Any place in the text where you see orange text, remember to replace those values with your own.


Here’s the plan

This is not a hard howto to follow, but it is a bit lengthy, and the order in which the steps are performed does matter. Here is my proposal, then:

  1. Give your system a static network address
  2. Modify the hosts file
  3. Install the software from the Ubuntu repositories
  4. Configure MySQL and Apache2 to start automatically on boot
  5. Create a folder for containing web development projects
  6. Modify the Apache2 configuration
  7. Define the default host as a virtual host
  8. Create a self-signed SSL certificate
  9. Define the SSL configuration for the default host
  10. Enable the secure site in Apache2
  11. Restart Apache2 and test HTTPS and PHP at the same time


Give your system a static network address

Frankly, it is not necessary to set a static IP address on a development machine where you are serving and editing files, but the moment that you decide that you would like to be able to allow another device on the network to access the apps you are developing is the moment that you are going to need a static IP address. Rather than waiting to cross that bridge some time in the future, let’s go ahead and set it up and plan on developing on it that way.

Let’s open the network configuration app by first opening the System Settings app using the gear icon on the launcher. (By the way, you’ll notice that I have moved the launcher to the bottom edge of my screen. If you want to do that, too, you can find out how in the previous article on Ubuntu, The Post-Installation Configuration of Ubuntu 16.04.)

Now click the Network icon to open the network configuration app. When I do it, I can see that my router has automatically assigned the IP address to my system.

How to set up a home network is outside the scope of this article. I am going to assume for demonstration purposes that you have a typical Class C network, and that addresses on it look something like In this example, our network is, which means that all of the addresses will begin with 192.168.1. and the last number identifies each machine, specifically. The /24 means that your network’s netmask value is The router on this network will take up the address, and it will serve as our network DNS and gateway, as well. Finally, the LAMP workstation we are going to build will reside at address Since the router automatically assigned this address, we know it is available.

Here are the IPv4 settings for our hypothetical server:

DNS Servers:,,

Click the Options… button in the bottom right corner of the applet.

Select the IPv4 Settings tab. Note that the Method control is currently set to Automatic (DHCP). That means that every time the system is booted, it requests an IP address from the DHCP server (the router), then the router assigns an unused address to your system. In this case, the router on my network has assigned the address *.201. The problem is that every time the system starts it could be given a different address, and remember that our goal is to set up a development workstation that also offers LAMP applications on the local network, and that means establishing a reliable address that can be added to the hosts file of other nodes on the network.

Change the Method control by selecting Manual from the flyout menu. Next, click the Add button and enter the values as given in the text above, to match your own network’s specific details. Please note that your own information could be different in too many ways to cover in this article, but if the address range is different only in the third section of the IP address (eg. the 1 in might be 0, 1, 2, 3, etc.), that is a normal variation, and the gateway value will likely still be /24 or Click the Save button when you are done.


Modify the hosts file

Go ahead and close the app window. Use the keyboard combination Ctrl-Alt-T to open a terminal window, and enter the following command:

sudo nano /etc/hosts

The hosts file acts as the highest authority of hostname-to-IP address mapping on each system. When Ubuntu was installed, its hostname was automatically assigned an address on the loopback network, but that network is only accessible from your machine. Each machine recognizes addresses in that range to be local to themselves.

Using the arrow keys to navigate within the hosts file, remove the line that looks like this:         ubuntu-virtual

Use your down arrow key to add a new line to the bottom of the hosts file. In subsequent articles, I will be appending virtual host names to this file. For now, add this line to the bottom of the file:     ubuntu-virtual

And it should look a lot like the image below. Save the changes by using the Ctrl-O (letter “o”) combination, then pressing the Enter key. Ctrl-X closes the nano editor and returns you to the console.


Install the software from Ubuntu repositories

Let’s begin by installing prepackaged LAMP software, graciously crafted by the Ubuntu software packagers. Note the caret character on the end of the name tells APT that it is a pattern and not a singular software package.

sudo apt install lamp-server^

Enter “y” into the terminal and press the Enter key.

Soon, a dialog will pop up and ask for a password to be used for the MySQL administrative user. Type in a password, then use your Tab key to highlight <OK>, and then press the Enter key when you are ready.

Repeat those steps to confirm the new password for the MySQL root user.

The installation then finishes up. We have more software to install.

With the terminal still open, paste the following command into it and press the Enter key.

sudo apt install php php-all-dev php-bcmath php-bz2 php-cli php-curl php-date php-gd php-gnupg php-imap php-intl php-json php-mbstring php-mcrypt php-pgsql php-sqlite3 php-xml php-xmlrpc php-zip

This will install PHP 7 and various extension modules. This list is only a tiny subset of the PHP modules available from the Ubuntu repositories, and if you ever need additional modules, you can always install them later.

You will be asked to confirm the installation. Enter “y” into the terminal and press the Enter key.


Configure MySQL and Apache2 to start automatically on boot

The next step is to set the local database server and web server to start up when ever the system starts up, and so we will run MySQL and Apache2 as system services, or daemons, that are always on. This takes surprisingly little processing power or memory. Even on my 13-year-old PCs, there is no noticeable difference in system performance with these services running full-time in the background.

Paste the following command to enable MySQL as a system service:

sudo systemctl enable mysql

The output should resemble the following:

Synchronizing state of mysql.service with SysV init with /lib/systemd/systemd-sysv-install...
Executing /lib/systemd/systemd-sysv-install enable mysql

You can start MySQL right now using the following command:

sudo systemctl start mysql

…and if you want to stop it:

sudo systemctl stop mysql

You can check the status of the MySQL server with this:

sudo systemctl status -l mysql

The Apache2 server will be handled in exactly the same way. To enable the web server to start at system boot time, paste the following into the terminal and press the Enter key:

sudo systemctl enable apache2

…and start the web server with:

sudo systemctl start apache2

At this point you might want to open up a browser window and enter your system’s address into the browser’s address input box. You can use the hostname of your system, such as http://ubuntu-virtual, or you can instead use your IP address, like You can also use the loopback network address or hostname, and http://localhost, respectively. You should find the default Apache2 landing page.


Create a folder for containing web development projects

There is no one right place to put your web projects. I like to put my projects in my home folder, in a subfolder named Websites. The document root for the default website is located in the filesystem at /var/www/html. You can create the new folder using the Ubuntu file manager, or you can do it from the terminal. In the terminal, make sure that you are in your home directory by entering the following command:

cd ~

The cd command means “change directory”, and the tilde character (~) is a shortcut meaning the home directory. Create the new folder with the following command:

mkdir Websites

That’s where our virtual hosts will go. Enter the command below to list the visible contents of your home directory:

ls -l


Modify the Apache configuration

At this time, let’s modify the main Apache configuration file to make our system permissive enough for development duty. In the terminal window, enter the following:

sudo nano /etc/apache2/apache2.conf

Navigate down the using your arrow keys until you find the section similar to the screen grab below. Add a new Directory section defining permissions broadly for the Websites folder and inherited by the virtual hosts in it. Paste in this addition, using your username in the path to your Websites subfolder:

<Directory /home/applebiter/Websites/>
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted

Save the file by first using the keyboard combination Ctrl-O (letter “o”) and then pressing the Enter key. Use Ctrl-X to close the nano editor.


Define the default host as a virtual host

When you decide to run virtual hosts on your system, Apache needs the default host to be redefined as a virtual host, itself.

Virtual hosts are defined in corresponding configuration files in the Apache configuration directory, /etc/apache2/sites-available. Note that the configuration for the default server MUST be loaded first, therefore we typically give that file a name that will keep it at the top of the list, alphabetically and numerically, 000-default.conf. Look inside the configuration folder by entering the following command into the terminal:

sudo ls -l /etc/apache2/sites-available

The output should resemble the following:

-rw-r--r-- 1 root 1332 Mar 19 2016 000-default.conf
-rw-r--r-- 1 root 6338 Apr  5 2016 default-ssl.conf

As you can see, Ubuntu has already created a default virtual host definition and a default secure socket layer configuration, too. We will get to the latter later, and attend to the former forthwith.

Enter the following command into the terminal to open the virtual host definition for the main server:

sudo nano /etc/apache2/sites-available/000-default.conf

It should look something like the image below.

This file is not only the configuration for the default host, but also a template that can be used to define new virtual hosts as we add them. With that in mind, I am going to trim all of the commented code out of the file except for the ServerName directive. Also, I will modify the name of the log file to reflect the hostname. The end result should resemble the following, substituting your own specific hostname and email address, if any:

<VirtualHost *:80>
    ServerName ubuntu-virtual
    DocumentRoot /var/www/html

    ErrorLog ${APACHE_LOG_DIR}/ubuntu-virtual_error.log
    CustomLog ${APACHE_LOG_DIR}/ubuntu-virtual_access.og combined

When you’re finished, save the file and close it.


Create a self-signed SSL certificate

There is a lot to know when it comes to SSL and encryption on the Web, but for the sake of brevity, I will simply say that self-signed certificates are not insecure, nor does the use of self-signed certificates fall short in any way of best practices when used on a private network. The warnings that the use of self-signed certificates produces in browsers are of a certain hyperbolic pitch which may leave the lay user with the wrong impression about the suitability or the appropriateness of self-signed certificates in general. Even web-facing hosts might have legitimate reasons to use self-signed certificates, however, and if anyone tells you otherwise, you tell them to go pound sand.

In any case, we are going to use them, and we’re going to like it.

First, we will create a folder inside the Apache2 configuration folder to hold the private key and the certificate generated for our secure host. Use the following command to accomplish that goal:

sudo mkdir /etc/apache2/ssl

The openssl tool will allow us to generate a key and a certificate in one command:

sudo openssl req -x509 -nodes -days 3650 -newkey rsa:4096 -keyout /etc/apache2/ssl/ubuntu-virtual.key -out /etc/apache2/ssl/ubuntu-virtual.crt

It’s going to be an interactive process, and it should end up resembling the following text. Remember when you get to the line that is emboldened below to make sure that the value you enter matches your hostname as defined in the hosts file, earlier in this article.

Generating a 4096 bit RSA private key
writing new private key to '/etc/apache2/ssl/ubuntu-virtual.key'
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:North Carolina
Locality Name (eg, city) []:Youngsville
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Applebiter Consulting
Organizational Unit Name (eg, section) []:Home
Common Name (e.g. server FQDN or YOUR name) []:ubuntu-virtual
Email Address []


Define the SSL configuration for the default host

In the terminal, open the web server’s default-ssl configuration file with the following command:

sudo nano /etc/apache2/sites-available/default-ssl.conf

As I did with the other configuration file in this folder, earlier, I am going to strip out most of the commented code and use it not only to define the SSL configuration for the default host, but also as a template upon which the SSL configuration of future web apps will be based. After editing the file to match the actual details of my configuration, it resembles the text below:

<IfModule mod_ssl.c>
 <VirtualHost _default_:443>
 ServerName ubuntu-virtual:443
 DocumentRoot /var/www/html

 ErrorLog ${APACHE_LOG_DIR}/ubuntu-virtual_error.log
 CustomLog ${APACHE_LOG_DIR}/ubuntu-virtual_access.log combined

 SSLEngine on
 SSLCertificateFile /etc/apache2/ssl/ubuntu-virtual.crt
 SSLCertificateKeyFile /etc/apache2/ssl/ubuntu-virtual.key

 <FilesMatch "\.(cgi|shtml|phtml|php)$">
 SSLOptions +StdEnvVars
 <Directory /usr/lib/cgi-bin>
 SSLOptions +StdEnvVars

 # BrowserMatch "MSIE [2-6]" \
 # nokeepalive ssl-unclean-shutdown \
 # downgrade-1.0 force-response-1.0


Enable the secure site in Apache2

We now need to enable the SSL module in Apache, and we can do it using the following command:

sudo a2enmod ssl

When we execute this command, we are presented with output instructing us to restart the server for the changes to take effect. Before we do that, however, let’s make one more change. We are going to activate the SSL configuration, which is not activated by default. To do that, put the following command into the terminal and press the Enter key:

sudo a2ensite default-ssl


Restart Apache2 and test HTTPS and PHP at the same time

First, let’s create a very simple PHP script in the document root of our default web host using the following command:

sudo nano /var/www/html/info.php

And now, in the empty editor, type the following text. When you are finished, save and close the file.


The script we just created invokes a built-in function in PHP which renders its configuration to the screen. Hopefully, that configuration is exactly what we will see when we open the web browser.

Restart the Apache2 web server since we have made configuration changes:

sudo systemctl restart apache2

Remember that we are using self-signed certificates. I am going to show you how both Google Chrome and Firefox treat the situation when we open our default host over a secure web connection using the hostname or IP address of your system, such as https://ubuntu-virtual/info.php or

Let’s begin by opening the site in Firefox.

Well, yes, in fact your connection is secure, it’s just that a Trusted Authority, which is a 3rd party whom you pay to endorse your claim that you are indeed who you say you are, has not been given their fee, and so your website is made to look like a criminal endeavor by default.

In Firefox, click the Advanced button, then the Add Exception… button, and finally click the Confirm Security Exception button to make Firefox relent and let you into your own web host. When the page loads, browse the details of your PHP installation at your leisure.

Now let’s see how Google Chrome presents our new website. Open up Chrome and again, enter the URL to your system into the input box, such as https://ubuntu-virtual/info.php or

Chrome matches Firefox by blandly asserting a falsehood. Click the ADVANCED link on the bottom left.

Chrome finally relents, after making you click Proceed to ubuntu-virtual (unsafe).


Mission accomplished

You just installed and configured the LAMP stack on your system, but there is more work to do to finish erecting the development part of the environment. The remaining work will be demonstrated in upcoming articles. Thank you for participating in open source culture, and good luck.

Share this:

Set Up the Basic LAMP Stack on Ubuntu LTS 16.04
Tagged on:                         

Leave a Reply