Setup WordPress on Linux in Azure

Every since Dreamhost started pushing my buttons with less than sub-par service, dead slow loading speeds and pointing fingers at WordPress plugins and themes I was using, I’ve been looking at alternatives for my hosting needs.

Among some of the options are Amazon and Azure Cloud offerings.


Microsoft’s Azure service has 2 huge advantages, in my opinion:

  1. Easier management interface
  2. 30 day credit so you can try service and even know how much would it cost you.

Amazon has free for 1 year program, which allows you to use their Small VM for free for a period of one year. But if you would like to try larger instances you would have to pay out of your own pocket. Which one to select will depend on your plan of migration. For me, Azure was the way to go.

These instructions are for Azure Linux installations, but they could also be used on Amazon AWS though some steps might require additional setup.

So let’s start.

Setup Linux VM

  1. First, let create VM. Click on a “+ NEW” sign in Azure Portal and follow promptsCreate New Virtual Machine
  2. We will choose Ubuntu 14.04 LTS as our baseChoose Ubuntu installation Image
  3. Give VM distinct name and set up size, user name and passwordSelect Virtual Machine Configuration
  4. Next step allows us to create Cloud Service for this VM or we can connect it to existing Cloud Service. Select Region (I use West US).
    Setup endpoints to your VM. You can set them up now or later. Make sure you enable: SSH and web port 80. Setup Cloud Service and Endpoints
  5. That’s it! That was easy. Now just wait about 5 minutes for your new VM to be fully provisioned. We are now ready to log in to our Azure VM.Virtual Machine Configuration complete
  6. Linux on Azure is installed without GUI, so the only way to login is through SSH. Use Terminal on Mac or any SSH client on Windows to connect to your machine. You will see your VM’s IP (public virtual IP, VIP) address on the right hand side of the Dashboard panelAzure Step 8 - Virtual Machine Dashboard 2
  7. SSH into your VM:
    $ ssh admin_user@your_ipaddress
  8. For some reason Azure does not set default root password, so let’s fix that:
    $ sudo passwd root

    You now can sudo your commands.

    $ su

Install infrastructure

All of the steps below are performed using SSH. I did not install Linux GUI nor RDP connection as they will add unnecessary overhead which translates into extra cost. If you are interested in installing GUI and RDP, refer to my post about Splunk Setup on Azure for instructions.

Assuming you SSH into VM,


  • Install Apache
    $ apt-get install apache2
  • Test by visiting http://your_ipaddress in the browser. You should see Apache start pageAzure Step 9 - Install Apache


  • Install PHP  and several essential php libraries by running
    $ apt-get install php5 libapache2-mod-php5
  • Restart Apache
    $ service apache2 restart
  • Test PHP by creating info.php file and accessing it via browser:
    $ nano /var/www/html/info.php
  • Type in:
  • Save the file via Ctrl+O, Return
  • Open http://your_ipaddress/info.php in your browser, you should see PHP Info page.Install and test PHP


  • Install MySQL by running
    # apt-get install mysql-server mysql-client
  • Enable MySQL support in PHP
    # apt-get install php5-mysql
  • Install X-Cache
    # apt-get install php5-xcache
  • Optionally, install phpMyAdmin, tool you can use to access your MySQL database
    # apt-get install phpmyadmin
  • Enable link between phpmyadmin and www [3]
    # ln -s /usr/share/phpmyadmin /var/www/html
  • Enable mod_rewrite and restart apache [5]
    # a2enmod rewrite
    # service apache2 restart
  • Test phpMyAdmin by accessing  http://your_ipaddress/phpmyadmin/

Set up Virtual Hosts [4]

… if planning to host more than one website

You can run more than one website on one machine, which might make sense for ease of administration. Enabling that is pretty easy with Apache.

  • Copy default config file and give it distinct name
    # sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/teterine.conf
  • Create separate folder for log delivery
    # mkdir /var/log/apache2/teterine
  • Modify file to include:
    # nano /etc/apache2/sites-available/teterine.conf
    DocumentRoot /var/www/html/teterine
    ServerAlias *
  • Change log delivery directory in config file
    ErrorLog ${APACHE_LOG_DIR}/teterine/error.log
    CustomLog ${APACHE_LOG_DIR}/teterine/access.log combined
  • Enable the new VirtualHost using the a2ensite utility and restart Apache2
    # a2ensite teterine
    # service apache2 reload 
    # service apache2 restart
  • You can test newly created site by modifying you hosts file to include
  • You can switch it back and forth by adding # in front of that line

Create Database

  • Access MySQL interface by executing
    mysql -u root -p
  • In MySQL interface create database, create user and assign privileges:
    -> CREATE DATABASE database_name;
    -> CREATE USER database_user@localhost IDENTIFIED BY 'secure_password';
    -> GRANT ALL PRIVILEGES ON database_name.* TO database_user@localhost;
    -> exit

Install WordPress

  • install unzip
    $ apt-get update
    $ apt-get install unzip
  • install php5-gd libssh2-php
    $ apt-get update
    $ apt-get install php5-gd libssh2-php
  • download WordPress
    $ mkdir temp
    $ cd temp
    $ wget
  • Unzip files
    $ unzip -q -d /var/www/html/teterine/
  • Change permissions
    $ chown -R www-data.www-data /var/www/html/teterine
    $ chmod -R 755 /var/www/html/teterine
  • Create Uploads directory
    $ mkdir -p /var/www/html/teterine/wp-content/uploads
  • Change permissions for Uploads directory
    $ chown -R :www-data /var/www/html/teterine/wp-content/uploads
  • Modify config file, or wordpress will do it for you
    $ cd /var/www/html/wordpress/
    $ cp wp-config-sample.php wp-config.php
    $ nano wp-config.php
    // ** MySQL settings - You can get this info from your web host ** //
    /** The name of the database for WordPress */
    define('DB_NAME', 'database_name');
    /** MySQL database username */
    define('DB_USER', 'database_user');
    /** MySQL database password */
    define('DB_PASSWORD', 'secure_password');

Rewrite rules [6]

  • WordPress usually updates .htaccess file with Rewrite rules. Recent apache installations ignore .htaccess Rewrite rules, which is more secure that way. So in order to accomplish same results as changing .htaccess file, modify you site config file instead. Below is sample what I added to my config file, as I had WP Multisite enabled. Add your things WordPress tells you to add to .htaccess file to site config file.
    $ nano /etc/apache2/sites-available/teterine.conf
    <Directory /var/www/html/teterine>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.php$ - [L]
    # add a trailing slash to /wp-admin
    RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]
    RewriteCond %{REQUEST_FILENAME} -f [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^ - [L]
    RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L]
    RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L]
    RewriteRule . index.php [L]


Special thank you to this resources that helped me go through process for setup and documentation
Tags: , , , , , , , , , ,