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.

Installing programs on Linux from command line.

To learn how how to install new programs on your Linux machine we will start by examining a preinstalled program called top.

The program top provides a real time dynamic view of resource usage and currently running processes. It can be invoked by the command top on the command line.

Typing top into the command line of your terminal starts the top application. The upper part is a summary of resource usage and the bottom part under the black line in the screenshot is the running processes.

You even see here that the user, ec2-user , is running top because I am!  The top part is showing me a summary of how many processes are running, how much CPU I am using and how much memory is available and being used, and the bottom part is breaking the usage out by each process. Pretty awesome.

If you played along and you now have this list of processes running on your Linux machine, you will want to get back to the command line prompt by simply typing “q” for quit.

This is not an exhaustive tutorial on top. The top program is used here so I can show you a few things that will help you when you install your first program on your Linux machine or EC2 instance.

OK I will show you one top specific command.


$ top -a 

will sort the top process list by memory so you can see which processes are taking up the most memory. This is very important in server management.

In the command  top -a the command is top and -a is an option you can set on the command. You can find options by reading the documentation on top.

Let’s explore top a little bit. This program came prepackaged but where is top “installed”? Another way to ask that is, “where is top’s executable binary?”

Linux has a few other commands that can help us answer that questions.

We have three pretty good options:

  • whereis
    • whereis locates the source, binary and manuals sections for specified files
  • which
    • which locates the executable file associated with a given command
  • find
    • find searches for files in a directory hierarchy

You might be thinking, I thought this tutorial was about installing new programs on a Linux machine. It is! Bear with me. I am hopeful the stuff I am explaining will save you a lot of headache in the future.

The goal of this tutorial is to install your first program on your Linux machine. We can get into specifics later let’s actually do what we came to do.

To install our first program, htop, we are going to use the package manager, yum. Htop is a interactive process viewer for Linux like the preinstalled top, but is a bit more visual and provides more information than top. Htop is a great system monitor.

$ sudo yum install htop

Now simply type htop into the command line.

$ htop

$ which htop

You can see that htop is the in the same directory, /usr/bin/,  as top. 

When we check the permissions of htop we see that the two executables have the same permissions, group and users.

ls -la htop top

-rwxr-xr-x 1 root root 121312 Jul 24  2013 htop

-rwxr-xr-x 1 root root  58400 Mar 17  2015 top


The permissions read -rwxr-xr-x

file –

Read Write Execute

Read   –        Execute

Read  – Execute

So any user on the system can execute this file.

$ echo $PATH



usr/bin is in your path so you can execute htop simply by running the command htop anywhere by any user in the system.

Analyzing the permission, groups, owner and path will be important in running programs after you install them.




Why you need an Amazon Elastic IP Address.

If you are using Amazon Web Services and EC2 instances, go ahead and setup an Elastic IP address.

I am just going to save a you a little time here. We have chosen to use Amazon Web Services (AWS) because it is easy to create and terminate free Linux based servers thought their EC2 instances. We can try things out, and if I need to start over we can just terminate the EC2 instance and start again. Of we can quickly back it up and revert back to a previous state if we become frustrated.

However, my hope is that you get to a point where you are building an application you are interested in continuing. Inevitably you you’ll need to stop and restart you EC2 instance.

Whenever you start your EC2 instance it is assigned a public IP address and a public DNS. The public DNS resolves to the public IP address. You will be using these to connect to the server, and maybe to request your web application.

However, if you stop and restart this server, both the public IP address and the public DNS will change. You will then have to go update these wherever you have used them. It could be in your SSH command or your SFTP settings or in your local hosts file you are using to resolve virtual domains on your Apache server.

Regardless, it is annoying but there is often a price to pay for convenience, and it is super convenient to be able to spin up free computers whenever you need them.

We get around this by using Amazon’s Elastic IP addresses.

Fix: virtualhost overlap on port 80 the first has precedence

I had to virtual host conf files but only the first one was resolving

When I would restart Apache I would see this
 virtualhost overlap on port 80 the first has precedence

    ServerName localhost
    DocumentRoot /var/www/html/000


    ServerAdmin carla@localhost
    DocumentRoot /var/www/html/
 This fixed it # NameVirtualhost is needed in httpd prior to v2.3.11 NameVirtualHost 
 NameVirtualhost *:80
    ServerName localhost
    DocumentRoot /var/www/html/000

I believe this NamedVirtualhost can be enabled in main config

Add User to EC instance with /home directory

[ec2-user@ip-172-30-1-107 conf.d]$ adduser paul
-bash: /usr/sbin/adduser: Permission denied
[ec2-user@ip-172-30-1-107 conf.d]$ sudo adduser paulpend
[ec2-user@ip-172-30-1-107 conf.d]$ cd /home
[ec2-user@ip-172-30-1-107 home]$ ls
ec2-user paulpend
[ec2-user@ip-172-30-1-107 home]$ ls -la
total 16
drwxr-xr-x 4 root root 4096 Feb 17 23:21 .
dr-xr-xr-x 25 root root 4096 Feb 16 19:22 ..
drwx------ 4 ec2-user ec2-user 4096 Feb 17 07:35 ec2-user
drwx------ 2 paulpend paulpend 4096 Feb 17 23:21 paulpend
[ec2-user@ip-172-30-1-107 home]$


Now this user needs access in someway

[ec2-user@ip-172-30-1-107 home]$ cd ec2-user
[ec2-user@ip-172-30-1-107 ~]$ ls
[ec2-user@ip-172-30-1-107 ~]$ ls -la
total 36
drwx—— 4 ec2-user ec2-user 4096 Feb 17 07:35 .
drwxr-xr-x 4 root root 4096 Feb 17 23:21 ..
-rw——- 1 ec2-user ec2-user 1262 Feb 17 07:35 .bash_history
-rw-r–r– 1 ec2-user ec2-user 18 Aug 30 19:00 .bash_logout
-rw-r–r– 1 ec2-user ec2-user 193 Aug 30 19:00 .bash_profile
-rw-r–r– 1 ec2-user ec2-user 124 Aug 30 19:00 .bashrc
drwx—— 2 ec2-user ec2-user 4096 Feb 16 19:22 .ssh
drwxr-xr-x 2 ec2-user ec2-user 4096 Feb 17 02:46 .vim
-rw——- 1 ec2-user ec2-user 996 Feb 17 07:35 .viminfo
[ec2-user@ip-172-30-1-107 ~]$ cd .ssh
[ec2-user@ip-172-30-1-107 .ssh]$ ls

ec2-user etin with keys


If I try to go into this new users home folder I get permissioned denied.


Because I am currently ec2-user


[ec2-user@ip-172-30-1-107 home]$ cd paulpend
-bash: cd: paulpend: Permission denied
[ec2-user@ip-172-30-1-107 home]$ whoami

I can use the su command to change my login session to paulpend


However paulpend has no password

[ec2-user@ip-172-30-1-107 home]$ su paulpend
su: Authentication failure

So what the fuck should I do?

Well, since ec2-user is a sudoer then I can sudo and act on behalf of root who can do whatever they want.

[ec2-user@ip-172-30-1-107 home]$ sudo su paulpend
[paulpend@ip-172-30-1-107 home]$

Or alternatively I could get paulpend a password if I wanted

[paulpend@ip-172-30-1-107 home]$ pwd
[paulpend@ip-172-30-1-107 home]$ ls -la
total 16
drwxr-xr-x 4 root root 4096 Feb 17 23:21 .
dr-xr-xr-x 25 root root 4096 Feb 16 19:22 ..
drwx------ 4 ec2-user ec2-user 4096 Feb 17 07:35 ec2-user
drwx------ 2 paulpend paulpend 4096 Feb 17 23:21 paulpend
[paulpend@ip-172-30-1-107 home]$ cd paulpend
[paulpend@ip-172-30-1-107 ~]$ ls -la
total 20
drwx------ 2 paulpend paulpend 4096 Feb 17 23:21 .
drwxr-xr-x 4 root root 4096 Feb 17 23:21 ..
-rw-r--r-- 1 paulpend paulpend 18 Aug 30 19:00 .bash_logout
-rw-r--r-- 1 paulpend paulpend 193 Aug 30 19:00 .bash_profile
-rw-r--r-- 1 paulpend paulpend 124 Aug 30 19:00 .bashrc
[paulpend@ip-172-30-1-107 ~]$ touch index.html
[paulpend@ip-172-30-1-107 ~]$ ls -la
total 20
drwx------ 2 paulpend paulpend 4096 Feb 17 23:37 .
drwxr-xr-x 4 root root 4096 Feb 17 23:21 ..
-rw-r--r-- 1 paulpend paulpend 18 Aug 30 19:00 .bash_logout
-rw-r--r-- 1 paulpend paulpend 193 Aug 30 19:00 .bash_profile
-rw-r--r-- 1 paulpend paulpend 124 Aug 30 19:00 .bashrc
-rw-rw-r-- 1 paulpend paulpend 0 Feb 17 23:37 index.html
[paulpend@ip-172-30-1-107 ~]$ nano index.html
[paulpend@ip-172-30-1-107 ~]$ ls -la
total 24
drwx------ 2 paulpend paulpend 4096 Feb 17 23:37 .
drwxr-xr-x 4 root root 4096 Feb 17 23:21 ..
-rw-r--r-- 1 paulpend paulpend 18 Aug 30 19:00 .bash_logout
-rw-r--r-- 1 paulpend paulpend 193 Aug 30 19:00 .bash_profile
-rw-r--r-- 1 paulpend paulpend 124 Aug 30 19:00 .bashrc
-rw-rw-r-- 1 paulpend paulpend 28 Feb 17 23:37 index.html
[paulpend@ip-172-30-1-107 ~]$


Now I’ve made an index.html file and I need Apache to server it.

Let’s try to make a virtual host.

Important Apache Files and Directories

We have already learned that Apache is configured by default to deliver web files from


Here are the locations of other important files and directories

Apache Important Files and Directories

  • The default server root directory (top level directory containing configuration files): /etc/httpd
  • The main Apache configuration file: /etc/httpd/conf/httpd.conf
  • Additional configurations can be added in: /etc/httpd/conf.d/
  • Apache virtual host configuration file: /etc/httpd/conf.d/vhost.conf
  • Configurations for modules: /etc/httpd/conf.modules.d/
  • Apache default server document root directory (stores web files): /var/www/html


From the command line we can see

[ec2-user@ip-172-30-1-107 httpd]$ ls
conf conf.d logs modules run

Looking a bit closer by applying the -la flag to ls

[ec2-user@ip-172-30-1-107 ~]$ cd /etc/httpd
[ec2-user@ip-172-30-1-107 httpd]$ ls -la
total 16
drwxr-xr-x 4 root root 4096 Feb 16 21:18 .
drwxr-xr-x 79 root root 4096 Feb 16 21:18 ..
drwxr-xr-x 2 root root 4096 Feb 16 21:18 conf
drwxr-xr-x 2 root root 4096 Feb 16 21:18 conf.d
lrwxrwxrwx 1 root root 14 Feb 16 21:18 logs -> /var/log/httpd
lrwxrwxrwx 1 root root 24 Feb 16 21:18 modules -> /usr/lib64/httpd/modules
lrwxrwxrwx 1 root root 14 Feb 16 21:18 run -> /var/run/httpd

Setting Up Apache on Amazon EC2


Install Apache


We’ve installed Apache, a web server but we still can’t see a web page.

What gives?

This is because you can’t accept inbound traffic. You are allowing inbound traffic on port 22 for SSH but not on port 80 needed for HTTP.

So we need to allow Inbound traffic from Port 80

And now when we visit our public domain we see the default web page of the Apache HTTP server.

This page tells us the default location to add HTML content

“You may now add content to the directory /var/www/html/. Note that until you do so, people visiting your website will see this page, and not your content. To prevent this page from ever being used, follow the instructions in the file /etc/httpd/conf.d/welcome.conf.”
So let’s go there.
Currently we are in the users home directory. We can use pwd to see where we are.
You are in the home directory of the ec user
[ec2-user@ip-172-30-1-107 ~]$ pwd
Let’s take a peek in this directory using the ls -la command. This will list all files and their group and user permissions. We will use ls -la again in a minute.

[ec2-user@ip-172-30-1-107 ~]$ ls -la
total 24
drwx------ 3 ec2-user ec2-user 4096 Feb 16 19:22.
drwxr-xr-x 3 root     root     4096 Feb 16 19:22..
-rw-r--r-- 1 ec2-user ec2-user   18 Aug 30 19:00 .bash_logout
-rw-r--r-- 1 ec2-user ec2-user  193 Aug 30 19:00 .bash_profile
-rw-r--r-- 1 ec2-user ec2-user  124 Aug 30 19:00 .bashrc
drwx------ 2 ec2-user ec2-user 4096 Feb 16 19:22.ssh

We need to go to the directory /var/www/html/
Let’s go check it out

[ec2-user@ip-172-30-1-107 html]$ cd /var/www/html
[ec2-user@ip-172-30-1-107 html]$ ls
[ec2-user@ip-172-30-1-107 html]$ ls -la
total 8
drwxr-xr-x 2 root root 4096 Feb 16 21:41 .
drwxr-xr-x 6 root root 4096 Feb 16 21:18 ..
We see there are no files here. Let’s create an HTML file, index.html using nano

[ec2-user@ip-172-30-1-107 html]$ nano index.html

Oh nooooooo permission denied (see message at bottom of next image).

What the hell. Well its because the permission for this directory is set to root, and we are logged in as ec-user.

Have you noticed in our command line


[ec2-user@ip-172-30-1-107 html]$


If we want to create a file in this directory as is, we need to write the file with root permissions.

You NEVER want to log in as root, and it is really hard in an Amazon EC2 server without some making some serous changes. Fortunately we can use the sudo command to do this.

If you add the prefix sudo to most linux commands, that command will run with elevated privileges required to perform certain, usually administrative tasks.

Basically if you need to do shit as root then instead of logging in as root use the sudo command.

The ec2-user has sudo privileges on AWS EC2 servers.

So a quick aside as I show you.

Sometimes you can find the list of users who can sudo here

less /etc/sudoers

However, on this Amazon EC2 instance the file is located here


and we don’t have permission to see it as ec2-user

This is a bit meta but if you need to elevate your privileges with sudo to read the contents of the sudoers file.

[ec2-user@ip-172-30-1-107 etc]$ sudo nano /etc/sudoers.d/cloud-init

When the files opens you will see ec2-user listed.

A side note, you may have tried to use the change directory command, cd to get into the sudoers.d directory; however, you would get a permission denied as this directory requires root. You can’t use sudo cd because cd is part of the shell. sudo foo means run the program foo as root. cd is not a program  but an in-built command and sudo only applies to programs.

If for some reason you really wanted to cd into this directory you’d have to become root (this is NOT recommended)
[ec2-user@ip-172-30-1-107 etc]$ sudo -s
[root@ip-172-30-1-107 etc]# cd sudoers.d
[root@ip-172-30-1-107 sudoers.d]# ls

To get out of root and back to ec2-user simply use exit

[root@ip-172-30-1-107 sudoers.d]# exit

[ec2-user@ip-172-30-1-107 etc]$

See how the username before the @ changes from root to ec2-user

Phew ok back to making out first HTML page.

All of this to say that ec2-user has sudo privelges and as such can create an index.html with root permission to match the permssions of the direcotry that have the Apache HTML files
[ec2-user@ip-172-30-1-107 html]$ cd /var/www/html
[ec2-user@ip-172-30-1-107 html]$ ls
[ec2-user@ip-172-30-1-107 html]$ ls -la
total 8
drwxr-xr-x 2 root root 4096 Feb 16 21:41.
drwxr-xr-x 6 root root 4096 Feb 16 21:18..
[ec2-user@ip-172-30-1-107 html]$
OK so we are in the directory Apache told us the files are in, we understand the containing directories have root permissions. So we will sudo and make this file
[ec2-user@ip-172-30-1-107 html]$ sudo nano index.html

Control X will exit and ask you to save.

Navigate back to the public url for this EC2 instance. Boom!