notes on setting up php apps at EngineYard (EY) December 12th, 2013, by Rob Koberg

EY works through deployments of branches or tags from your git repo. For now you will probably just have a deployment off of your develop branch (you are using gitflow, right http://jeffkreeftmeijer.com/2010/why-arent-you-using-git-flow/ ).

Each time you deploy, everything will sync up with whatever is in the develop branch of your repository. This means you cannot put things that will vary by the server or any uploaded files that normally live under docroot directory.

During the deployment process they give us deployment ‘hooks’ which are simple ruby evals of command line commands. For example, you probably have some settings file that should live at a specific location. Since that file should not be in version control, you need to create it on the server. On each EY instance there is a shared directory (/data/{environment-name}/shared). I suggest you create a folder (wp?) inside the shared directory. In there you can put server variable files for settings and directories for uploaded files. Then you would need to symlink them to the correct locations in the currently deployed project (always at /data/{env-name}/current). This is where deployment hooks come in.

You should have a basic directory structure where you have your docroot directory and a deploy directory directly under your project root:
my-project
-- .git
-- deploy
-- public (or docroot or whatever)

Inside the deploy directory will go your deploy hooks. For example, for a drupal I have a file named before_symlink.rb that will be run before EY does its symlinking. It has:
run "sudo ln -s #{config.shared_path}/drupal/files #{config.release_path}/docroot/sites/default/files"
run "sudo ln -s #{config.shared_path}/drupal/files-private #{config.release_path}/docroot/sites/default/files-private"
run "sudo ln -s #{config.shared_path}/drupal/settings.php #{config.release_path}/docroot/sites/default/settings.php"

This links the uploadable files destinations, as well as the main settings.php from its location in the shared directory to the necessary locations in the currently deployed app.

Recipes

Next you will want to use recipes. First clone (not in your current working project) the ey recipes from https://github.com/engineyard/ey-cloud-recipes and follow the 6 step quickstart. Once you are setup you just need to uncomment out some lines for the services you want to enable like varnish_frontend, memcached, ssmtp. I had a problem with varnish and needed to alter the recipe because no pages where being served outside of localhost.

One recipe that is not included is reverting from php54 to php53. Drupal throws tons of warnings if you use php54. To get the recipe for going down to 53, follow the instructions found here: https://support.cloud.engineyard.com/entries/23768022-PHP-5-4-is-the-version-available-by-default-if-you-need-PHP-5-3

Bootstrap’s fade class and Windows 8, Internet Explorer 10 March 21st, 2013, by Rob Koberg

If content is not show because you are using fade transitions:

jQuery(document).ready(function($) {

if ( $.browser.msie && 10 >= $.browser.version ) {
$('.fade').removeClass('fade');
}

before anything else…

Adding largish amounts of data in a rails migration March 7th, 2013, by Rob Koberg

There was a little trick to it. First, here is the migrate script:

class ImportMdrDataToSchoolsImport < ActiveRecord::Migration
  def up
    ActiveRecord::Base.connection.execute(IO.read("./db/schools_import.sql"))
  end

  def down
  end
end

The schools_import.sql file is about 75MB.

The trick was to use pg_dump with the --inserts flag as using a standard dump’s stdin would not work.

pg_dump --inserts -t schools_import schools > schools_import.sql

I also edited the dump to remove everything but the insert statements and the create indexes. Then I added a statement for truncating the table, then drop the indexes, then the existing insert statements from the dump followed by the create indexes. For example:

TRUNCATE TABLE schools_import;

DROP INDEX "index_schools_import_on_MCITY";
DROP INDEX "index_schools_import_on_MSTATE";

INSERT INTO schools_import VALUES (...)
...all inserts...

CREATE INDEX "index_schools_import_on_MCITY" ON schools_import USING btree ("MCITY");
CREATE INDEX "index_schools_import_on_MSTATE" ON schools_import USING btree ("MSTATE");

It took under 8 minutes to run and put about 260k records.

CSS data-uri optimization February 12th, 2013, by Rob Koberg

One thing you can do to improve your web site’s performance and cut http requests is to use data-uris in your CSS. If you can get the data-uri under 32k, it can safely be used in CSS with support for browsers down to IE8.

If you just have a few to deal with, here is a handy tool that will offer a right+click context menu item to put the data-uri in your clipboard.

Generate a base64 encoded Data URI straight from the Finder.
An Automator workflow which adds an item to the ‘Services’ contextual menu. It generates the Data URI for a file and copies it to the pasteboard.

Just right+click on an image in your finder and then paste it in a CSS url().

For a more maintainable approach (using Sass, Compass, and Bootstrap), I like to keep two separate SCSS include files that just define variables for each image URL. One is for a URL to the real image, and one is for a generated data-uri. I do this because images will change and I can run a quick java command line app to quickly regenerate the data-uri file. Check out Automatic data URI embedding in CSS files Nicholas C. Zakas.

Twitter Bootstrap, Sass, and Compass for sanity February 12th, 2013, by Rob Koberg

Twitter Bootstrap: http://twitter.github.com/bootstrap/
Sass: http://sass-lang.com/
Compass: http://compass-style.org/

I have used this combination on several web sites and really like it. I understand there is Foundation, but prefer bootstrap and honestly probably just more used to it.

I understand that bootstrap uses less out of the box, but find sass much more appealing. With compass, you can edit the source files and get them generated to CSS on the fly.

I just started this WordPress blog over the weekend and brand new to WordPress in general. I thought the best way to start to understand it was creating a custom theme. The first thing I did was setup an environment where I could use bootstrap, sass, and compass. After a few failed attempts with top google results, I went with forge to generate a theme and have my CSS and JavaScript generated on the fly. I have the ruby gem bootstrap-sass installed from other projects, so that is what I will use for the CSS part.

Rails comes with this ability built-in with a few extra gems. Even for a simple web site, a drupal based one, or some even more complex monstrosity, these three support my sanity.

PNG Image optimization with pngquant February 11th, 2013, by Rob Koberg

Use pngquant: http://pngquant.org/

pngquant is a command-line utility for converting 24/32-bit PNG images to paletted (8-bit) PNGs.

The conversion reduces file sizes a great deal (often as much as 70%) and preserves full alpha transparency. Generated images are compatible with all modern web browsers, and have better fallback in IE6 than 24-bit PNGs.

On OS X you can install it easily with homebrew:
$ brew install pngquant

Now you can optimize the hell out of your PNGs. Let’s say you don’t have thousands of images to optimize. You can do:
$ cd ~/to/some/root/dir
$ find . -name '*.png' -exec pngquant -ext .png -force 256 {} \;
This searches recursively through the current directory and greatly reduces the file size of each PNG it finds. Using the -force flag lets you overwrite the existing file.

Let’s say you have several thousand PNGs to optimize. Using the command above froze my poor little imac. You might also want to do other things with the image (like convert it to an SWF so it can be used in an online PDF flash reader…). If we loop through the files to perform the optimization, my poor little iMac can handle it. Here is a simple bash script that basically does the same thing as the one liner above:

#!/bin/bash

for PNG in $(find . -name '*.png'); do
  
  pngquant -ext .png -force 256 ${PNG}
  echo "Optimized PNG: ${PNG}"

done

Using git and gitflow with Acquia and EngineYard February 11th, 2013, by Rob Koberg

First read: http://jeffkreeftmeijer.com/2010/why-arent-you-using-git-flow/

More depth: http://nvie.com/posts/a-successful-git-branching-model/

Video tutorial: http://vimeo.com/16018419

And: http://blog.sourcetreeapp.com/2012/08/01/smart-branching-with-sourcetree-and-git-flow/http://yakiloo.com/getting-started-git-flow/

I want to outline the process we are using at two separate hosting services:

  • EngineYard – a ruby project that has multiple developers. Requires a separate deployment step
  • Acquia – multisite drupal projects, now with only me as the developer. For Acquia, we are using them as the remote repository which allows us to just push our changes to the remote repo to have them deploy.

The process is similar for both projects. Each uses three separate environments: development, stage/test, production. You will see some redundancy if you deploy to dev, then to stage and then to prod.

Deploying to development

  1. Ensure you are in the develop branch:
    $ git branch
    and/or
    $ git checkout develop
  2. Get the latest code:
    $ git pull origin develop
  • For engineyard:
    $ ey deploy -e dev
  • For acquia (just push to the develop branch):
    $ git push origin develop

Deploying to stage/test

  1. Ensure you are in the develop branch:
    $ git branch
    and/or
    $ git checkout develop
  2. Get the latest code:
    $ git pull origin develop
  3. Switch over to the master branch:
    $ git checkout master
    $ git pull origin master
  4. Merge your changes:
    $ git merge develop
  5. Push your changes to the remote repo:
    $ git push origin master
    This deploys the master branch to acquia.
  • For engineyard:
    $ ey deploy -e staging

Deploying to production

For acquia we use their web control panel to simply drag and drop the stage code to production. This automatically tags master and deploys it to production. For engineyard we set up a slightly more elaborate (and correct) release process. In general do the following steps for both hosting services.

  1. $ git checkout master
  2. $ git pull origin master
  3. $ git checkout develop
  4. $ git pull origin develop
  5. $ git diff master develop

You should not see any differences.

For engineyard we will create a release and publish that with gitflow. I usually just check the rails app’s config/ey.yml for the latest version number, but you should also be able to do:
$ git branch -r
The version number will look like: 1.1.3

Create a release with the next version number, e.g.
$ git flow release start 1.1.4
Update the rails engineyard config by editing:
$ vim config/ey.yml
Add it by being extra careful at this point:
$ git add -p
Commit this changed config file:
$ git commit -m "Updated release branch for production."
Now use gitflow to publish and finish the release:
$ git flow release publish 1.1.4
$ git flow release finish 1.1.4
Enter a message like “releasing 1.1.4 to production.”
You changes are now in the master branch.
$ git co master
$ git push origin master
Deploy to engineyard:
$ ey deploy -e production
Finally, after the deployment, make sure you switch back to develop so you don’t forget next time you make some changes.
$ git co develop