Hi Jeff, thanks for waiting patiently while we review your charm! Sorry it's taken so long to get to, but the first cut is looking great - please see my review below: # Proof These are the results run from charm-tools, available in ppa:juju/stable, and executed using `juju charm proof` in the charm directory: > I: all charms should provide at least one thing The first error is more of an informational piece, though all charms /should/ provide something. In this case I think the ghost charm is a perfect candidate to provide a relation using the HTTP interface. Doing so will allow it to be attached to loadbalancers and other charms which consume the http interface. > E: config.yaml: type of option config_file is specified as string, but the type of the default value is NoneType This is indicating that having null as the default of a string type config is a mismatch. Use an empty string "" to indicate a null match. W: config.yaml: option config_key does not have the keys: default, type This indicates that the config_key configuration option is missing the default and type keys. These are expected for all configuration options. # Review Continuing with config.yaml, if items are truly not implemented don't include them in the config.yaml. Remove them, or comment them out, so they're just not listed at all instead of having them listed as (TODO) in the description. Given the release string pattern, it'd be stellar to add a "release" or "version" configuration option so users could specify what version of ghost they wanted to use. Install hook fails idempotency checks, because it's moving assets instead of copying. You're upstart job runs ghost as root, when possible we recommend all services run as a normal user. http://upstart.ubuntu.com/cookbook/#setgid and http://upstart.ubuntu.com/cookbook/#setuid for how to achieve this in upstart. Start hook runs npm start & and opens port. Shouldn't it call the upstart job instead? Also is ghost usable without a MySQL database? If not, the open port should happen after database-relation-changed is run. Also, just noticed the configureSqlite, very cool. However, this will cause a problem and is not documented in the README. If you set up the blog, then add MySQL later, you'll lose your data. Same goes if you setup blog with MySQL and later remove the MySQL relation. There's a database-relation-changed file that I can't figure out if it's ever called. If it's not used, just remove it. db-relation-changed seems to achieve the same thing in much fewer lines. The README is super light on details, you'll want to document each of the configuration options more in depth, how the charm operates at different levels, how to add MySQL database and the ramifications of this, how to scale the service if applicable. README's should be written with the idea that "I'm a user, I just installed the GUI thing, and I want to deploy this, but I have no idea what I'm doing". # Knitpicks In line 7 of database-relation-changed, you exec touch, would it be better to use native V8 functions for this? Here's a slightly more simplified, upstart-esque, init file: http://paste.ubuntu.com/6703577/ As you may well know, ;), tests for charms will be required soon. You may want to take a look at the documentation we'll be publishing soon on writing tests for charms!