In this post, I am going to walk through on how to install LEMP stack on Google Cloud Platform (GCP). You have to create an account first and if possible try to get the 300$ free GCP credit.

If you want an alternative to Google Cloud Platform, you can either use Vultr or DigitalOcean, their service is a great alternative to GCP.

Creating new Instance

Now access the Compute Engine from the sidebar and let’s create a new instance. This instance will be running the LEMP stack.

Google Cloud Platform Products
Google Cloud Platform Products

Once you are on the page, create new instance and type in the credentials that you want the instance to have.

Google Cloud Platform Create an Instance
Google Cloud Platform Create an Instance

The important part is the Machine type as well as the Boot disk. Choose the machine type that’s suitable for your web application. For this example, I am choosing the machine that comes with 1.7GB memory. Other than that, because we are going to use Ubuntu, change the Boot disk to use Ubuntu 18.04 LTS.

Google Cloud Platform Boot Disk
Google Cloud Platform Boot Disk

You can also specify the type of the disk that you can use for this instance. They provide with 2 options, Standard persistent disk and SSD persistent disk, choose the later one as the performance is multiple times better.

Lastly, allow HTTP and HTTPS in the Firewall section of the configuration.

Google Cloud Platform Firewall Settings
Google Cloud Platform Firewall Settings

The creation of the instance will take about 30 seconds and once it’s ready, SSH into the machine.

Google Cloud Platform SSH into an Instance
Google Cloud Platform SSH into an Instance

If you see a new window popup, then you are in the terminal instance. Hooray, L of the LEMP is up and running.

Google Cloud Platform SSH Terminal
Google Cloud Platform SSH Terminal

Installing Nginx

The next step is to install the latest version of Nginx, this is pretty straightforward and you can find it from the Ubuntu Software Repository.

Searching Nginx from Google Compute Engine Terminal
Searching Nginx from Google Compute Engine Terminal

But before you install Nginx, make sure to run sudo apt update to get the latest listing/repository. Then when it’s done fetching, run sudo apt-install nginx and press enter when it prompt you continue.

By right you will be able to preview the default NGINX page if you access the IP address of the instance, but because Ubuntu makes use of Firewall, we need to write some rules and enable it first. To check whether it’s enabled or not, you can run sudo ufw status. But highly likely you will get “Status: inactive”.

Before we enable it, add the rules so that it can be accessed by using http and https by running `sudo ufw allow 80` and `sudo ufw allow 443`. In addition to that, also add ssh rules `sudo ufw allow ssh`. Now let’s enable the Firewall by typing this command `sudo ufw enable`, press Y and let it run.

Now you can try to access the ip address for the instance and by right you will see this default NGINX page.

Default NGINX page
Default NGINX page

Installing MySQL

The next step is to install MySQL and this will be used to store the data of your website. Because the latest version of MySQL doesn’t use a password to authenticate users, we will be installing MySQL version 5.7. To install it, you can run this command sudo apt install mysql-server-5.7.

Next, in order to secure your installation, run sudo mysql_secure_installation and follow the steps that you see from the terminal (this will requires you to either agree or disagree with it).

Now let’s assign a password to the mysql user by running sudo mysql and query the mysql.users table to check the current authentication method that’s being used by the root user.

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

You will see its output to something like this.

+------------------+-------------------------------------------+-----------------------+-----------+
| 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 | *F152DB0F7988DBCDAE8B3835844FED248C8FFC08 | mysql_native_password | localhost |
+------------------+-------------------------------------------+-----------------------+-----------+
4 rows in set (0.00 sec)

So to change the auth_socket into the normal password, we need to run this alter command. ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your-password-here'; Now run, FLUSH PRIVILEGES; and let’s query it once again to double check.

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

This time you will see mysql_native_password instead of auth_socket and that means, we are ready to go.

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

Type exit and hit enter key to exit from the MySQL terminal.

Installing PHP

The last step for our LEMP stack is to install PHP and in this tutorial, it will be the lates version of PHP fpm which is PHP 7.2 fpm.

sudo apt search php7.2-fpm | grep 'php7.2-fpm'

And now let’s install it and configure it to work with NGINX.

sudo apt install php7.2-fpm

In addition to that, because we are using MySQL, we need the PHP extension for it. You can find any of the extensions by using the apt search command if you are not using MySQL.

sudo apt install php-mysql

Once you have done that, now let’s enable our NGINX to serve PHP files. The nginx configuration can be found in /etc/nginx/sites-available directory. In that directory, you will see 1 file called default and we need to edit that file.

In this case, I am going to use vim editor, but you can use nano or any other text editor that you have fond of. Let’s edit the file by typing vim default and now you will be able to edit the content of the file. You can move between lines by using the arrow keys and now navigate to the middle of the page inside the server block. To delete a character, use x character in your keyboard.

server {
        listen 80 default_server;
        listen [::]:80 default_server;

        # SSL configuration
        #
        # listen 443 ssl default_server;
        # listen [::]:443 ssl default_server;
        #
        # Note: You should disable gzip for SSL traffic.
        # See: https://bugs.debian.org/773332
        #
        # Read up on ssl_ciphers to ensure a secure configuration.
        # See: https://bugs.debian.org/765782
        #
        # Self signed certs generated by the ssl-cert package
        # Don't use them in a production server!
        #
        # include snippets/snakeoil.conf;

        root /var/www/html;

        # Add index.php to the list if you are using PHP
        index index.html index.htm index.nginx-debian.html;

        server_name _;

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;
        }

        # pass PHP scripts to FastCGI server
        #
        #location ~ \.php$ {
        #       include snippets/fastcgi-php.conf;
        #
        #       # With php-fpm (or other unix sockets):
        #       fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
        #       # With php-cgi (or other tcp sockets):
        #       fastcgi_pass 127.0.0.1:9000;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #       deny all;
        #}
}

By default the # means it’s being commented. To uncomment it, we just need to remove it so that later when we restart NGINX, it can take effect.

Starting from the top let’s enable it to read PHP files and we can do that by adding the index.php into the list.

# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html index.php;

Now, for the inslide the location block we just need to uncomment it to allow php run through the socket.

location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    #       # With php-fpm (or other unix sockets):
    fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
    #       # With php-cgi (or other tcp sockets):
    #       fastcgi_pass 127.0.0.1:9000;
}

And finally, the last location block which deny access to .htaccess files, if Apache’s document root concurs with nginx’s one.

location ~ /\.ht {
    deny all;
}

To save the configuration, use :wq and then you will come back to the terminal. restart nginx by running sudo systemctl restart nginx.

Test It Out

To test it out, let’s create a php test file. Using vim again type sudo vim /var/www/html/index.php and when you are inside vim, press i character and then enter the following.

<?php
phpinfo();

Save and exit from vim by typing :wq and now try to access your IP address with the info.php at the end of it. http://your-server-IP/index.php and you will be able to see your PHP configuration.

LEMP phpinfo
LEMP phpinfo