SpreeCamps Developer Tutorial

What is a camp? It’s an independent copy of an application that allows you to develop your site without interfering with your production code and database. Because each camp has its own independent copy of the entire software stack, including Apache or nginx, Passenger or Unicorn, Rails, and the database, you can experiment with different server configurations, try radical database changes, and so on, without any risk of harm to the production site or other camps.

Camps reside in each developer’s own system account. That way you can have your own shell aliases, editor configuration, etc. without affecting other developers or your production environment.

Let’s say your username is "john" and your app name is "spree". Your first camp (named "camp10" in this example) has this directory structure (output by the "tree" command):

`-- home
    `-- john
        `-- camp10
            |-- .git/
            |-- config/
            |   |-- environments/
            |   |-- initializers/
            |   |-- boot.rb
            |   |-- database.yml
            |   |-- environment.rb
            |   |-- routes.rb
            |   `-- spree_permissions.yml
            |-- db/
            |-- httpd/
            |   |-- conf/
            |   |   |-- sites/
            |   |   |-- ssl.crt/
            |   |   `-- httpd.conf
            |   |-- logs/
            |   |   |-- access_log
            |   |   `-- error_log
            |   `-- run/
            |       `-- httpd.pid
            |-- pgsql/
            |   |-- data/
            |   |   |-- postgresql.conf
            |   |   `-- postmaster.pid
            |   `-- tmp/
            |       `-- pgstartup.log
            |-- public/
            |   |-- assets/
            |   |   `-- products/
            |   |-- images/
            |   |-- javascripts/
            |   |-- stylesheets/
            |   |-- dispatch.cgi*
            |   |-- dispatch.fcgi*
            |   |-- dispatch.rb*
            |   |-- favicon.ico
            |   `-- robots.txt
            |-- script/
            |-- vendor/
            |   |-- extensions/
            |   |-- gems/
            |   `-- plugins/
            |-- .gitignore
            |-- CHANGELOG
            |-- CONTRIBUTORS
            |-- INSTALL
            |-- LICENSE
            |-- README.markdown
            `-- Rakefile

Notice that this camp10 directory contains its own web server and database engine instances, within the httpd and psql directories respectively. The .git directory contains the files Git needs to keep everything under version control. Everything else here is the code comprising your Spree application.

Even as a single developer, you’ll often need to work on multiple projects for the same site at the same time. Keeping those projects separate makes it much easier to test and roll out the changes independently, regardless of which project finishes first.

Say you’ve been working on an improved checkout process in camp10, but now you need to overhaul your shipping calculation logic. Creating another camp for that is easy:

mkcamp --comment="overhaul shipping calculation"

The new camp number will be 11 by default. This camp11 resides alongside camp10 in your home directory with an identical structure. You can easily switch between your two projects since they’re both under user "john".

You can create as many camps as you need and have resources for. Since each camp is a complete copy of your production site, each will need the same amount of disk space and a comparable amount of RAM. You can shut off camps not being actively used to free up RAM.

Starting, stopping, and restarting camp services is done with the "re" command while working within the relevant camp directory:

cd ~/camp10
re --all          # restart is the default action
re --all --start
re --all --stop

Removing a camp is also easy. Simply get out of its directory, and use the "rmcamp" command:

rmcamp --number=11

Your camp database listens on a custom socket and the shortcut to access the SQL shell is:

# or mysql_camp

Your SpreeCamps server comes preinstalled with one camp, and with the production site.

The production site is called "live" in camps parlance, and the code resides under the user "spree" by default. But unlike camps, the production site uses the standard CentOS system Apache or nginx, Passenger or Unicorn, and PostgreSQL or MySQL. That means that starting, stopping, or restarting those services is done using the customary CentOS commands:

 service httpd restart       # which includes Passenger
 service postgresql restart  # or service mysqld restart

Note that these service commands must be executed as root, so you’ll need to use sudo or login as root to restart your production instance.

It also means that the "live" directory structure contains only the "rails" directory, not "httpd" and "pgsql", as those instead reside in the standard system-wide locations /usr/lib64/httpd, /usr/lib/pgsql, /var/lib/pgsql, and so on. Thus the production site consists of this directory tree:

`-- home/
    `-- spree/
        |-- .pgpass
        `-- live/
            `-- rails/
                `-- spree/
                    |-- .git/
                    |-- config/
                    |-- db/
                    |-- log/
                    |-- public/
                    |-- script/
                    |-- vendor/
                    |-- .gitignore
                    |-- CHANGELOG
                    |-- CONTRIBUTORS
                    |-- INSTALL
                    |-- LICENSE
                    |-- README.markdown
                    `-- Rakefile

To promote code changes from a camp to production, use Git.

Let’s say you finished your shipping calculation overhaul, and want to roll that out to the live site. You would already have committed your work to your camp’s Git repository:

 git commit -a -m "overhaul shipping calculation"

Now that you’re sure you want to promote it to production, push the changes out:

 git push

The central Git repository resides in the "camp" user’s directory, along with the various camp commands, configuration, and so on.

Now you bring the code into production by logging in as the "spree" production user (or using "su" or "sudo", etc.):

 ssh root@myhost
 su - spree
 cd live/rails/spree
 git pull

You may need to apply database migrations if this change requires any:

 rake db:migrate

Then you may need to go back to being root and restart Apache to pick up configuration changes or to restart Passenger to pick up code changes:

 service httpd restart

As soon as is convenient, you should "git pull" in other camps to bring in the changes so that you’re working against the latest code there.

If a camp has been around for a while, you may want to update its database with a recent dump from production, so you’re working against a realistic assortment and amount of data. Your camp server is set up to dump the production database early every morning so you always have a current database dump to import from:

 refresh-camp --db

Of course that will destroy any changes you made in your camp’s database, but anything of importance should be put in a migration file and committed to Git anyway.

This tutorial demonstrates a few workflows as an introduction to the DevCamps system. For further information, please view our DevCamps FAQ or contact us.