Do Yourself a Favor: Set Up a Staging Server

Update: I corrected 3 parts of this where I mistakenly intructed you to use ‘ssh://’ before the URI to your git remotes

Remember the days when you used to deploy your websites using FTP? I sure do. Back then FTP was how everyone was doing it. The command line was foreign. Git didn’t exist. It was simple and we had no idea there was any other way. Well things sure have changed. These days no one builds websites, it’s all about the apps. And when you run an app you don’t want to get caught with your pants down. One way to do that is to deploy your app without a staging server. So before you launch your brand new app into the world and become a billionaire, do yourself a favor and set up a staging server. It’s simple and I’ll show you how.

What’s a staging server

I might have a slightly different definition of a staging server than others so let me explain. A staging server is basically a testing server. It’s an environment you deploy your app to that’s identical to the server you’ll be running in production. Ideally they’re the same server. You might have a perfectly working app on your local development machine but even minor changes in your development and production environments could cause your app to crap out on you. That’s not something you want happening on a live website. The idea is that by running your site on the staging server you can quickly identify bugs your users may encounter as well as any environment differences that’ll cause your app to error out unexpectedly. Just yesterday I spent about 5 hours trying to figure out why the latest build of Write.app wouldn’t run through its most basic functions on the server. It worked fine on my Mac where I develop and test it. Luckily I always deploy to a staging server and that has and will continue to save me from deploying bunk code into production.

Prerequisites

This guide assumes you’re running your own server or a VPS. Something like Linode, MediaTemple, Amazon EC2 or a dedicated server will do. Shared hosts are spotty and there’s no guarantee any of this will work but MediaTemple’s (gs) shared service is actually pretty good about this. You’ll need SSH access and the ability to sudo.

You’ll also need the ability to create A records which means access to your DNS provider (that’s probably either your hosting company or registrar).

Lastly, you’ll need Git installed on your server and local machine. We’re going to be working with Git deployment here.

Step 1: Set up your servers

Locally

Mac users can either run a LAMP stack much like you would on a Linux server by installing via Homebrew or installing MAMP.

Windows users can use XAMPP or WAMP to run a local server.

Linux users are pretty smart and probably know this already but running sudo apt-get install git git-core apache2 php5 mysql5 should do the trick (note: those package names are from memory and may not be correct).

On the server

I assume you’re using a Linux distro and if you’re not I’m wondering why. Most people run something Debian based like Ubuntu so running this command should set you up sudo apt-get install git git-core. You should already have your LAMP stack setup. If not, Linode has some great docs to get you started.

Set up your DNS

Okay, so you should have a LAMP stack running locally and on the server along with Git. So now you’ll need to create a subdomain for your staging server. If your main domain is awesome.com then add an A record called staging.awesome.com. You’ll need to create the appropriate virtual host configuration and the proper directory structure to host that site but otherwise you should be good and I’ll get into some of that below.

Step 2: Set up Git deployment

This has nothing to do with GitHub! Now you’re going to need 4 Git repositories set up. 3 on the server and 1 on your local machine. Here’s how to set this up:

On your server

1
2
3
4
5
6
7
ssh you@awesome.com # Log into your server
cd ~/
mkdir git
cd git
mkdir awesome.git
cd awesome.git
git init --bare

What that does is create a folder to host Git repos in your home folder on your server. Then we create a new folder to hold the repository, cd (change directories) into it and initialize a totally bare Git repo. It is now ready to accept data from your local computer

On your local machine

cd into the directory your site’s main folder is in and type the following:

1
2
3
4
git init
git add .
git commit -m "First commit"
git remote add origin username@awesome.com/path/to/repo.git

What we did there was initialize a git repository for your project and set the main remote on your server. This remote is your master. It’s purely for version control and will store all changes from all branches. It’s your main repository. The others will have very specific purposes and will be for deployment only.

Now you have simple version control. But that repository doesn’t do anything. In order to deploy to a staging server and production we’ll need two more repositories on the server.

Back on the server

Type this

1
2
3
4
cd /path/to/staging_website/document_root # You know, public_html
mkdir staging.git
cd staging.git
git init --bare

Now you’ve created a bare repository on the server that’ll be used for deploying into staging. But we’re not done here. We need to create one more that’ll be used for production too! And please, fill in the blanks with your own directories. Do not type them verbatim. This is supposed to be instructive but I don’t know your specific directory structure. I know for my own server I usually use /srv/www to store my websites. So in that folder I’ll have the folders of my production_site/public_html and my staging_site/public_html. Yours might be similar but definitely not the same. So while you’re still on the server…

1
2
3
4
cd /path/to/production_website/public_html
mkdir production.git
cd production.git
git init --bare

Now you created the repository from which you’ll deploy into production! Now that you have both of those set up, do this on your local computer:

1
2
git remote add production you@awesome.com/path/to/production.git
git remote add staging you@awesome.com/path/to/staging.git

So now you have remotes set up for your overall version control (origin), for deploying to a staging server (staging), and deploying to production (production). The next step is to set up Git deploy hooks in your prudction and staging repos and you’ll be pushing from staging to production in no time!

Setting up the deploy hooks

Now that you have all your repositories set up you’ll be needing to set up the deploy hooks. You’ll be pasting a couple very simple lines of text into a file in your repositories and when your done you just push to the appropriate remote to deploy your website. Here we go.

On the server inside your production and staging repositories you’ll find a folder called hooks. You’ll need to either find or create a file called post-receive. Back on your server do this in both your production and staging repo (one after the other, of course – not at the same time):

1
2
3
4
5
ssh you@awesome.com # Log in if you're not already
cd /path/to/production.git
cd production.git
cd hooks
touch post-receive

You’ll do that in both repos but you’re not finished yet. Before you leave that directory or log out of the server you’ll need to copy and paste some code into that post-receive file…

1
nano post-receive

Now that you’ve got the file open, paste this into it:

1
2
#!/bin/sh
GIT_WORK_TREE=/path/to/your/document/root git checkout -f master

Then do a Control-X and hit Y and Enter and you’re done. Repeat that process for both the production and staging repos. Basically, what those two lines do is checks out the latest version of your code into your site’s document root. That’s why it’s important that the path you put for GIT_WORK_TREE should be the one to your site’s document root and not the path to the repo.

But before this works there’s just one more step (I swear it’s the last one). You’ll need to make the hook executable and you may need to change the permissions on the folder.

1
sudo chmod a+x post-receive

Now, you may need to change the permissions on the repository folder and/or the document root as well. Your mileage may vary depending on where on your server you serve your sites from.

So now, finally, you can log out of your server and start deploying sites.

To deploy just git push staging master or git push production master.

Now, what you should be doing is pushing to your origin just to keep a record of changes then to your production server/area. Test your site. Be sure it works like it did in development and then push to production. It takes a little effort to set up if you’ve never done it before but once it’s done it’s the easiest, most hassle-free way to manage your app or website.

Web development

« In Need of Recharging Making money chase you »

Comments