Jesse is a developer from Calgary, Alberta who specializes in websites, Flash and iPhone development.

Multiple Environments in htaccess

Posted on 5 Oct 2014 by Jesse Knowles in HTML, EE | Comments

I recently wrote about using multiple environments with GIT and ExpressionEngine. There is one last item that you likely need to manage and that is when you only want to password protect your staging environment and not your local or live environments. You generate an htpasswd file easily from here. After that, this code should help you configure your htaccess file so only your staging environement requires password authentication.

#allows everything if its on a certain host
SetEnvIf HOST "^domain.dev" dev_url
SetEnvIf HOST "^staging.domain.com" staging_url
SetEnvIf HOST "^domain.com" live_url
Order Deny,Allow

AuthName "Authorized Access Only"
AuthType Basic
AuthUserFile "/var/www/vhosts/domain.com/staging/.htpasswd"
AuthGroupFile /
Require valid-user

#Allow valid-user
Deny from all
# Allow from env=staging_url
Allow from env=dev_url
Allow from env=live_url
Satisfy any

Deployment with Git and ExpressionEngine

Posted on 3 Oct 2014 by Jesse Knowles in Git, EE | Comments

As of the last year or so, I have transitioned into using GIT for not only backing up my sites onto a remote server but its also a wonderful tool for keeping track of past changes, working on separate branches for time sensative releases, and even deploying updates to the server.

My CMS of choice for the last 4 or so years has been ExpressionEngine and there are a number of intricacies when dealing with a cms. For one, the cms at times updates files that are on the server, so you don't want your deploy to mess with those files, at least if you intend on keeping that smile on your clients face.

This is the logic behind my workflow with GIT and ExpressionEngine...

First off, my favorite editor is SublimeText, the best editor on the planet. It comes with the ability to install lots of add-ons to make sitting at a desk all day, that much better (hopefully). One add-on that I wouldn't leave home without is GIT Gutter, it integrates with git on your local machine to show you in the gutter of your edited files, what lines have been modified since your last commit. It's a quick way of keeping track all of your updates. Another is 'sftp', it makes ftp'ing files a breeze. It adds a sftp config file to your main directory where you can easily put in your ftp credentials and settings. 

Whenever I'm building an EE website, I always create a local git repository and I create a backup on my remote server (for safe keeping). If I have ssh access to the clients server, then its a no brainer, I setup git and work at getting my deployment method rolling. Git has what is called Hooks, these are nifty little code chunks, that you can write, that will fire when a certain event happens within a git repo. There is a 'post-receive' hook that is of particular interest to you. This hook runs after you have pushed an update to the remote repository. This is the time when we want our code to modify the server with an update of our latest changes. You can even have the hook look at what branch was updated so you can determine what options you want to take. I use my master branch to checkout files to my production directory and a staging branch to checkout to my staging directory.

When developing and maintaining an EE website for a client, I like to have a local version (for making and viewing updates quickly), a staging version that only the client has access to, for showcasing updates and getting them approved, and obviously the live production version that everyone sees. This means you need 3 locations for the files, 3 databases and a modified database.php file to store the different database settings for each server. It's also nice to be able to keep them all in sync as quickly as possible, which isn't the easiest thing to do when dealing with a CMS, however, I believe I have a fairly simple way to keep them in sync. It's a combination of GIT (I actually prefer GIT Tower over the command line), ftp, Sequel Pro (or any decent mysql client), and an EE module called REElocate.

I use GIT for updating any files I modify such as css, javascript, html templates, added add-ons, config/database settings, etc. I use sftp in Sublime Text to quickly sync the upload directory on the live server down to my local server, so I can grab the latest updated files from the CMS. I can then upload/sync that directory back up to the staging server, if I need to. Sequel Pro is a quick way to export the live database and import it into my other environments and finally REElocate is used to update all of the directory path and domain settings in EE, so it works properly at each location. It usually takes no more than a couple of minutes to be all synced up. I generally try to have a staging.website.com subdomain for the staging environment and a website.dev domain for my local environment.

ExpressionEngine Configuration

Now for the exciting part. In config.php I determine what environment I am in and define a variable and add a config variable that I can use in templates. Here is the code...

if(!defined('SERVER_ENV')) {
    // Define the server name, basepath and site_url
    // These can all be defined using the server request and filepath
    define('SERVER_NAME', $_SERVER['SERVER_NAME']);

    if ( strstr( SERVER_NAME, '.dev' ) ) define('SERVER_ENV', 'local');
    elseif( strstr( SERVER_NAME, 'staging.' ) ) define('SERVER_ENV', 'staging');
    // Fallback to production settings
    else define('SERVER_ENV', 'production'); // live

    // Not sure what environment the request is?
    // Add ?debug_config_bootstrap to the end of the URL
    if(isset($_GET['debug_config_bootstrap'])) {
        die('The current environment is: '.SERVER_ENV);
    }
}

global $assign_to_config;
if(!isset($assign_to_config['global_vars']))
    $assign_to_config['global_vars'] = array();
$assign_to_config['global_vars']['environment'] = SERVER_ENV;

Notice the last line I set a global variable called 'environment'. I can now use {environment} in any template I want. I use it for displaying a bar at the top of the page (when not on production), of what environment I am viewing. Here's what I add to my EE template...

[if environment != 'production']<p class="dev-bar">[environment] Environment</p>[/if]

* replace the square brackets with curly brackets

Then you just style it however you want. The main part of this is in the database.php file. We can use our newly defined environment variable in a conditional to determine our different environments. 

switch ( SERVER_ENV ) {

/* Local DB Config */
case 'local' :
$db['expressionengine']['hostname'] = 'localhost';
$db['expressionengine']['username'] = 'username_here';
$db['expressionengine']['password'] = 'password_here';
$db['expressionengine']['database'] = 'db_name';
$db['expressionengine']['cachedir'] = '/path/to/expressionengine/cache/db_cache/';
break;

/* Development DB Config */
case 'staging' :
$db['expressionengine']['hostname'] = 'localhost';
$db['expressionengine']['username'] = 'username_here';
$db['expressionengine']['password'] = 'password_here';
$db['expressionengine']['database'] = 'db_name';
$db['expressionengine']['cachedir'] = '/path/to/expressionengine/cache/db_cache/';
break;

/* Development DB Config */
case 'production' :
$db['expressionengine']['hostname'] = 'localhost';
$db['expressionengine']['username'] = 'username_here';
$db['expressionengine']['password'] = 'password_here';
$db['expressionengine']['database'] = 'db_name';
$db['expressionengine']['cachedir'] = '/path/to/expressionengine/cache/db_cache/';
break;

}

Git Deployment

ExpressionEngine is all setup. Now lets get git working. Assuming you already have a remote repo on the production server. You need to add/edit ssh into the server and in your git/hooks directory, you should see a file called post-receive. Open that in nano (or whatever you prefer). Then you add this bash script to the file.                                                                                   

#!/bin/bash

# To use this functionality turn this to true
enabled=true

###### SETTINGS ######

# set the server paths here
livepath=/live/path/here
devpath=/dev/path/here/

#set the user
git_user=ftp_username
git_group=ftp_usergroup

#file permissions
#666
sixes=(
        'system_dir/expressionengine/config/config.php'
        'system_dir/expressionengine/config/database.php'
      )
#777
sevens=(
        'system_dir/expressionengine/cache/'
        'images/avatars/uploads/'
        'images/captchas/'
        'images/member_photos/'
        'images/pm_attachments/'
        'images/signature_attachments/'
        'images/uploads/'
      )

#files/directories to remove
#used for if you want to git backup directories but don't want them in your htdocs location
removedirs=(
            '_db'
            'sftp-config.json'
            '.gitignore'
          )

###### LOGIC ######

# this handles the updates
if [ "$enabled" = true ]; then

  while read oldrev newrev ref
    do
      branch=`echo $ref | cut -d/ -f3`

      if [ "master" == "$branch" ]; then
        deploydir="$livepath"
        msg="Changes pushed live."
      fi

      if [ "staging" == "$branch" ]; then
        deploydir="$devpath"
        msg="Changes pushed to dev."
      fi

      # update the directory
      git --work-tree="$deploydir" checkout -f $branch

      # fix owner
      FILES=`git diff --cached --diff-filter=ACMRTUXB --name-only ${oldrev}`
      for F in $FILES; do
        chown $git_user:$git_group "${livepath}${F}"
        echo "chowned ${livepath}${F}"
      done

      #set file permissions
      for F in "${sevens[@]}"; do
        chmod 777 "${livepath}${F}"
      done
      for F in "${sixes[@]}"; do
        chmod 666 "${livepath}${F}"
      done

      #remove files/directories
      for D in "${removedirs[@]}"; do
        rm -rf "${livepath}${D}"
      done

      echo "$msg"
  done

fi

The comments make what it does self explanitory. Git does a checkout to a desired working tree and that directory is determined by the name of the branch that is being pushed to the server. In my case, It then sets the desired user as the owner of those files, then it sets the necessary file permissions that we need. I wanted to backup certain files/directories but I didn't necessarily want them accessible in the production directory. So I have a list of files that it removes after the checkout occurs.

Finally, I also have a gitignore file in the root directory of my files, that prevents git from managing or overriding certain files.

# Track all .gitignore files
!.gitignore # or !.gitkeep if you prefer

# Ignore all cache & private files
/system_dir/expressionengine/cache/
/images/sized/
/images/uploads/

# Ignore EE file upload directories
/assets/

# Ignore design directories
/_layout/
/_inc/

That's about it. Once that is all setup, managing all the different environments is fairly simple. With every update you make and push to the Git repo, the files you want updated on your server will be updated and only if you push to the master or staging branch. I'm sure this may evolve over time but, so far I like it.

EDIT: you may also want to see this article I wrote about integrating htaccess/htpasswd files with multiple environements.

Forcing HTTPS on an ExpressionEngine Site

Posted on 19 Aug 2013 by Jesse Knowles in EE | Comments

I recently built a shopping cart for a client using ExpressionEngine and had to make the checkout secured by SSL. Once the SSL certificate is installed, the trick is to make every link on the page have a https:// or // protocol. I was using structure and a few other plugins, so the task seemed a bit daunting. It turned out to be really simple.

1) In the htaccess file you need to force certain pages to be https. This code will do that...

# Force HTTPS
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} /account/checkout/
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L]

2) Next, convert any google fonts links to start with // and any others you can find that are hard coded.

3) Lastly, in order to have all your addons output the proper protocol add this code to your index.php file so that it sets the site_url variable to https if that is the protocol being used.

if(strtolower(substr($_SERVER["SERVER_PROTOCOL"],0,5))=='https') // site_url is https if its in the url
$assign_to_config['site_url'] = 'https://'.$_SERVER['HTTP_HOST'].'/';

Too easy? I know, I told you so!

This is ANT - A Total Redesign

Posted on 17 Dec 2012 by Jesse Knowles in HTML, EE | Comments

The folks at Dynastream Innovations hired me to build them a brand new CMS driven website. The website launched a couple of weeks ago and is powered, once again, by the best CMS on the planet, ExpressionEngine. Check it out.

A new website for Wilton Resources

Posted on 12 Nov 2012 by Jesse Knowles in HTML, PHP | Comments

Kinoli recently worked with Studio Forum to develop a static website for an up and coming oil producer headquartered in Calgary. The website has a unique image scaling technique that stretches to the size of the browser window. The striking images emphasize the work that Wilton Resources does and the content is layed out in a straight forward manner.

Have a look at WiltonResources.com

Trickster Theatre Go’s Global

Posted on 1 Sep 2012 by Jesse Knowles in HTML, PHP, EE, Design | Comments

This was a brand new website for Trickster Theatre company. They had this idea of connecting schools and students with NGO's to help raise awareness and funds for projects around the globe. They hired me as the web developer to build fulfill this desire. The website has several different user groups that have different experiences based on their account type. NGO's are able to add projects that they are working on and schools can get involved with these projects to partner with the NGOs. Schools are also able to create their own projects to get students involved in their communities. We wish the best of luck to Trickster Theatre and hope it is a great success story.

An iPad Application For a Cause

Posted on 1 Aug 2012 by Jesse Knowles in HTML, PHP, Mobile, Design | Comments

Real Simple Magazine partnered with Cooking Light and Purina for a promotion they were putting on in Grand Central Terminal in New York City. They hired me as the ipad developer to create an iPad application that would be shown on 10 ipads and allow people in the terminal to add magazine photo's, apply filters to them, attach a picture frame to it and submit it to a website that was displayed on a large screen. The photo's were uploaded to the website and the website would automatically reload the most recently submitted photos. It also allowed people to post their creations to their facebook wall.

Another Mobile Website - Calgary Coop

Posted on 1 Jul 2012 by Jesse Knowles in HTML, PHP, EE, Mobile | Comments

Mobile websites seems to be getting a leg up on the desktop world these days or at least at Kinoli. I was hired as the web developer to build a jQuery Mobile website for Calgary Coop. I integrated it into an existing ExpressionEngine environment using jQuery mobile on the front-end to ensure the majority of mobile browsers would have the same experience. The mobile website shows store locations, hours for individual stores, featured recipies and even recent flyers.

View Calgary Coop Mobile.

Charmin iPad Application

Posted on 14 Jun 2012 by Jesse Knowles in Mobile, Design | Comments

Charmin needed a mobile iPhone developer and looked to me to fulfill their needs. I was hired to create an iPad application for Charmin. It was a simple application that was used at an event in New Orleans. They created a ficticious booth that represented a bathroom stall. The iPad was mounted on the inside of the door, where the user would tell their strangest bathroom story. The iPad was the perfect solution for this, I got to design it and develop the entire application. The application even stored the video recordings on the hard drive so the staff at Charmin will now be able to do promotional marketting with them.

High Dynamic Range Photography

Posted on 21 Mar 2012 by Jesse Knowles in Photography | Comments

With all the advancements in technology we still don't have the ability to take pictures that can pull in the full range of light that our eyes can see. That is why you see windows that are all washed out, or lack of details in clouds in photos. The sensor on any camera can't see everything that your eye can pick up. I guess the good Lord did a pretty good job in making us. As for camera's, that's where High Dynamic Range (HDR) photography comes in. It is a crafty technique of taking several photo's of the same subject all at different exposures, then with the magic of the computer and even some cameras, blending the images together so that we can have all that tonal range in one photo. It sounds complicated but it really isn't. 

Latest Tweets

Clients