Moving sites from old VPS cpanel sever to EC2

Just some notes as I had to do this a number of times today. There are likely still some efficiencies to be gained but this is pretty quick.

I am running  Apache 2.4 with per user web directories for this post. One of the reason’s this works os well with per user web directories is that I can visibly see progress without having to change my local machine’s host files, and I can name my EC2 servers user accounts the same as my cpanel server’s accounts, and it makes the commands a bit less confusing.

Adding a user to your EC2 Apache server configured with per user web directories means if I add a user I can serve files from whatever directory you configure in your .conf files


The UserDir directive specifies a directory out of which per-user content is loaded.

I have my server configured read files in public_html inside of each user home directory.

UserDir public_html

Say I have a user on my EC machine rbowen

If I visit the URL

I will see any files i have put into /Home/rbown/public_html on my new server. This is  similar to how my old cpanel server is configured.

Let’s start, and again there are a plethora of ways one could do this. This is just how I did it today.

sudo adduser butlerraines

This command will create a new home directory and user on my EC2 instance.

sudo su butlerraines
cd ~

Here I switch user (su) and impersonate butlerraines. The command sudo will allow me to switch users easily and without a password (note I didn’t set one when I added the user)

The command cd ~ puts me in the home directory of the current user so now my current path is /home/butlerraines

Let’s make our public_html directory.

mkdir public_html

Now let’s check your permissions.

Ok! So let’s navigate to public_html

We will use an absolute path just to make sure we know where we are.

cd /home/butlerraines/public_html

Now we have files over on the old Hostgator cpanel server we want to move. And granted you could pull all these files down by FTP, either zipped or unzipped and push the back up. Or really a ton of different ways to do this.

In this post I simply use rsync.

As always I like to make sure programs and utilities are on my machine so I run the which command.

which rsync

and it tells me it is in fact on my machine, and I can tell it is in path. If “path” is a foreign concept to you just know if the command or executable is in the path you can run with from just about anywhere.

[butlerraines@ip-xxx-xx-x-xxx public_html]$ which rsync

It’s there!

Cool. Ok here we go. I am in /home/butlerraines/public_html and about to sync the files from my old Hostgator Cpanel VPS to my EC instance.

rsync -azvv /home/butlerraines/public_html/


Let’s go through this because it could be confusing, and I purposely did it this way for simplicity. Yeah I know. Sounds backwards.

Using the rsync command I am going to attempt to log into my old server, and go to the path holding the files I want to copy

The trailing slash / tells rsync to only get the contents of /home/butlerraines/public_html/ and not the directory public_html itself.

Then once I have logged into this directory successfully, make a copy of those files on my EC2 instance which I have purposely set up with the same username and directory structure.

When I click enter it will ask for the password to user butlerraines on my old Hostgator VPS, and if successful start making copies of the files.

Step 2. Move the database

Exporting the database tables from the old VPS

Since my old VPS  is utilizing cpanel, I’m going to make an assumption here and say anyone reading this is probably used to managing their database in a GUI interface like phpMyAdmin. We could do all this from the command line on the old VPS server but here we do it from cpanel and phpMyAdmin.

On my old VPS I log into my account via cpanel and navigator to phpMyAdmin

I select the database I need and export the tables from that database. Why is that underlined, well you can export the database itself but I just want the tables for this post.

I exported the tables from the database to my local machine. It is not pictured here but I selected the option to gzip my .sql file. You don’t have to depending on the size of you database. You probably don’t have to at all, but I did. Ok moving on.

This exported to my Downloads folder on my local machine.

Copying the exported .sql file to a EC2 instance

Now that I have my exported database on my local machine I need to move it to my remote EC2 instance.

Since I am already able to SSH into my EC2 machine with my SSH keys (if I couldn’t I wouldn’t have even been able to do the first part of this post), I can easily apply that to a similar protocol, scp.

SSH into an EC2 instance looks like this


ssh -i /Users/username/.ssh/filename.pem</code>

The first part is an example path on a local machine to a private ssh key.

The second part is the standard way to connect to a remote machine username@ipaddress.

scp looks very similar


scp -pr -i /Users/username/filename.pem /Users/username/Downloads/database_1.sql.gz


Basically we are copying the database file from the Downloads folder on a local machine to the ec2-user home directory of the EC2 instance. Don’t be confused by the fact am putting in /home/ec2-user instead of the specific user directory where we placed our original files. MySql is a bit agnostic to where the .sql files is stored. We just need to know where to find the sql quickly, and it will be in /home/ec2-user

Importing the tables to the new database

We have exported the database (well the tables from the database) from the old VPS and now have pushed the .sql file into home directory of the ec2-user on the new EC2 instance.


Now let’s log back into our EC2 instacne


ssh -i /Users/username/.ssh/filesname.pem


This should put us in the home directory of ec2-user. If you want to be sure you can always


cd ~


I always like to take a peek by listing all the files if the directory. You should see your database file in there ie database_1.sql.gz




Now you need to login to mysql from the command line on the EC2 instance.


mysql -u username -ppassword



  • I set up mysql on this machine long before I wrote this post and setting up mysql is out of scope of this post.
  • You mysql username and password is mostly likely not nor it should be the same password as your Linux users on your EC2 machine.
  • That is not a typo above. The flag is -p for accepting a password and then there is no space after the -p. Alternatively you can simply put ‘mysql -u username -p’ and upon enter it will ask for a password.
  • I’ve already created the database I want to import so yes I cheated a bit.

Now that your end your command prompt will change a bit


mysql> show databases;


mysql> show databases will show you all the databases you have created.


mysql> use database_1;


use database_1 selects the database you will be using. Put if your database name of course.


mysql> source database_1.sql;


source database_1.sql puts the tables in the export into the database_1 (or whatever you named it).


mysql> exit;


mysql> exit gets you back to the normal command line.

Step 3. Hook up the files and the database.

Today I was moving Drupal and WordPress sites from my old Hostgator VPS to a new Amazon EC2 instance.

Inevitably you will have to make some adjustments to each web applications configuration files.

This particular example was a WordPress site. You can tell by the database table names. So I will need to edit the wp-config.php files in /home/butlerraines/public_html and add in the new database name, database username and database password.

I find it easier to switch users than to worry with file permissions. Currently I am logged in as ec2-user but I want to edit the wp-config files as butlerraines.

Earlier I showed you how to switch users.


sudo su butlerraines


now let’s go back to /home/butlerraines/public_html


cd /home/butlerraines/public_html


If you look in this directory you will see wp-config.php.




Most Linux machines will have a variety of text editors you can use. The one I like is called nano

You can open and edit the wp-config.php file with nano and make the changes you need to connect your database.

Now go visit visit the URL

and you will see things starting to happen.

Installing Drupal 8 from the command line without Composer or Drush

You might read my tutorial on Installing Drupal 7 from the command line first as it is more in depth. I am troubleshooting an error I have installing Drupal 8 with Composer and trying to discern if it is my LAMP stack or Drupal 8 or Composer by process of elimination.

Since I am using Apache User Directory to serve my web application from public_html in the users directory, I like to make sure I start in the user home.

[user@ip-xxx-xx-x-xxx public_html]$ cd ~

I then go into the public_html directory.

[user@ip-xxx-xx-x-xxx public_html]$ cd public_html

I have a habit of listing the contents of directories I enter just be sure it looks like I want it to.

[user@ip-xxx-xx-x-xxx public_html]$ ls

I download the latest version of Drupal to public_html using wget. I find the latest version of Drupal go to This version at the time of this post is 8.5.5 so I will download it.

[user@ip-xxx-xx-x-xxx public_html]$ wget

I list all the files in public_html and should see drupal-8.5.5.tar.gz

[user@ip-xxx-xx-x-xxx public_html]$ ls

It is a zipped fie. I will unpack the zipped files directly into the directory, public_html.
[user@ip-xxx-xx-x-xxx public_html]$ tar --strip-components=1 -xvzf drupal-8.5.5.tar.gz

This will extract all contents of drupal-8.5.5.tar.gz but also leave the drupal-8.5.5.tar.gz in public_html. If you want to you can remove it from public_html.

[user@ip-xxx-xx-x-xxx public_html]$ rm drupal-8.5.5.tar.gz

Go to the url where you are attempting to install Drupal 8 and start the web installer.

Depending on how your server is set up you might see the following errors. This is because “Drupal” did not have permission to create files or directories  on the server. No worries you will just change them.


So let’s mikes the files directory first in /sites/default/

Starting in public_html

[user@ip-xxx-xx-x-xxx default]$ cd sites

[user@ip-xxx-xx-x-xxx default]$ cd default

[user@ip-xxx-xx-x-xxx default]$ mkdir files


Now back to web installer and refresh. We see a different error.

Since this error has to do with the directory being writable I will just add write permissions for the all, the user, group and other users.

[user@ip-xxx-xx-x-xxx default]$ chmod a+w files

Basically this simply is
chmod who=permissions filename where a = all= user, group, and other and w = write.

That cleans that error up. There is only one more. The Settings file does not exist.

Drupal give you and example settings file you can copy and rename. One thing to note,
in this tutorialyou are currently in the default directory or /sites/default relative to public_html. Relative to your user home directory you are at /user/public_html/sites/default. Relative to the root of your file system you are at /home/user/public_html/sites/default.

It is always good to know where you are. Again if you are following this post you are current in the default directory.

We need to copy default.settings.php and rename it settings.php.

[user@ip-xxx-xx-x-xxx defaultl]$ cp default.settings.php settings.php

Alright we are almost set. One more error. Now we have to make the Settings file writable.


Similar to what we did above. Let’s go ahead and grant write permissions to all. However we will need to lessen the permissions later.

[user@ip-xxx-xx-x-xxx default]$ chmod a+w settings.php


And now let’s finish the install by configuring Drupal to connect to our database. This post assume you have a database set up already.

500 Days Sober: My Life is not perfect

I enjoy sharing every 10 days of sobriety. With a milestone like 500 days I hoped I’d have something profound to say. I don’t, but consistency is an essential aspect to my life. So here goes…

My life is not perfect. I do not expect it to be. I don’t want it to be. Perfect is unrealistic and exhausting.

Had my life been “perfect” I would not be the man I am today. I grew out of challenge, heartache, and darkness; much of it self-imposed.

I realize my circumstances are better than most.

Life is ambiguous. A tension between who you are and who you will be; our facticity and our transcendence.

I balance being ok with who I am today while seeking to be the best person I can be tomorrow.

I am grateful for what I have in life. I experience a lot of joy.

I also battle depression and angst. I worry about my niece and nephew. I wish I did more for my family. I wish we were closer.

I have the most supportive friends in the world. I hide at home many nights because I’m still learning how to connect with people without alcohol and drugs.

I have a yoga practice I love. I beat myself up over it. I call myself lazy. I know I need to keep breathing / moving / trying. Sometimes I don’t. I don’t know why. Breathe.

I remember being an asshole. I sometimes think I am too nice. I say the wrong thing all the time. I know better. I still do it. I think I’m being funny. I’m not.

I wish I was impeccable with my words. Some people find the humor. Some find me off-putting. I don’t have to please everyone. I can’t please everyone.

For all my accomplishments and responsibilities, I still can’t manage to keep my apartment clean.

I often wonder what’s more important, helping solve today’s problems or solving interplanetary travel? Does anything truly matter after you die? Where should I invest my time?

Am I happy? Happiness is so temporary. Tomorrow I could be sad.

I prefer stronger and more resilient rather than happy or sad.

I am all these things. Often all at once.

I like myself even if I think I have small hands.

Namaste y’all.

Day 496: Graduating and looking for your first job? Do what Kate did.

Finding a job right out of school with no experience is challenging.

With graduation season upon us and s many new graduates trying to figure out how to land their first job, I thought I’d share how Kate Butcher and I met.

A few weeks ago I was invited to speak to an organization at Georgia College I helped found nearly 20 years ago. I hoped to pass along three points of wisdom I had distilled from my own journey.

  • Take opportunities before you think you are ready.
  • Seek out, do not be afraid of, feedback.
  • Suspend your need to be right.

The next morning I received a LinkedIn message from Kate referencing one of the points of the speech, how it resonated with her and a request to learn more about an entry level sales position at SalesLoft. Her message was personalized, relevant and to the point. And maybe most importantly the message was more about me than her 

To test her seriousness, I asked if she could be at the SalesLoft office at 9am on Friday, less than 36 hours of receiving her initial message. She agreed to meet on Friday.

Upon meeting her she was poised and prepared, and as I learned more about her I realized she had an aptitude for technology. She double majored in marketing and management informations systems.

Many of my colleagues, my network and I hire for positions that don’t have tracks in traditional colleges, and I thought maybe Kate was not aware of all of her possibilities when she inquired about the sale roles. I have the good fortune to work with very strong female technology leaders at SalesLoft. I asked for favors so Kate could spend time with them and learn about their teams.

We don’t know where it will end up, but she got her foot in the door by being the right amount of assertive and respectful, and she found a friend and mentor in me.


Day 460: A dedicated yoga practice changed our lives

460 days (Butler) and 768 days (Flo) sober: A dedicated yoga practice changed our lives.

I started to get to know Flo in May of 2015. We both signed up for a 3 month Ashtanga Yoga immersion at Balance Yoga.

As you learn Ashtanga, teachers begin to talk to you about the benefits of a dedicated practice. 

They first convince you to practice Mysore style which is intimidating.

Mysore is self-led. There is no teacher up front telling you what to do. You memorize the sequence, and you do the same sequence every fucking day but somehow it’s always different.

No music. Just breathing.

When you enter you think everyone is going to look at you. You haven’t learned about drishti yet.

Everyone looks like advanced. You are a beginner. Everyone is beginning something.

There is talk of a daily practice, 6 days a week at sunrise except on moon days. What the fuck is a moon day? You will quickly begin to appreciate moon days.

You begin to notice what affects your body. To maintain your practice you begin to sleep more and eat healthier.

An article this week read, “Watching live music is better for your wellbeing than yoga.” Using a heart monitor and psychometric tests “experts” measured “wellness” after a concert and a yoga “session”.

Sutra 1.14: sa tu dīrghakāla nairantarya satkāra-ādara-āsevito dr̥ḍhabhūmiḥ

Practice becomes firmly grounded when it has been cultivated for a long time, uninterruptedly, with earnest devotion.

1.20 śraddhā-vīrya-smr̥ti samādhi-prajñā-pūrvaka itareṣām

śraddhā means having faith you are on the right path.

Practice must be pursued with trust, vigor, memory, absorption and discernment.

1.21 tīvra-saṁvegānām-āsannaḥ
The goal is near for those who apply themselves intensely.

1.22 mr̥du-madhya-adhimātratvāt-tato’pi viśeṣaḥ

Even among these, there is further differentiation of mild, mediocre and extreme intensity.

The benefits of yoga are found with dedicated, consistent practice over time. The immersion was about committing to the practice in this way. The article is talking about one session which is simply exercise

This is something we didn’t fully understand until years later. We were not able to commit back then, but our teachers never gave up on us. We are committed now and have faith we are on the right path. We help each other.


Unregister custom post types in WordPress Themes

Remove Wordpress Post Types

I have a few WordPress themes that are just easy to work with. I know them inside and out and can spin up a site very quickly. However, these themes come with custom posts types I don’t need or want, and I like to keep the content management workflows as lean as possible.

To remove unwanted custom post types set by themes you simply unregister them post type.

//working with a theme that is easy to builid in but come with some posts
function custom_unregister_theme_post_types() {
global $wp_post_types;

if ( isset( $wp_post_types[“portfolio”] ) ) {
unset( $wp_post_types[ “portfolio” ] );

if ( isset( $wp_post_types[“testimonial”] ) ) {
unset( $wp_post_types[ “testimonial” ] );

add_action( ‘init’, ‘custom_unregister_theme_post_types’, 20 );

In this particular theme there are a number of custom post types. Chapter 12, “Two is Two Many,” of Understanding Software by Max Kanat-Alexander has always stuck in my mind. If I find myself cutting and pasting code there is I can probably find a more generic solution. He writes, “I do this as soon as I’m tempted to have two implementations of something.”

This function could very easily start to look like this:

//working with a theme that is easy to builid in but come with some posts
function custom_unregister_theme_post_types() {
global $wp_post_types;

if ( isset( $wp_post_types[“portfolio”] ) ) {
unset( $wp_post_types[ “portfolio” ] );

if ( isset( $wp_post_types[“testimonial”] ) ) {
unset( $wp_post_types[ “testimonial” ] );

if ( isset( $wp_post_types[“review”] ) ) {
unset( $wp_post_types[ “review” ] );

if ( isset( $wp_post_types[“blog”] ) ) {
unset( $wp_post_types[ “bog” ] );

add_action( ‘init’, ‘custom_unregister_theme_post_types’, 20 );

So you can begin to make this more generic by storing the post types in an array and making the rest of the function generic. PHP’s foreach construct provides an easy way to iterate over arrays.

//working with a theme that is easy to builid in but come with some posts
function custom_unregister_theme_post_types() {
global $wp_post_types;

$arr = array(‘portfolio’,’testimonial’, ‘course’);

foreach ($arr as $value) {

if ( isset( $wp_post_types[$value] ) ) {
unset( $wp_post_types[$value] );

add_action( ‘init’, ‘custom_unregister_theme_post_types’, 20 );

Day 440: Finding Ways to Keep Butler Sober.

A few hours ago my friend Rachel drove away. Several of us shared one last meal at a favorite Ethiopian spot before she headed to Michigan to start her new job.

Rachel has been a pillar of Balance Yoga Atlanta for much longer than I have practiced there. Her dedication to her practice and her love for our community is inspiring.

As I make excuses to stay in bed on Monday mornings (the Walking dead ran over), Rachel is there when the shala doors open. Whether 3 people or 15, she is there, in the front, doing her practice. Her practice, the practice she needs to do for her with no judgement; just simple dedication.

I met Rachel over 4 years ago after I started practicing Ashtanga yoga at Balance. The first time we had a real conversation was at a shala community potluck. Overweight, probably drunk and with a thick Southern drawl I felt out of place at a yoga vegan potluck. She noticed and was kind enough to start talking to me.

When I “decided” to stop drinking on Jan 1st 2017 I did not know Rachel well, but at a point when I needed support the most, she simply starting being there.

I put “decided” in quotes because originally I only committed to a few months of not drinking. I had practiced for three years , and I could barely make it through half primary series, and I was perpetually injured and sick. I hypothesized not drinking for a few months would allow my body to heal and build strength. I knew I need to stop drinking completely but was afraid of that commitment.

It didn’t occur to me that Rachel cared about me and my sobriety until one weekend after a hike she posted, “Finding ways to keep Butler Raines sober. Today’s activity was a 3 hour hike at Arabia Mountain.”

Since then we have been on many hikes, ate many brunches and had many conversations about life. She is always there encouraging me to practice yet reminding me to take the rest my body needs and to not judge myself for any of it.

Why she decided to care so much and take the time to help me I don’t know, but I know I am sober today,  and I am a better man because she did.

I look forward to practicing together again soon.


Transferring Drupal Apache Solr configuration files to EC2 Solr instance.

I decided to put Apache Solr on a separate EC2 instance. A requirement of this module is that you use the core configuration files from the Solr API module. If it was on the same server we could just copy the files but since this is a different server we need to move them either from server to server or local machine (laptop or desktop) to the Solr server.

We will use the secure copy protocol which is based on SSH secure shell protocol. The command is scp.

You need to locate the fully qualified path to your private key. I am not sure where you store your but a common place to store your private ssh keys are /home/.ssh

You will need to public DNS of the server you are copying to.

I like to login and make sure that the program we need, in this case scp, is installed.

whereis scp

This will copy to the home directory.

scp -i /home/.ssh/my-key-pair.pem /path/solor_module

I think it easier to just copy to your home directory and then move (mv) or copy (cp) once you have it on the remove sever.

This all would have been a lot easier had I just put Apache Solr on the same instance as my Drupal website, but I like playing around.

Day 430 of not drinking: LinkedIn Helped Change My Life.

Butler Raines LinkedIn

As I stepped up to talk about our product vision, the question hit me, “How did this Southern boy from a town of 500 get here? Six years ago I was teaching high school chemistry.”

Sixteen years ago I set out to get a PhD in chemistry at the University of Florida. Although I enjoyed my research in nanomembranes and quantum dots, I gravitated to teaching.

Computers, and later the internet, always fascinated me so I started a website to help my students with their chemistry questions. A friend in computer science recommended Drupal, a platform written in PHP, as a framework for my question and answer forum.

Unfortunately, or maybe fortunately, I did not finish my PhD.
With my masters degree and hurt pride, I took a job as an chemist in Savannah before pivoting to teach a few years later.

Thinking it would be a good for my resume, I kept the chemistry website going. As the website grew, my skills grew out of necessity. SEO (my #1 skill on LinkedIn) began to drive traffic to the website. Higher traffic required me to learn how to optimize servers and databases. My teacher salary “inspired” me learn about ads, and the advent of social media changed everything.

I started freelancing as a web developer to supplement my income.

In 2008 I set up a LinkedIn profile. Based on my SEO knowledge, I made some assumptions on how LinkedIn search worked and optimized my profile around my experience in Drupal and PHP. I started meeting more people and landing more projects. One summer Randi, a recruiter for NDN, found me on LinkedIn. I took the job shortly after. It was the culmination of all the skills I developed since graduate school.

As NDN grew, we hired a VP of Product, and I met my first product mentor, Rob Sheppe. I joined his team shortly after.

One morning I woke up to a LinkedIn notification on my phone. It was a message from Kyle Porter asking to chat about “determining the future.” Yesterday I celebrated my two year anniversary at SalesLoft as Head of Product. I have grown like never before, and the people I work with at SalesLoft inspire me daily to be the best me I can be. Thank you.

Installing Software on Linux from Source Code

install from packages when possible
Sometimes the package manager  may not have the updated version.

In keeping with my previous posts I will use the program htop as an example. This time I will walk you through how to install a program on Linux from Source code.

What is source code?


Download the source code of Htop and compile it on your system.


wget is preinstalled on your Linux machine

Using Source Code

tar xzf htop-2.1.0.tar.gz
cd htop-2.1.0
sudo make && sudo make install

Compile htop from the Source on CentOS

Another option is to compile and install htop from the source. This option is useful when you want to install the latest version of htop.


Here is how to download the source and install htop from the source


Download the source files using wget


Wget is a free software package and command line tool used for retrieving files using widely-used Internet protocols like HTTP and FTP.

It is likely preinstalled on your Linux machine but as always we can check with our

which searches your for your not only for the executable but also if it is in the $PATH environment variable.

Is wget installed an in my path?

[ec2-user@ip-172-30-1-107 ~]$ which wget

yes it is here!

whereis locates source/binary and manuals sections for specified files.

To find the paths of $PATH environment variable

echo $PATH
[ec2-user@ip-172-30-1-107 ~]$ echo $PATH

This basically mean any executables in any of these path (directories) will excute from the command line regardless of where you are in the file system if you have the right permissions.