Installing & Load Balancing Nginx on CentOS 7 in Azure

In this article, you will learn to create multiple CentOS servers in Azure. They will be properly load balanced in a way that it incurs less cost without sacrificing any performance. To do this, let's start with a LAMP stack.

LAMP Stack

LAMP stack stands for Linux, Apache, MySQL and PHP. It has served the internet exceptionally well for a long time now.

Step 1: LAMP

Creating a VM in Azure is a no-brainer. I have used CentOS 7 for my servers. Let’s start creating a Linux server in Azure.

Open Azure Management Portal.

  • Click on Virtual Machine and then click New > Compute > Virtual Machine > From Gallery.
  • Select CentOS based > Open Logic 7.0 and click the right arrow.
  • Provide Server Name, Size, New User Name.

A common thing that I see a lot of people doing is that they uncheck Upload... option here and check Provide a password since it sounds easier at first. However, I would like to call out that providing a password may sound like an easier option, but in Azure CentOS the root login is disabled by default. In effect, you will keep typing in the password (or copy/paste) for sudo commands again and again. In any case, it becomes a pain very soon. I would strongly recommend following this article and use SSH Key instead. Once you have uploaded the certificate, click Next.

Azure Password

  • Create a Cloud Service if you don’t have it already.
  • Ensure that you use an availability set. It is a very important step to save you some cost.
  • Click next a couple of times and you are all set.
  • To connect to the server, you need to use the following command:
ssh -i YOUR.KEY -p PORT_NUMBER ACCOUNT_NAME@CLOUD_SERVICE.cloudapp.net  
  • You may avoid typing -i YOUR.KEY by copying your key inside ~/.ssh and rename it as id_rsa
  • Ensure that you change the permissions or you might not be able to connect to the server.
chmod 600 ~/.ssh/id_rsa  

Step 2: LAMP

To install Apache, run the following command:

sudo yum install httpd  

If you are coming from IIS world, you will be surprised at how simple it is :) Let’s test Apache. First of all, install a command line browser locally in the server. You can also use curl command (and skip this command if you like). I like having a command line browser since I can interact with the websites which is something you can’t do with curl.

sudo yum install lynx  

The web server is not started yet. Start it by using the following command.

sudo systemctl start httpd  

Try browsing the local host by using:

lynx localhost  

You should be able to see a page shortly and that would mean your web server is up and running.

Step 3 : LAMP

Up next is mySQL. This guy is a little tricky. You can find detailed directions here. It is the download part that makes it tricky. If you learn Lynx it will be quite simple for you to do directly at the server without using FTP. At first, I would recommend taking a look at the link using a regular browser. It will ask you to go to the download page and select your package from here. Pick your version and copy the link. I picked RHEL 7’s download link = http://dev.mysql.com/downloads/file.php?id=450705

Now, in your CentOS server run the following command:

lynx http://dev.mysql.com/downloads/file.php?id=450705  

You will be presented a browser where you need to press tab to No thanks, just start my download link. Tab to the link and hit enter to download to the current location. It is quite simple if you simple follow the instructions in the page. Once done, you will have the rpm file locally downloaded. You need to install the rpm package next. For me, I ran the following command:

sudo rpm -Uvh mysql-community-release-el7-5.noarch.rpm  

Let’s find the repository list for mySQL:

yum repolist all | grep mysql  

As of today, mySQL 5.7 is in beta, and hence I would rather avoid it. From the output from the previous command you would have noticed that the latest version is already enabled in the repo-list. You just need to install it using:

sudo yum install mysql-community-server  

To start the service and check the status of mySQL you should use the following commands:

sudo service mysqld start  
sudo service mysqld status  

Step 4: LAMP

Great! Let’s get on with PHP.

sudo yum install php php-mysql  

Soon enough, PHP is up and running too! Once installed, restart Apache service so that PHP gets loaded.

sudo systemctl restart httpd  

Let’s create a simple info page and ensure things are working correctly locally. Run the following command to create a test.php file in Apache’s root directory.

sudo vi /var/www/html/test.php  

Paste the following PHP code and save the file.

<?php echo gethostbyname(trim(`hostname`)); ?>  
<?php phpinfo(); ?>  

Try browsing to this file, and if you have followed everything correctly so far, you should see a page which displays the server’s IP address along with PHP information.

lynx localhost/test.php  

Awesome! LAMP is all set locally. Does that mean you can access it from outside yet? Well… not yet! That’s because by default the ports are blocked to the outside world. There are multiple ways in which you can open the port. I will show you the easiest way, aka... UI :)

Step 5: Ta-da! Open your website to the world :-)

Logon to your Azure management portal navigate to your CentOS VM. Click Add button to add a new end point.

Add Load balancer endpoint

Notice that the 2nd radio button is disabled. That is because I don’t have any existing load balanced set. For the first server in your load balancer, you need to create a new Stand alone endpoint.

imgAzure2

Specify the details as follows, and ensure that the Checkbox for Create a load balanced set is checked.

imgAzure3

Provide an appropriate name for the load balanced set and proceed. A few minutes later, your server will be all set for access to the world.

imgAzure4

Go to your cloud service in Management Portal, and check your DNS name. If you try to hit your DNS, it should succeed. Typically, it looks like http://YOUR_CLOUD_SERVICE.cloudapp.net/

Step 6: Add another server to share load

With so many people hitting at your website, let’s add another server as a front end to share the load.

The steps are quite similar to Step 5, with a slight difference. This time around, you will need to join the Load Balancer instead of creating it.

imgAzure5

Provide other details in the next screen, and you are set with these 2 servers ready to take the load. You can add as many servers as you like!

imgAzure6

Step 7: What if you would like to save some cost?

Let’s say you have more than 2 servers and the load is not as much as you anticipated. While you work to make the site better, why incur that extra cost? Azure has auto-scaling built in and it is really straightforward to set it up. Set it up according to your preferences and the extra servers will be deallocated when not in use. It is a pretty simple way to save you considerable cost by shutting down the servers that are not in use.

imgAzure7


LEMP Stack

The new age internet needs a cutting edge web server and there are a plenty of limitations in Apache! Nginx has provided a great alternative to Apache. With Nginx in, LAMP stacks turns into LEMP stack (NGINX is pronounced EngineX). Read my book: Nginx - From Beginner to Pro to learn more.

Step 1: Installing Nginx

Let’s stop Apache by running the following command.

sudo service httpd stop  

You will need to add repo for nginx using the following command.

sudo vi /etc/yum.repos.d/nginx.repo  

Add the following text and save the file:

[nginx] 
name=nginx repo  
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/  
gpgcheck=0  
enabled=1  

You are now ready to install nginx.

sudo yum install nginx  

Just like Apache, you can start the service and view the status by using the following commands:

sudo service nginx start  
sudo service nginx status  

Your nginx is now ready. Since you have already added the load balancing end points, it should just work. Try it out and you will see your default nginx page.

Step 2: Check PHP

In previous post we created a test.php file, let’s copy that file to the root of nginx.

sudo cp /var/www/html/test.php /usr/share/nginx/html  

If you try accessing your site /test.php, you will notice that the file is simply sent back at text. Let’s ensure that PHP is installed along with fastCGI Process Manager using the following command.

sudo yum install php php-mysql php-fpm  

Step 3: Configure NGINX for PHP
Edit the configuration file for Nginx using:

sudo vi /etc/nginx/nginx.conf  

You will find a line that reads worker_process 1; That will cause only 1 worker process to spawn and it is a good idea to spawn more if your server has enough resources. You need to raise it to N where N is the number of CPUs you have, and save the file. Restart nginx.

sudo service nginx restart  

Open php-fpm’s config by typing the following command:

sudo vi /etc/php-fpm.d/www.conf  

Replace apache with nginx in the following code block. Save the file and exit.

; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
; will be used.
; RPM: apache Choosed to be able to access some dir as httpd
user = nginx  
; RPM: Keep a group allowed to write in log dir.
group = nginx  

Now restart the service by typing:

sudo service php-fpm restart  

Open the nginx configuration file:

sudo vi /etc/nginx/conf.d/default.conf  

I am using a root outside of location, since I want to host multiple sites on the same set of servers. My /etc/nginx/conf.d/default.conf looks as follows:

server{  
    return 404;
}
server {  
    listen       80;
    server_name  www.example.com example.com;
    root         /usr/share/nginx/html/example;

    location / {
        #try_files $uri $uri/ /index.html =404;
        index  index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {
        root           /usr/share/nginx/html/example;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
}
  • Notice the first server block that returns 404. This is to ensure that YOUR_CLOUDSERVICE.cloudapp.net doesn’t work! I am assuming you would like to have a real domain name. If your cloudserver.cloudapp.net works, you should remove the first server block.
  • Change server_name with your domain names. Notice that I have used both www.example.com and example.com. This is to ensure that this server block is responsible for my domain name completely.
  • Change the root path
  • The location has 2 lines. The first line is useful in scenarios like AngularJS. The 2nd line is good enough for your index page.
  #try_files $uri $uri/ /index.html =404;
  index  index.html index.htm;
  • Also notice, that the lines for location in PHP section has been changed. Please update your conf file and exit.
  • Restart nginx
sudo service nginx restart  
  • If you try to upload into the server with account name, it won’t work due to permissions. Let’s change the permissions so that you own root folder.
sudo chown VM_USER_NAME -R /usr/share/nginx/html  
  • Create the folder example in the location as mentioned and upload your files. You are good to go from hosting perspective.

At this point, you have a properly load balanced 2 web front end servers with nginx & mySQL installed. You can upload your stuff easily to these servers.

Hope this helps!

Rahul Soni

⌘⌘ Entrepreneur. Author. Geek. ⌘⌘

Kolkata, India

Subscribe to Attosol Technologies

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!