Adoptable Cookbooks List

Looking for a cookbook to adopt? You can now see a list of cookbooks available for adoption!
List of Adoptable Cookbooks

Supermarket Belongs to the Community

Supermarket belongs to the community. While Chef has the responsibility to keep it running and be stewards of its functionality, what it does and how it works is driven by the community. The chef/supermarket repository will continue to be where development of the Supermarket application takes place. Come be part of shaping the direction of Supermarket by opening issues and pull requests or by joining us on the Chef Mailing List.

Select Badges

Select Supported Platforms

Select Status

RSS

ghost (2) Versions 0.1.1

Installs and configures a Ghost blog

Policyfile
Berkshelf
Knife
cookbook 'ghost', '~> 0.1.1', :supermarket
cookbook 'ghost', '~> 0.1.1'
knife supermarket install ghost
knife supermarket download ghost
README
Dependencies
Quality 0%

ghost-cookbook

A Chef cookbook for building and managing a Ghost blog.

Features

  • Easily install new versions of Ghost by setting a version number in an attribute
  • Optionally merge with your own public or private Git repository to incorporate themes or customizations
  • Use SQLite as the database
  • Use Test Kitchen and ServerSpec for BDD awesomeness

Supported Platforms

  • Ubuntu >= 12.04
  • CentOS >= 6.5

Overview

Ghost is a great little blog engine, but it's not the easiest thing to work with if you're a Web developer into configuration management. Installing new versions is a pain, there's no great way to customize a theme (other than working over FTP and keeping your fingers crossed), and it doesn't suggest much of a workflow for keeping your site under revision control. This cookbook aims to fix all that by letting you work locally, test locally, commit to Github and use Chef to bring everything together, deploy and manage it.

Assumptions

This cookbook assumes a few things you should keep in mind:

  • It relies primarily on attributes, so it's currently one blog per node. Future versions might accomodate multiple blogs running on different ports, but for now, we're assuming you're okay with that.

  • You don't mind running SQLite in production. Some people have a philosophical issue with this, but most shouldn't: unless you're running a blog that's being updated very actively by multiple authors concurrently, or exceeding a million requests per day, it's unlikely you'll ever notice a problem — SQLite is fast and very happy to be flooded with reads. That said, I'll probably add an RDBMS recipe at some point, but I personally enjoy the simplicity and portability of a flat-file database, so that's what we have today.

  • Remote (content) repositories are presumed public by default. If you'd like to pull from a private (e.g., Github) repo, you'll need to generate a deployment key and add it to a chef-vault secret at vault/secrets/ghost/deploy-key. See the Workflow section below for specifics on how to do this.

  • Backups are up to you. I plan to include a recipe that addresses the obvious need to account for and capture content changes in production, but it's not there yet.

  • You're using a Chef server. Don't have one? Use Chef's. (It's free!) New to Chef? Start learning here.

Workflow

All you really need to do is upload this cookbook and its dependencies to your Chef server and run it; with only the default attributes, the default recipe alone will procuce a Ghost blog running on port 2368, and adding the nginx recipe will set up an Nginx server to proxy and expose it over port 80. (See below for a pasteable snippet that bootstraps a new node with both on Amazon EC2.)

Use the ghost-blog role (see test/integration/roles/ghost-blog.json for an example) as a shortcut to both set that run list and override any attributes you might prefer — e.g., to pull from a public repo I've set up containing a handful of free Ghost themes as a convenient jumping-off point:

{
  "name": "ghost-blog",
  "chef_type": "role",
  "json_class": "Chef::Role",
  "override_attributes": {
    "ghost": {
      "remote": {
        "name": "ghost-content",
        "repo": "https://github.com/cnunciato/ghost-content.git",
        "revision": "master"
      }
    }
  },
  "run_list": [
    "recipe[ghost]",
    "recipe[ghost::nginx]"
  ]
}

If you'd like to be able to develop locally and keep your changes under revision control, you'll need to download and install Ghost, create a repository from that, commit your changes and push to your remote, and then specify that remote as an override attribute — e.g., by modifying the ghost-blog role from above:

{
  "name": "ghost-blog",
  ...
  "override_attributes": {
    "ghost": {
      "remote": {
        "name": "your-repo",
        "repo": "https://github.com/yourusername/your-repo.git",
        "revision": "master"
      }
    }
  },
  ...
} 

In the example above, the assumption is that your repository is public, which doesn't work for everyone. If you'd like to pull from a private repo (e.g., it's a work thing, or you've got some paid themes you'd like to protect as a good citizen of the Internet), then you'll need — after your initial bootstrap (that's how chef-vault works) — to:

For example:

gem install chef-vault
ssh-keygen -t rsa "you@yourdomain.com" # and make sure you leave the passphrase blank

Create data_bags/vault/secrets.json, add your private key to it, then:

knife vault create vault secrets \
  --json data_bags/vault/secrets.json \
  --search 'role:ghost-blog' \
  --admins 'yourchefusername'
  --mode client

Update the role to use the new repo:

{
  "name": "ghost-blog",
  ...
  "override_attributes": {
    "ghost": {
      "remote": {
        "name": "your-private-repo",
        "repo": "git@github.com:yourusername/your-private-repo.git",
        "revision": "master"
      }
    }
  },
  ...
} 

And then run chef-client to pick up the changes:

knife ssh 'role:ghost-blog' 'sudo chef-client'

See test/integration/data_bags/vault/secrets.json for an example of the expected structure of secrets.json —just supply your (private, line-break-escaped) deploy key as the deploy-key value and you should be good to go. See the chef-vault documentation for additional details and examples.

Attributes

See attributes/default.rb for the set of default attributes. You can also specify additional/override attributes for mail-server settings, or to set your remote content repository as described above:

{
  "name": "ghost-blog",
  ...
  "override_attributes": {
    "ghost": {
      "app": {
        "mail": {
          "transport": "SMTP",
          "options": {
            "service": "Gmail",
            "auth": {
              "user": "your-designated-blog-email-address@gmail.com",
              "pass": "your-designated-blog-email-password"
            }
          }
        }
      },
      "remote": {
        "name": "your-private-repo",
        "repo": "git@github.com:yourusername/your-private-repo.git",
        "revision": "master"
      }
    }
  },
  ...
} 

Tests

If you're running VirtualBox and Vagrant, you can:

bundle install

... then run Test Kitchen and ServerSpec to verify Chef builds your node as you expect:

kitchen converge
kitchen verify

Issues

Bugs, features, comments? Use Github Issues.

A Quick Snip to Get Up and Running on EC2

Once you've got Chef installed, knife configured, and this cookbook (and its dependencies) uploaded to your Chef server, just swap in the path to your own EC2 key and go:

knife ec2 server create \
  --flavor t1.micro \
  --image ami-018c9568 \
  --availability-zone us-east-1d \
  --identity-file ~/.ssh/your-us-east-key.pem \
  --ssh-user ubuntu \
  --node-name 'my-ghost-blog' \
  --run-list 'recipe[ghost],recipe[ghost::nginx]'

This'll give you an Ubuntu 12.04 EBS-backed micro-instance running on port 80. (The usual charges may apply, of course.)

Author

Author:: Christian Nunciato (chris@nunciato.org)

Dependent cookbooks

apt >= 0.0.0
build-essential >= 0.0.0
nodejs ~> 1.3.0
chef-vault >= 0.0.0
sqlite >= 0.0.0
nginx >= 0.0.0
runit >= 0.0.0
git >= 0.0.0

Contingent cookbooks

There are no cookbooks that are contingent upon this one.

Collaborator Number Metric
            

0.1.1 failed this metric

Failure: Cookbook has 0 collaborators. A cookbook must have at least 2 collaborators to pass this metric.

Contributing File Metric
            

0.1.1 failed this metric

Failure: To pass this metric, your cookbook metadata must include a source url, the source url must be in the form of https://github.com/user/repo, and your repo must contain a CONTRIBUTING.md file

Foodcritic Metric
            

0.1.1 failed this metric

FC064: Ensure issues_url is set in metadata: ghost/metadata.rb:1
FC065: Ensure source_url is set in metadata: ghost/metadata.rb:1
FC066: Ensure chef_version is set in metadata: ghost/metadata.rb:1
FC069: Ensure standardized license defined in metadata: ghost/metadata.rb:1
FC104: Use the :run action in ruby_block instead of :create: ghost/recipes/default.rb:74
FC121: Cookbook depends on cookbook made obsolete by Chef 14: ghost/metadata.rb:1
FC122: Use the build_essential resource instead of the recipe: ghost/recipes/default.rb:21
Run with Foodcritic Version 16.3.0 with tags metadata,correctness ~FC031 ~FC045 and failure tags any

No Binaries Metric
            

0.1.1 failed this metric

Failure: Cookbook should not contain binaries. Found:
ghost/graph.png

Testing File Metric
            

0.1.1 failed this metric

Failure: To pass this metric, your cookbook metadata must include a source url, the source url must be in the form of https://github.com/user/repo, and your repo must contain a TESTING.md file

Version Tag Metric
            

0.1.1 failed this metric

Failure: To pass this metric, your cookbook metadata must include a source url, the source url must be in the form of https://github.com/user/repo, and your repo must include a tag that matches this cookbook version number