{"action":"created","comment":{"url":"https://api.github.com/repos/convox/convox.github.io/pulls/comments/39838298","id":39838298,"diff_hunk":"@@ -0,0 +1,331 @@\n+---\n+title: \"Developing an Application\"\n+sort: 11\n+---\n+## Local development\n+\n+Local development is hard to get right.\n+What starts as a simple install script sprawls into its own repository of bash scripts that run to completion on exactly the wrong person's machine.\n+\n+We seek a declarative solution that has a clean contract with the underlying operating system.\n+\n+Linux containers solve the clean contract and [dev/prod parity][dev-prod] problem by making virtualization cheap and reliable.\n+Docker is the de-facto open source standard for building and running linux containers:\n+by giving linux containers an API, Docker gives them a standard.\n+\n+Convox is the simplest and most intuitive way to leverage Docker for declarartive local development.\n+\n+## The Manifest(s)\n+\n+The manifest allows you to describe everything you need to run any application\n+consisting of containerized linux processes and cloud services.\n+\n+Convox uses three files to build and run your development environment:\n+\n+  - A `docker-compose.yml` file or a Procfile (referred to as the \"manifest\")\n+  - An optional `Dockerfile` to document your build (can be used instead of a manifest)\n+  - An optional `.env` to contain development secrets\n+\n+Only one of: `docker-compose.yml`, `Procfile`, or `Dockerfile` is required.\n+`convox start` will generate a `docker-compose.yml` from a `Dockerfile`.\n+It will generate a `docker-compose.yml` AND a `Dockerfile` from a `Procfile`.\n+\n+You will most likely need to customize these generated files until we add better project detection (pull requests welcome!).\n+\n+The other files are there to support information that is not in the manifest but\n+is required for a determinstic and declarative way to run your software.\n+\n+The build instructions, in the `Dockerfile`, defines how create your software from source code.\n+\n+The enviroment data, in the `.env`, allows you to configure your development enviroment.\n+\n+## Convox commands\n+\n+### `convox start`\n+\n+Convox supports a [Docker][docker] based local development workflow via the `convox start`\n+[CLI][cli] command.\n+\n+Like [docker-compose][compose], `convox` is a tool for defining and running\n+multi-container applications with Docker.\n+However, `convox start` is only focused on local development and offloads as much work as possible\n+to Docker itself.\n+\n+`convox start` builds and runs the processes decalared in your application manifest with environment\n+stored in a `.env` file and interleaves the standard output and standard error of those processes.\n+It allows Docker to act as build service, runtime, and process manager.\n+\n+For example:\n+\n+    $ cd $GOPATH/src/github.com/convox/rack/examples/procfile\n+    $ convox start\n+    RUNNING: docker build -t knexsfvjdc /Users/csquared/projects/go/src/github.com/convox/rack/examples/procfile\n+    Sending build context to Docker daemon 8.192 kB\n+    Step 0 : FROM ruby:2.2.2\n+     ---> 9664620d4c2a\n+    Step 1 : EXPOSE 3000\n+     ---> Running in d2894bf8d64b\n+\n+    ...\n+\n+    RUNNING: docker tag -f ejjcgsgjgh procfile/web\n+    RUNNING: docker tag -f ejjcgsgjgh procfile/worker\n+    web    | running: docker run -i --name procfile-web -p 5000:3000 procfile/web sh -c ruby web.rb\n+    web    | [2015-09-18 06:16:53] INFO  WEBrick 1.3.1\n+    web    | [2015-09-18 06:16:53] INFO  ruby 2.2.2 (2015-04-13) [x86_64-linux]\n+    web    | == Sinatra (v1.4.6) has taken the stage on 3000 for development with backup from WEBrick\n+    web    | [2015-09-18 06:16:53] INFO  WEBrick::HTTPServer#start: pid=7 port=3000\n+    worker | running: docker run -i --name procfile-worker -p 5100:3000 procfile/worker sh -c ruby worker.rb\n+    worker | working!\n+    worker | working!\n+    worker | working!\n+    ^C\n+    $\n+\n+\n+A `CTRL+C` on the `convox start` process stops everything and exits.\n+\n+By using Docker, Convox is able to achieve fast setup and teardown, dev/prod parity, and an intuitive developer experience behind a simple command.\n+\n+\n+### `convox exec <process> <command>`\n+\n+Convox supports executing a command within the context of one of your local running processes via the `convox exec`[CLI][cli] command.\n+\n+This allows you to administer your development app via [one-off processes][12fac-oneoff] using the same commands you would pass to `convox run`. For example, you could run database migrations via:\n+\n+    $ convox exec web rake db:migrate\n+\n+Depending on your base image's operating system, you can can also start a shell for interactive debugging:\n+\n+    $ convox exec main bash\n+    $ convox exec web sh\n+\n+Or start an interactive session with your favorate REPL:\n+\n+    $ convox exec web rails console    # rails\n+    $ convox exec web node             # node.js\n+    $ convox exec main psql <host>     # SQL session\n+\n+Your only limit is the software in your manifest!\n+\n+## The Manifest(s) (continued)\n+\n+Let's take a look at the manifest, the build instructions, and the environment\n+and how they interact in the context of the [Convox Sinatra Example](https://github.com/convox-examples/sinatra).\n+\n+### `docker-compose.yml`\n+\n+The `docker-compose.yml` looks like this:\n+\n+    web: &web\n+      build: .\n+      command: bin/web\n+      environment:\n+        - RACK_ENV=development\n+        - POSTGRES_URL=postgres://postgres:password@postgres:5432/app\n+        - REDIS_URL=redis://redis:password@redis:6379/0\n+      ports:\n+        - 3000:3000\n+      volumes:\n+        - .:/app\n+      links:\n+        - postgres\n+        - redis\n+    worker:\n+      <<: *web\n+      ports: []\n+    redis:\n+      image: convox/redis\n+    postgres:\n+      image: convox/postgres\n+\n+\n+The `&web` reference is yaml syntax that allows you to name and copy parameters from one hash to another.\n+This allows us to assign all the same configuration to `worker` process with the syntax `<<: *web`.\n+Notice how we have to then clear the port mappings. Why we do this will become clear below.\n+\n+Each top level key defines the configuration necessary to run a process for your application.\n+If the parameters look familiar, it is because they are.\n+Everything [docker compose][compose-conf] supports is also supported here.\n+\n+This particular manifest describes four processes: `main`, `worker`, `postgres`, and `redis`.\n+The `postgres` and `redis` processes are both images, which means they are already built.\n+They are pulled from [Docker Hub][docker-hub] during `convox start` using `docker pull`.\n+\n+The `main` process has a `build` key.\n+That instructs `convox start` to build an image using the `Dockerfile` in the specified directory.\n+\n+The `ports` key is passsed to `docker run` and determines port mappings for the host VM.\n+In this example, the port 5000 of the docker host machine is being mapped to port 3000 in the container.\n+\n+The `worker` process configuration is copied from web because it is built with the same codebase,\n+talks to the same database, and otherwise shares everything in common with the `web` process except the command.\n+\n+And the ports. We've already mapping `3000` on the host container to the exposed `3000` on `main`.\n+Because we can't have two processes on the same port, this will cause an error starting the `worker`.\n+\n+<div class=\"block-callout block-show-callout type-info\">\n+<h3>Ports</h3>\n+<p>You can either explicity map ports from the host os via \"HOST:CONTAINER\" syntax\n+in the manifest, but that can lead to conflicts.\n+This is usually only necessary few to one process in your application to explicitly define a port and\n+that is usually to communicate with an external load balancer..\n+</p>\n+\n+<p>\n+When possible, it is better to avoid picking ports and to use container linking and/or `docker port` to query\n+exposed port values.\n+This\n+allows the image to bind to a known port within a container but still allow\n+docker to map arbitrary ports to your container.\n+</p>\n+</div>\n+\n+The `volumes` key is passed to `docker run` to mount a volume for read and write access into the running container.\n+This is useful for mapping in config files that exist in your source repository or for mapping the\n+source code directories into the docker conatiner so you can do code reloading on change detection.\n+\n+The `links` key defines dependencies on other processes named in this file.\n+`convox start` uses [docker container linking][docker-links] to connect processes in development.\n+In general, it is a good practice to have containers wait for connections they expect to become available.\n+This way if the main process completes startups before the database you don't throw an error because the connection is not there.\n+\n+You can read more about [the docker-compose configuration options][compose-conf] on Docker's website.\n+\n+### `Dockerfile`\n+\n+A `Dockerfile` looks like this:\n+\n+    FROM gliderlabs/alpine:3.2\n+\n+    RUN apk-install ruby ruby-bundler ruby-io-console ruby-kgio ruby-pg ruby-raindrops ruby-unicorn\n+\n+    WORKDIR /app\n+\n+    # cache bundler\n+    COPY Gemfile /app/Gemfile\n+    COPY Gemfile.lock /app/Gemfile.lock\n+    RUN bundle install\n+\n+    # copy the rest of the app\n+    COPY . /app\n+\n+    ENTRYPOINT [\"bundle\", \"exec\"]\n+    CMD [\"bin\", \"web\"]\n+\n+It describes the steps you need to build and run a unix process.\n+\n+The `FROM` declaration specifies your \"base image\".\n+For applications you are developing, it is most common to start with a minimal operating\n+system or a language-specific image manintained by that language's community.\n+\n+In Docker, a build takes place in terms of the \"build context\", which is basically a\n+snapshot of the directory you're currently in when you run `docker build` or `convox start`.\n+\n+`COPY` (and `ADD`, not shown here) commands move files from the build context into the\n+image. `RUN` executes the given command in the context of the image.\n+\n+`EXPOSE` allows docker to know which tcp or udp ports the application binds to.\n+If you do not publish the port it is only avaiable via name to a [linked service][docker-links].\n+\n+\n+\n+`ENTRYPOINT` and `CMD` control the default command that is executed via `docker run`.\n+You can think of `CMD` as setting a default, whereas `ENTRYPOINT` should do any\n+necessary runtime configuration. This may include adding config files from a known\n+location, setting up the environment, or waiting on resources to become available.\n+\n+It is extremely common for entrypoint scripts to do their work in shell and end with:\n+\n+    exec \"$@\"\n+\n+Both `ENTRYPOINT` and `CMD` can be overriden at runtime. In fact, everything in the\n+build can be overridden or augmented with information passed to `docker run`.\n+That's the very reason we need something like `docker-compose.yml`!\n+\n+To be fair, every deviation from the vanilla `docker run <image>` invocation has the potential\n+to change behavior.\n+This is why a `Dockerfile` alone is not enough to describe an application.\n+\n+For more information on how to write Dockerfiles, see the [Docker user guide][docker-ug] and the [Dockerfile reference][dockerfile-ref].\n+\n+### `.env`\n+\n+A `Dockerfile` and `docker-compose.yml` *should* be enough to describe your application.\n+Where there are no private credentials or all linked services have known,\n+deterministic credentials, a `Dockerfile` and `docker-compose.yml` are enough.\n+\n+However, we have found that some credentials are only possible or significantly easier to generate outside of the application.\n+This can often be the case with cloud resources; there just isn't a simple solution to running large parts of the internet on your laptop.\n+\n+To support this use-case, we automatically populate `enivronment` variables that are listed in the manifest but not declared to equal anything (no equals sign) with `KEY=VALUE` pairs from your `.env` file.\n+\n+## Bringing it together\n+\n+Instead of telling you, let's use convox to show exactly how the `.env` file works.\n+\n+We can start with a simple `docker-compose.yml` and a minimal linux distribution so we can have the `env` command available.\n+Since we don't need to install anything on top of the base image, we don't need a `Dockerfile`.\n+\n+Here's a `docker-compose.yml` that we can use:\n+\n+    main:\n+      image: gliderlabs/alpine:3.2\n+      environment:\n+        - TEST_ONE\n+        - TEST_TWO=\n+        - TEST_THREE=3\n+      command: env | grep TEST\n+\n+Now simply running `convox start`:\n+\n+    RUNNING: docker pull gliderlabs/alpine:3.2\n+    3.2: Pulling from gliderlabs/alpine\n+    2cc966a5578a: Already exists\n+    Digest: sha256:10e5a41452c61b36a936384c6162588142d95299ea8b67fa7e52eef6f934bd88\n+    Status: Image is up to date for gliderlabs/alpine:3.2\n+    RUNNING: docker tag -f gliderlabs/alpine:3.2 test-env/main\n+    main | running: docker run -i --name test-env-main -e TEST_ONE= -e TEST_TWO= -e TEST_THREE=3 test-env/main sh -c env | grep TEST\n+    main | TEST_TWO=\n+    main | TEST_THREE=3\n+    main | TEST_ONE=\n+\n+Here you can see we build the image, then print out the exact command used to run the container, and then run the command.\n+Most servers won't exit, but our command does.\n+Notice we get what we expect: `TEST_THREE` has a value, but `TEST_ONE` and `TEST_TWO` do not.\n+\n+Now let's create a `.env` file:\n+\n+    TEST_ONE=1\n+    TEST_TWO=2\n+    TEST_THREE=4\n+\n+What do you think will happen? As stated above, we'll populate variables that are undeclared, ie: have not equals sign.\n+\n+This is to fit with the expected meaning: `TEST_ONE` is declared to exist, whereas we interpret `TEST_TWO=`\n+as being declared _and initilized to the empty string_.","path":"_getting_started/developing-locally.md","position":307,"original_position":307,"commit_id":"e3ae12e668c68a0a4d4c9a12afdd13ff7a7d6ff3","original_commit_id":"e3ae12e668c68a0a4d4c9a12afdd13ff7a7d6ff3","user":{"login":"slaskis","id":5991,"avatar_url":"https://avatars.githubusercontent.com/u/5991?v=3","gravatar_id":"","url":"https://api.github.com/users/slaskis","html_url":"https://github.com/slaskis","followers_url":"https://api.github.com/users/slaskis/followers","following_url":"https://api.github.com/users/slaskis/following{/other_user}","gists_url":"https://api.github.com/users/slaskis/gists{/gist_id}","starred_url":"https://api.github.com/users/slaskis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/slaskis/subscriptions","organizations_url":"https://api.github.com/users/slaskis/orgs","repos_url":"https://api.github.com/users/slaskis/repos","events_url":"https://api.github.com/users/slaskis/events{/privacy}","received_events_url":"https://api.github.com/users/slaskis/received_events","type":"User","site_admin":false},"body":"initi*a*lized","created_at":"2015-09-18T09:31:51Z","updated_at":"2015-09-18T09:31:51Z","html_url":"https://github.com/convox/convox.github.io/pull/41#discussion_r39838298","pull_request_url":"https://api.github.com/repos/convox/convox.github.io/pulls/41","_links":{"self":{"href":"https://api.github.com/repos/convox/convox.github.io/pulls/comments/39838298"},"html":{"href":"https://github.com/convox/convox.github.io/pull/41#discussion_r39838298"},"pull_request":{"href":"https://api.github.com/repos/convox/convox.github.io/pulls/41"}}},"pull_request":{"url":"https://api.github.com/repos/convox/convox.github.io/pulls/41","id":45378042,"html_url":"https://github.com/convox/convox.github.io/pull/41","diff_url":"https://github.com/convox/convox.github.io/pull/41.diff","patch_url":"https://github.com/convox/convox.github.io/pull/41.patch","issue_url":"https://api.github.com/repos/convox/convox.github.io/issues/41","number":41,"state":"open","locked":false,"title":"[wip] document local development","user":{"login":"csquared","id":173457,"avatar_url":"https://avatars.githubusercontent.com/u/173457?v=3","gravatar_id":"","url":"https://api.github.com/users/csquared","html_url":"https://github.com/csquared","followers_url":"https://api.github.com/users/csquared/followers","following_url":"https://api.github.com/users/csquared/following{/other_user}","gists_url":"https://api.github.com/users/csquared/gists{/gist_id}","starred_url":"https://api.github.com/users/csquared/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/csquared/subscriptions","organizations_url":"https://api.github.com/users/csquared/orgs","repos_url":"https://api.github.com/users/csquared/repos","events_url":"https://api.github.com/users/csquared/events{/privacy}","received_events_url":"https://api.github.com/users/csquared/received_events","type":"User","site_admin":false},"body":"heavily edited first draft. time to take in some feedback.\nits a bit late so will need to follow up with at least one more round\nof editing.","created_at":"2015-09-18T07:49:42Z","updated_at":"2015-09-18T09:31:51Z","closed_at":null,"merged_at":null,"merge_commit_sha":"4c049f7e1c0e446d5e8f4fd2588d99cf2396c519","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/convox/convox.github.io/pulls/41/commits","review_comments_url":"https://api.github.com/repos/convox/convox.github.io/pulls/41/comments","review_comment_url":"https://api.github.com/repos/convox/convox.github.io/pulls/comments{/number}","comments_url":"https://api.github.com/repos/convox/convox.github.io/issues/41/comments","statuses_url":"https://api.github.com/repos/convox/convox.github.io/statuses/e3ae12e668c68a0a4d4c9a12afdd13ff7a7d6ff3","head":{"label":"convox:doc-local-dev","ref":"doc-local-dev","sha":"e3ae12e668c68a0a4d4c9a12afdd13ff7a7d6ff3","user":{"login":"convox","id":10547780,"avatar_url":"https://avatars.githubusercontent.com/u/10547780?v=3","gravatar_id":"","url":"https://api.github.com/users/convox","html_url":"https://github.com/convox","followers_url":"https://api.github.com/users/convox/followers","following_url":"https://api.github.com/users/convox/following{/other_user}","gists_url":"https://api.github.com/users/convox/gists{/gist_id}","starred_url":"https://api.github.com/users/convox/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/convox/subscriptions","organizations_url":"https://api.github.com/users/convox/orgs","repos_url":"https://api.github.com/users/convox/repos","events_url":"https://api.github.com/users/convox/events{/privacy}","received_events_url":"https://api.github.com/users/convox/received_events","type":"Organization","site_admin":false},"repo":{"id":33002637,"name":"convox.github.io","full_name":"convox/convox.github.io","owner":{"login":"convox","id":10547780,"avatar_url":"https://avatars.githubusercontent.com/u/10547780?v=3","gravatar_id":"","url":"https://api.github.com/users/convox","html_url":"https://github.com/convox","followers_url":"https://api.github.com/users/convox/followers","following_url":"https://api.github.com/users/convox/following{/other_user}","gists_url":"https://api.github.com/users/convox/gists{/gist_id}","starred_url":"https://api.github.com/users/convox/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/convox/subscriptions","organizations_url":"https://api.github.com/users/convox/orgs","repos_url":"https://api.github.com/users/convox/repos","events_url":"https://api.github.com/users/convox/events{/privacy}","received_events_url":"https://api.github.com/users/convox/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/convox/convox.github.io","description":"Convox Docs","fork":false,"url":"https://api.github.com/repos/convox/convox.github.io","forks_url":"https://api.github.com/repos/convox/convox.github.io/forks","keys_url":"https://api.github.com/repos/convox/convox.github.io/keys{/key_id}","collaborators_url":"https://api.github.com/repos/convox/convox.github.io/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/convox/convox.github.io/teams","hooks_url":"https://api.github.com/repos/convox/convox.github.io/hooks","issue_events_url":"https://api.github.com/repos/convox/convox.github.io/issues/events{/number}","events_url":"https://api.github.com/repos/convox/convox.github.io/events","assignees_url":"https://api.github.com/repos/convox/convox.github.io/assignees{/user}","branches_url":"https://api.github.com/repos/convox/convox.github.io/branches{/branch}","tags_url":"https://api.github.com/repos/convox/convox.github.io/tags","blobs_url":"https://api.github.com/repos/convox/convox.github.io/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/convox/convox.github.io/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/convox/convox.github.io/git/refs{/sha}","trees_url":"https://api.github.com/repos/convox/convox.github.io/git/trees{/sha}","statuses_url":"https://api.github.com/repos/convox/convox.github.io/statuses/{sha}","languages_url":"https://api.github.com/repos/convox/convox.github.io/languages","stargazers_url":"https://api.github.com/repos/convox/convox.github.io/stargazers","contributors_url":"https://api.github.com/repos/convox/convox.github.io/contributors","subscribers_url":"https://api.github.com/repos/convox/convox.github.io/subscribers","subscription_url":"https://api.github.com/repos/convox/convox.github.io/subscription","commits_url":"https://api.github.com/repos/convox/convox.github.io/commits{/sha}","git_commits_url":"https://api.github.com/repos/convox/convox.github.io/git/commits{/sha}","comments_url":"https://api.github.com/repos/convox/convox.github.io/comments{/number}","issue_comment_url":"https://api.github.com/repos/convox/convox.github.io/issues/comments{/number}","contents_url":"https://api.github.com/repos/convox/convox.github.io/contents/{+path}","compare_url":"https://api.github.com/repos/convox/convox.github.io/compare/{base}...{head}","merges_url":"https://api.github.com/repos/convox/convox.github.io/merges","archive_url":"https://api.github.com/repos/convox/convox.github.io/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/convox/convox.github.io/downloads","issues_url":"https://api.github.com/repos/convox/convox.github.io/issues{/number}","pulls_url":"https://api.github.com/repos/convox/convox.github.io/pulls{/number}","milestones_url":"https://api.github.com/repos/convox/convox.github.io/milestones{/number}","notifications_url":"https://api.github.com/repos/convox/convox.github.io/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/convox/convox.github.io/labels{/name}","releases_url":"https://api.github.com/repos/convox/convox.github.io/releases{/id}","created_at":"2015-03-27T18:31:13Z","updated_at":"2015-09-15T22:15:29Z","pushed_at":"2015-09-18T07:58:01Z","git_url":"git://github.com/convox/convox.github.io.git","ssh_url":"git@github.com:convox/convox.github.io.git","clone_url":"https://github.com/convox/convox.github.io.git","svn_url":"https://github.com/convox/convox.github.io","homepage":"","size":2111,"stargazers_count":19,"watchers_count":19,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":14,"mirror_url":null,"open_issues_count":10,"forks":14,"open_issues":10,"watchers":19,"default_branch":"master"}},"base":{"label":"convox:master","ref":"master","sha":"b622fcdf2c6a552a92092c5e580404a2310a2dc3","user":{"login":"convox","id":10547780,"avatar_url":"https://avatars.githubusercontent.com/u/10547780?v=3","gravatar_id":"","url":"https://api.github.com/users/convox","html_url":"https://github.com/convox","followers_url":"https://api.github.com/users/convox/followers","following_url":"https://api.github.com/users/convox/following{/other_user}","gists_url":"https://api.github.com/users/convox/gists{/gist_id}","starred_url":"https://api.github.com/users/convox/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/convox/subscriptions","organizations_url":"https://api.github.com/users/convox/orgs","repos_url":"https://api.github.com/users/convox/repos","events_url":"https://api.github.com/users/convox/events{/privacy}","received_events_url":"https://api.github.com/users/convox/received_events","type":"Organization","site_admin":false},"repo":{"id":33002637,"name":"convox.github.io","full_name":"convox/convox.github.io","owner":{"login":"convox","id":10547780,"avatar_url":"https://avatars.githubusercontent.com/u/10547780?v=3","gravatar_id":"","url":"https://api.github.com/users/convox","html_url":"https://github.com/convox","followers_url":"https://api.github.com/users/convox/followers","following_url":"https://api.github.com/users/convox/following{/other_user}","gists_url":"https://api.github.com/users/convox/gists{/gist_id}","starred_url":"https://api.github.com/users/convox/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/convox/subscriptions","organizations_url":"https://api.github.com/users/convox/orgs","repos_url":"https://api.github.com/users/convox/repos","events_url":"https://api.github.com/users/convox/events{/privacy}","received_events_url":"https://api.github.com/users/convox/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/convox/convox.github.io","description":"Convox Docs","fork":false,"url":"https://api.github.com/repos/convox/convox.github.io","forks_url":"https://api.github.com/repos/convox/convox.github.io/forks","keys_url":"https://api.github.com/repos/convox/convox.github.io/keys{/key_id}","collaborators_url":"https://api.github.com/repos/convox/convox.github.io/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/convox/convox.github.io/teams","hooks_url":"https://api.github.com/repos/convox/convox.github.io/hooks","issue_events_url":"https://api.github.com/repos/convox/convox.github.io/issues/events{/number}","events_url":"https://api.github.com/repos/convox/convox.github.io/events","assignees_url":"https://api.github.com/repos/convox/convox.github.io/assignees{/user}","branches_url":"https://api.github.com/repos/convox/convox.github.io/branches{/branch}","tags_url":"https://api.github.com/repos/convox/convox.github.io/tags","blobs_url":"https://api.github.com/repos/convox/convox.github.io/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/convox/convox.github.io/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/convox/convox.github.io/git/refs{/sha}","trees_url":"https://api.github.com/repos/convox/convox.github.io/git/trees{/sha}","statuses_url":"https://api.github.com/repos/convox/convox.github.io/statuses/{sha}","languages_url":"https://api.github.com/repos/convox/convox.github.io/languages","stargazers_url":"https://api.github.com/repos/convox/convox.github.io/stargazers","contributors_url":"https://api.github.com/repos/convox/convox.github.io/contributors","subscribers_url":"https://api.github.com/repos/convox/convox.github.io/subscribers","subscription_url":"https://api.github.com/repos/convox/convox.github.io/subscription","commits_url":"https://api.github.com/repos/convox/convox.github.io/commits{/sha}","git_commits_url":"https://api.github.com/repos/convox/convox.github.io/git/commits{/sha}","comments_url":"https://api.github.com/repos/convox/convox.github.io/comments{/number}","issue_comment_url":"https://api.github.com/repos/convox/convox.github.io/issues/comments{/number}","contents_url":"https://api.github.com/repos/convox/convox.github.io/contents/{+path}","compare_url":"https://api.github.com/repos/convox/convox.github.io/compare/{base}...{head}","merges_url":"https://api.github.com/repos/convox/convox.github.io/merges","archive_url":"https://api.github.com/repos/convox/convox.github.io/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/convox/convox.github.io/downloads","issues_url":"https://api.github.com/repos/convox/convox.github.io/issues{/number}","pulls_url":"https://api.github.com/repos/convox/convox.github.io/pulls{/number}","milestones_url":"https://api.github.com/repos/convox/convox.github.io/milestones{/number}","notifications_url":"https://api.github.com/repos/convox/convox.github.io/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/convox/convox.github.io/labels{/name}","releases_url":"https://api.github.com/repos/convox/convox.github.io/releases{/id}","created_at":"2015-03-27T18:31:13Z","updated_at":"2015-09-15T22:15:29Z","pushed_at":"2015-09-18T07:58:01Z","git_url":"git://github.com/convox/convox.github.io.git","ssh_url":"git@github.com:convox/convox.github.io.git","clone_url":"https://github.com/convox/convox.github.io.git","svn_url":"https://github.com/convox/convox.github.io","homepage":"","size":2111,"stargazers_count":19,"watchers_count":19,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":14,"mirror_url":null,"open_issues_count":10,"forks":14,"open_issues":10,"watchers":19,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/convox/convox.github.io/pulls/41"},"html":{"href":"https://github.com/convox/convox.github.io/pull/41"},"issue":{"href":"https://api.github.com/repos/convox/convox.github.io/issues/41"},"comments":{"href":"https://api.github.com/repos/convox/convox.github.io/issues/41/comments"},"review_comments":{"href":"https://api.github.com/repos/convox/convox.github.io/pulls/41/comments"},"review_comment":{"href":"https://api.github.com/repos/convox/convox.github.io/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/convox/convox.github.io/pulls/41/commits"},"statuses":{"href":"https://api.github.com/repos/convox/convox.github.io/statuses/e3ae12e668c68a0a4d4c9a12afdd13ff7a7d6ff3"}}}}