• Call: +1 941 462 4550

DevOps stories 1: working with a high traffic e-commerce portal

Looks like this is a good idea to write down first person stories of various DevOps – Cloud migration scenarios that we come across.

In this particular case we have a beast of a server with 32 processors with 8 cores each & 256 of RAM running LAMP stack, CakePHP & X-cart shopping cart. And yes, everything is dead slow.

Cleaning up the X-cart cache

By default (?), the cache is at /var/www/html/cache or [DOCTUMENT_ROOT]/cache. If there are too many files, you will not be able to delete the files. The following commands can help.


touch /root/agileblaze/cache-file-list.txt #empty file
find . -name '.js' | grep -vFf /root/agileblaze/cache-file-list.txt | xargs /bin/rm -f
find . -name 'sql.
' | grep -vFf /root/agileblaze/cache-file-list.txt | xargs /bin/rm -f
find . -name 'rf*.php' | grep -vFf /root/agileblaze/cache-file-list.txt | xargs /bin/rm -f

MySQL

There are tons of issues like a db that is not upgraded, joins without indexes etc. We decided to make use of the RAM & have MySQL MYISAM temporary files in there for faster access. Don’t forget to create the required directory and add the necessary entries /etc/fstab to persist the changes over reboots.

/etc/my.cnf is changed as follows

tmpdir = /var/mysqltmp # changed from /var/lib/mysql/tmp

Now that we have some room to look into other matters, things should be easier.

We also had the non-so-friendly max connections error. We increased in the max connections from the default.

# MAX CONNECTIONS
max_connections = 300 #Sat Apr 30 03:35:25 CDT 2016

Urban Airship Push Notification Integration

Push Notification is one of best way to interact with app users. Every mobile developer knows the importance of push notification in mobile apps. Push Notification provides near real-time updation of informations such as news,score updates,messages etc., to users. iOS provides APNS (Apple Push Notification Service) to send push notification data to applications installed on Apple devices. There are many third party push notification services are available  like Parse,Urban airship, Carnival,Push woof etc. The benefits of using third party Push Notification service are,

  • – Reduce Your code.
  • – Save Your  time and effort.
  • – Manage the notifications easily.

This section will explain some simple steps to be followed to send push notification to iOS platform via Urban airship dashboard. The steps are given below.

  • 1. Registration and login
  • 2. Create Your first app in Urban airship
  • 3. Set up your xcode project.
  • 4. Send your first Push Notification

Registration and login

You need to create an account in Urban Airship using an email id and password. There are many pricing plans available. Select a pricing plan or select a free starter account. Click here to view the available account plans. After the successful registration, click manage your apps from Urban Airship dashboard to get started.

Create Your first app in Urban Airship

After the registration is completed, add your first app. You need to specify the following details to create an app.

App Name

The name of your app.

App Icon

Upload an app icon.

Production status

You must select whether your app is in development mode or production mode. When you are setting up development and production apps, you have to configure them for push services. See the APNS Setup documentation for detailed instructions.

Select Platform that will use Urban Airship

Select your platform here. The available platforms are iOS, Android, Windows, Blackberry etc.

After selecting the iOS app platform, save your app.

app fields

Set up your xcode project

You have created an app in previous section. Then you need to set up the xcode project. First, create an xcode project for push notification. Then you have to follow some steps to set up your project. The steps are  explained below.

  • Download Urban airship SDK

Download the latest version of  libUAirship from Urban Airship. Unzip the SDK and add the libUAirship static library and headers into your project. Click here to download the latest version of Urban Airship SDK.

airshipKit

  • Manage Build Settings

In the project’s build settings set “Enable Modules” field to “Yes” and “Link Frameworks Automatically ” to “Yes”.

  • Add Urban Airship SDK

The SDK can be included using the Urban Airship static library(iOS 7+) and Urban Airship Embedded framework(iOS 8+). The static library and embedded framework have different setup procedures.

      Including Urban Airship SDK using Embedded framework(iOS 8+)

-Include Airshipkit

Add  Airshipkit.XcodeProj into your app project in xcode.

-Link against embedded framework

adding framework

Add the Airshipkit.framework file to the Embedded binaries section in the general tab for your project to link against the embedded framework.

Including static library (iOS 7+)

– Search paths

Screen Shot 2016-04-20 at 1.00.23 PM

Ensure that your project’s header search paths under build settings include the Airship directory.

– Linker Flags

Add –objC –lz –lsqlite3 linker flag to prevent “Selector Not Recognized” runtime exceptions and to include linkage to libz and libsqlite3. The linker flag –force_load<path to library>/ libUAirship<version.a> may be used in instances where using the –objC linker flag is undesirable.

Screen Shot 2016-04-20 at 1.01.21 PM

– Link against the static library

In the libraries section in the Build Phases, add the libUAirship.a file to the link binary to link against the static library.

link binary

– Add the Urban Airship resource bundle

Add the UrbanAirshipResources.Bundle file to the Copy Bundle Resources section in the Build Phases tab for your target.

  • Enable Background Notification

You can enable Background notification by enabling Remote notifications of Background mode under the target’s capabilities section.

remoteNotification

  • Create AirshipConfig.plist

To manage your production and development application profiles, the Urban Airship SDK uses a .plist configuration file named AirshipConfig.plist. You can create two application within your Urban Airship account:one for development and one for production. Create  an AirshipConfig.plist and set the following values in your .plist file.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" 
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>detectProvisioningMode</key>
  <true/>
  <key>developmentAppKey</key>
  <string>Your Development App Key</string>
  <key>developmentAppSecret</key>
  <string>Your Development App Secret</string>
  <key>productionAppKey</key>
  <string>Your Production App Key</string>
  <key>productionAppSecret</key>
  <string>Your Production App Secret</string>
</dict>
</plist>
  • Import the required header files

Import the AirshipKit header files to your application delegate.

Import AirshipKit (Swift)

#import<AirshipKit/ AirshipKit.h>

You must import the individual headers if your application uses the static library.

#import “UAirship.h”

#import “Uaconfig.h”

#import “UAPush.h”
  • Starting Urban Airship Services

Inside your application delegate’s application:didFinishLaunchingWithOptions:method,initialize a shared Uairship instance by calling Uairship takeoff.This will bootstrap the Airship SDK.

-(BOOL)application:(UIApplication*) 
didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{

         [Uairship takeOff:config];
}
  • Retrieving your channel ID

The channel ID is a unique identifier used to target pushes to a specific devices using the Urban Airship API.You can always get the channel ID using the following code.

ObjC:

            NSString *Channelid=[Uairship push].channelID;
            NSLog(@”My channelID:%@”, Channelid);

Swift:

            Let Channelid=Uairship.push().ChannelId
            print(”My channelID:%@”, Channelid)

ChannelID initially comes back as NULL on your apps first run.It will be created and persisted during registration.

  • Enabling User Notifications

By default User notifications are disabled.To enable notification write the following code. Set the user notification types on [Uairship push]. Sounds, alerts and badges are the default types. The library will register to receive notification after the user push notifications are enabled.

[UAirship push].userNotifictionTypes=(UIUserNotificationtypeAlert| UIUserNotificationtypeBadge|UIUserNotificationtypeSound)

[Uairship push].userpushNotificationEnabled=YES;

After all this steps your project’s AppDelegate.m file looks like  below

AppDelegate.m

#import <AirshipKit/AirshipKit.h>

#import “AppDelegate.h”

@interface AppDelegate ()

@end

@implementation AppDelegate

-(BOOL)application:(UIApplication*) 

didFinishLaunchingWithOptions:(NSDictionary*)launchOptions

{
         [Uairship takeOff:config];

         //Set the icon badge to zero

         [[Uairship push]resetBadge];

         [UAirship push].userNotifictionTypes=(UIUserNotificationtypeAlert|   

         UIUserNotificationtypeBadge|UIUserNotificationtypeSound)

         [Uairship push].userpushNotificationEnabled=YES;

}

Send your first push Notification

  • Adding Test Devices

You need to add a list of test devices in Urban airship console before sending your first notification. To setting up test devices, select Audience. You can see a text box for entering  list of device identifiers. You can enter up to 100 device identifier here. After entering the device identifiers save the list.

add audience

To send your first push notification,navigate to Messages Overview ,located under the Messages tab,and click + Messages. You can see a Message box here and type your notification message here. Before sending the notification you have to select the audience and delivery options. The audience are,

All Devices

Single Device

Segments

segments are groups of audience that you can create using combinations of location,tags and lists.

Test Devices

Test devices are predefined devices created by an account administrator.

selecting audience

Select an audience from the list. Then navigate to the delivery section and you can see two options here.

Immediately

Deliver the message immediately.

Schedule

Deliver the messages according to the scheduled time

delivery

If all has been set up correctly,click Confirm and Send Now.

send 1st

You  have sent your first push notification!!!

We use Zeroshell and its awesome :-)

Many of the Free Softwares (GPLed) IMHO (author’s personal opinion) struggles with marketing or reaching to mass audiences. The effort by Zeroshell to reach more audiences by the peculiar “viralware” model is appreciated.

 

We use Zeroshell Firewall on quite a few of our networks and are happy with it.

 

Viralware is a word I just coined ?!

Mosh aka mobile-shell

Mosh_demo_screenshot

Stumbled upon Mobile shell (Mosh) which allows persistent connection over intermittent connections, VPN – WiFi – networking roaming etc. Its quite useful especially when we have tons of nodes across multiple cloud providers & resulting attempts of their attention grabbing. Automating few things in a CRM made us  end up setting up a Postfix mail server after something like more than a decade, got frustrated over the nearly non-existent internet provided by Asianet DSL & all credit of this goes to them.

 

TL;DR Here is a quick guide to get Mosh working on Mac & GNU/Linux flavours.

 

Mosh uses UDP. Yes, you heard it right.

By default it uses 60000 to 61000 for establishing connections. We would need to open up some of these ports, say a subset of this in the fire wall mechanism that we use to get access to the servers.

There is a client & a server

I missed out this part ! Well, we need to install Mosh on the client and the server. (ie apt-get install mosh or yum install mosh on the servers too BOFH.)

On Amazon / AWS / EC2 cloud,

Open up few UDP ports in the security groups. We opened up 10 ports.

On DigitalOcean or any other provider open the ports in your firewall.

Client side installation:

On Mac,  we ran into issues with libprotobuf

> mosh migrate2cloud.com
dyld: Library not loaded: /usr/local/lib/libprotobuf.7.dylib
  Referenced from: /usr/local/bin/mosh-client
  Reason: image not found
Died at /usr/local/bin/mosh line 201. 

The solution is to upgrade Brew (well why shouldn’t one use brew ?)

brew update ; brew upgrade ;  brew remove libprotobuf ; brew install libprotobuf

will do the magic. If not,  we can try

         brew remove mosh ; brew install mosh

as well. If its doesn’t work, RTFM & the FAQ 🙂

Another issue we ran into was the locale & UTF-8 encoding. We fixed it by installing the locale in the client and server and exporting the following environment variable to the bash profile.

# for mosh
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
export LC_CTYPE=en_US.UTF-8
export MM_CHARSET=utf8
export LC_COLLATE=”en_US.UTF-8″
export LC_TIME=”en_US.UTF-8″
export LC_NUMERIC=”en_US.UTF-8″
export LC_MONETARY=”en_US.UTF-8″
export LC_MESSAGES=”en_US.UTF-8″

You load the environment variables by doing the following in bash.

. ~/.bash_profile   # don’t miss the dot at the beginning

Firewalls, Tunnelling, NAT

It may not work just yet as you may have to deal with NAT traversal and other nasty things. Creating an SSH tunnel can solve these issues.

mosh –ssh=”ssh -4 -R 2222:localhost:22 -i /Users/migrate2cloud/keys/ssh-key”  root@server.com

Reattaching a detached Mosh:mobile-shell is not possible. But we can run screen inside mobile shell.

do pkill mosh-server instead … or pgrep mosh-server -> kill etc

PS: if you use CIRU.org, things may be different for you.

That’s it. DigitalOcean guys have come up with a  nice write up here which is very helpful. There is also an Android client and iOS client in the making. On GNU/Linux I use KDE Konsole & on Mac iTerm : these are 2 good tools that are very useful IMHO.

Install Magento2 in Nginx Server Using Command Line

Magento-2-Banner

 

Installing magento2 in Ubuntu 14.04 with Nginx web server.

Prerequisites:

 1.PHP:

Version 5.5.X or more

Required PHP extensions:

PDO/MySQL

mbstring

mcrypt

mhash

simplexml

curl

ext-xsl

gd2, ImageMagick 6.3.7 (or later) or both

soap

intl

2.Mysql 5.6.X

3.Nginx.

 Create basic nginx configuration file for magento2.

# vim /etc/nginx/sites-available/magantositename

Add the following configuration files in nginx,

 

##########################

server {

listen 80;

 root /var/www/magento2; #Use you mangeto2 location

index index.php index.html index.htm;

 server_name yuor_magento.siteurl;

#location / {

#try_files $uri $uri/ /index.php?q=$uri&$args;

#}

   location /setup {

       try_files $uri $uri/ @setuphandler;

   }

# Rewrite Setup’s Internal Requests

   location @setuphandler {

       rewrite /setup /setup/index.php;

   }

    location / {

       index index.php index.html;

       try_files $uri $uri/ @handler;

   }

    # Rewrite Internal Requests

    location @handler {

       rewrite / /index.php;

    }

     location /pub/static {

         try_files $uri $uri/ @static;

    }

     location @static {

          rewrite ^/pub/static/(.*)$ /pub/static.php?resource=$1? last;

    }

 error_page 404 /404.html;

 error_page 500 502 503 504 /50x.html;

location = /50x.html {

root /usr/share/nginx/www;

}

#pass the PHP scripts to f stcgi socket

location ~ \.php$ {

               try_files $uri =404;

               fastcgi_pass unix:/var/run/php5-fpm.sock;

               fastcgi_index index.php;

               fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

               include fastcgi_params;

               fastcgi_read_timeout 900s;

#Magento 2 Developer Mode

               fastcgi_param MAGE_MODE “developer”;

      } 

}

 

#########################

 

create a symlink in /etc/nginx/sites-enable/magantositename

 # ln -s /etc/nginx/sites-available/magantositename /etc/nginx/sites-enable/magantositename

 

Restart PHP handler php5-fpm and nginx

 #  service php5-fpm restart

 # service nginx restart 

Create database and database user for magento2

login to mysql using root user and password:

#  mysql -u root -p

## mysql> CREATE DATABASE <magentodbname>;

## mysql>  GRANT ALL ON <magentodbname>.* FROM magentodb@localhost IDENTIFIED BY <magentodbpasswd>;

 

Steps to install Magento2

 Change the directory where to download and install Magento2.

 # cd /var/www/

 Download the magento2 zip file from github

 # wget https://github.com/magento/magento2/archive/develop.zip

 # unzip develop.zip

# mv magento2-develop magento2

 Change the ownership to your webserver user name. Typically it is www-data

 # chown -R www-data:www-data magento2

 # cd magento2

Change the permissions as follows,

 # find . -type d -exec chmod 700 {} \;

# find . -type f -exec chmod 600 {} \;

make the file magento file executable  in the directory bin

# chmod +x bin/magento

Install magento using command line,

# ./bin/magento setup:install –base-url “http://your_site_url/” –db-name “magentodbname” –db-user “magentodb” –db-password “magentodbpasswd” –admin-firstname “yourname” –admin-lastname “yourlastname” –admin-email “your_email” –admin-user “magenoadmi” –admin-password “magentoadminpasswd” –language “en_US” –currency “USD” –timezone “America/Chicago” –use-sample-data –use-rewrites=1

 

Here you will get your Language, Currency and Time zone using the following magento command.

Language:

# ./bim/magento info:language:list

Currency:

# ./bim/magento info:currency:list

Time Zone:

# ./bim/php magento info:timezone:list

 Once the installation is completed you will get the SUCCESS message at the end of installation.

You can access the magento admin interface using the random  generated URL while installing Magento2.

You can check the URL using magento command line.

# ./bin/magento info:adminuri

 You will get the admin URI as,

Admin URI: /admin_8mdvzn

You can  change the the Admin URI in <your Magento install dir>/app/etc/env.php.

Then you can access admin page as http://yuor_site_url/admin_8mdvzn/

 

magento-admin

 

You can access the magento2 home page at the installed URL as http://yuor_site_url.

It will look as below,

magento-2-home

 

cloud vendors and interoperability

It’s Phab! That makes your life easier

We have been using plenty of different tools for tracking bugs/product management/project management/to do lists/code review; such as ClearCase, ClearQuest, Bugzilla, Github, Asana, Pivotal Tracker, Google Drive etc. We found Phabricator as a “Too Good To Be True” software engineering web application platform originally developed at Facebook. It has code review, wiki, repository browsing,tickets and a lot more to make Phab more fabulous.

Phabricator is an open source collaboration of web applications which help software companies to build better software. It is a suite of applications. Following are the most important tools in phabricator :
Maniphest – Bug tracker/task management tracker
Diffusion- source code browser
Differential – code review tool that allows developers to easily submit reviews to one another via command line tool when they check in code using Git or Subversion
Phriction – wiki tool

How to setup and configure the code review and project management tool – Phabricator

Installation

Server – 4GB Digital ocean droplet
OS – Ubuntu 14.04

1. Install dependencies

apt-get install mysql-server apache2 dpkg-dev php5 php5-mysql php5-gd php5-dev php5-curl php-apc php5-cli php5-json

2. Get code

#cd /var/www/codereview

git clone https://github.com/phacility/libphutil.git

git clone https://github.com/phacility/arcanist.git

git clone https://github.com/phacility/arcanist.git

3. Configure virtual host entry

#add below lines

#######################################################################

DocumentRoot /var/www/codereview/webroot
RewriteEngine on
RewriteRule ^/rsrc/(.*) – [L,QSA]
RewriteRule ^/favicon.ico – [L,QSA]
RewriteRule ^(.*)$ /index.php?__path__=$1 [B,L,QSA]
Order allow,deny
allow from all
#######################################################################
4. Enable the virtual host entry for phabricator.

# a2ensite phabricator.conf
# service apache2 reload

5. Configure the MySQL database configuration for phabricator

– create database
# /var/www/codereview/phabricator/bin/config set mysql.user mysql_username
# /var/www/codereview/phabricator/bin/config get mysql.pass mysql_password
# /var/www/codereview/phabricator/bin/config get mysql.host mysql_host
# /var/www/codereview/phabricator/bin/config storage upgrade
-tweak mysql

Open /etc/mysql/my.cnf and add the following line under [mysqld] section:

sql-mode = STRICT_ALL_TABLES

#service mysql restart

Set the Base URI of Phabricator install

# /var/www/codereview/phabricator/bin/config set phabricator.base-uri

(eg: phabricator.your-domain.com)

Configure Outbound Email – External SMTP (Google Apps)

Set the following configuration keys using /var/www/codereview/phabricator/bin/config set value

– metamta.mail-adapter -> PhabricatorMailImplementationPHPMailerAdapter
– phpmailer.mailer -> smtp
– phpmailer.smtp-host -> smtp.gmail.com
– phpmailer.smtp-port -> 465
– phpmailer.smtp-user -> Your Google apps mail id
– phpmailer.smtp-password -> set to your password used for authentication
– phpmailer.smtp-protocol -> ssl

Start the phabricator daemons

You can start all the phabricator deamons using the script
# /var/www/codereview/phabricator/bin/phd start
To start daemons at the boot time, add this entry to the file /etc/rc.local

/var/www/codereview/phabricator/bin/phd start

Diffusion repository hosting with git

1. Install git

#apt-get install git

2. Create a local repository directory:

#mkdir -p /data/repo

3. Edit the repository.default-local-path key to the new local repository directory.

Go to the Config -> Repositories -> repository.default-local-path

4. Configure System user accounts

Phabricator uses as many as three user accounts. These are system user accounts on the machine Phabricator runs on, not Phabricator user accounts.

* daemon-user – The user the daemons run as

We will configure the root user to run the daemons

* www-user – The user the web server run as

We will use www-data to be the web user

* vcs-user – The user that users will connect over SSH as

We will configure git user to the vcs-user

To enable SSH access to repositories, edit /etc/sudoers file using visudo to contain:

#includedir /etc/sudoers.d
git ALL=(root) SETENV: NOPASSWD: /usr/bin/git-upload-pack, /usr/bin/git-receive-pack, /usr/bin/git

Since we are going to enable SSH access to the repository, ensure the following holds good.

– Open /etc/shadow and find the line for vcs-user, git.

The second field (which is the password field) must not be set to !!. This value will prevent login. If it is set to !!, edit it and set it to NP (“no password”) instead.

– Open /etc/passwd and find the line for the vcs-user, git.
The last field (which is the login shell) must be set to a real shell. If it is set to something like /bin/false, then sshd will not be able to execute commands. Instead, you should set it to a real shell, like /bin/sh.

– Use phd.user as our daemon user;
# /var/www/phab/phabricator/bin/config phd.user root
# /var/www/phab/phabricator/bin/config set diffusion.ssh-user git

5. Configuring SSH

We will move the normal sshd daemon to another port, say 222. We will use this port to get a normal login shell. We will run highly restrictive sshd on port 22 managed by Phabricator.

Move Normal SSHD

– make a backup of sshd_config before making any changes.

#cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup

– Update /etc/ssh/sshd_config, change the port to some othert port like 222.

Port 222

– Restart sshd and verify that you are able to connect to the new port

ssh -p 222 user@host

Configure and start Phabricator SSHD

We now configure and start a second SSHD instance which will run on port 22. This instance will use special locked down configuration that uses Phabricator to handle the authentication and command execution.

– Create a phabricator-ssh-hook.sh file

– Create a sshd_phabricator config file

– Start a copy of sshd using the new configuration

Create phabricator-ssh-hook.sh: Copy the template in phabricator/resources/sshd/ phabricator-ssh-hook.sh to somewhere like /usr/lib/phabricator-ssh-hook.sh and edit it to have the correct settings

##############################################################

#!/bin/sh

# NOTE: Replace this with the username that you expect users to connect with.
VCSUSER=”git”

# NOTE: Replace this with the path to your Phabricator directory.
ROOT=”/var/www/codereview/phabricator”

if [ “$1” != “$VCSUSER” ];
then
exit 1
fi

exec “$ROOT/bin/ssh-auth” $@
##############################################################

Make it owned by root and restrict editing;

#sudo chown root /usr/lib/phabricator-ssh-hook.sh
#chmod 755 /usr/lib/phabricator-ssh-hook.sh

Create sshd_config for Phabricator: Copy the template in /phabricator/sshd/sshd_config.phabricator.example to somewhere like /etc/ssh/sshd_config.phabricator

Start Phabricator SSHD

#sudo /usr/sbin/sshd -f /etc/ssh/sshd_config.phabricator

Note:-
Add this entry to the /etc/rc.local to start the daemon on startup.

If you did everything correctly, you should be able to run this;

#echo {} | ssh git@phabricator.your-company.com conduit conduit.ping

and get a response like this;

{“result”:”phab-server”,”error_code”:null,”error_info”:null}

You should now be able to access your instance over ssh on port 222 for normal login and administrative purposes. Phabricator SSHD runs on port 22 to handle authentication and command execution.

6. To create a git repository

Go to Diffusion -> New Repository -> Create a New Hosted Repository

Upgrade Phabricator

Since phabricator is under development, you should update frequently. To update phabricator:

– Stop the web server
– Run git pull in libphutil/, arcanist/, and phabricator.
– Run phabricator/bin/storage upgrade.
– Restart the web server.
Also you can use a script similar to this one to automate the process:
http://www.phabricator.com/rsrc/install/update_phabricator.sh