{"action":"created","comment":{"url":"https://api.github.com/repos/gamechanger/dusty/pulls/comments/33174227","id":33174227,"diff_hunk":"@@ -0,0 +1,132 @@\n+# Dusty App Specs\n+These specs are used to specify apps for you local environment. They should go in the apps folder in your specs repo.\n+\n+## Keys\n+\n+### repo\n+```\n+repo: github.com/gamechanger/app1\n+repo: /Users/dusty/app1\n+```\n+This repo key is used to specify a local or remote github repo where the code for the app lives.\n+\n+### mount\n+```\n+mount: /gc/app1\n+```\n+The mount key is used to specify where in the container's file system to mount the code specified by the repo key.  The mounting is done using docker's volume mounts. <br />\n+Using the image and mount keys specified above, the code specified in `/Users/dusty/app1` on your mac will be visible in your container at `/gc/app1`.<br />\n+The repo and mount keys are linked.  If you specify one you must specify the other. If you do not specify one, you cannot specify the other.<br />\n+\n+\n+### depends\n+```\n+depends:\n+  services:\n+    - coreMongo\n+    - coreRedis\n+  apps:\n+    - deferrableworker\n+    - docketsworker\n+  libs:\n+    - gclib\n+```\n+The depends key is used to specify what libs, apps and services this app depends on.<br />\n+Apps and services specified in the depends dict are spun up before the current app. The current app is then linked (using docker-compose's links) to the apps and services. Because we are using docker-compose links, dependencies must only be 1 way.  This means you cannot have app1 depend on app2 and app2 depend on app1.<br />\n+Libs specified in the depends dict have a different meaning.  They tell dusty that these libs (and their recursive dependencies) need to be mounted into this app's container (using docker's volume mounts).  In so doing, the running app will have access to the most recent code in these libs.<br />\n+The values corresponding to the services, apps, and libs keys are all lists.<br />\n+\n+### conditional_links\n+```\n+conditional_links:\n+  apps:\n+    - app2\n+```\n+The conditional_links key is similar to the depends key. There are some big differences though. First, the conditional_links key can only specify apps. Second, the current app will only link to the apps specified (here app2), if the app has already been specified in a 1 of 2 other ways. <br/>\n+1. It is specified in different activated app's depends dict. <br/>\n+2. It is specified in an activated bundles apps list. <br/>\n+As in the depends dict, circular dependencies are still not allowed.\n+\n+### host_forwarding\n+```\n+host_forwarding:\n+  - host_name: local.website.com\n+    host_port: 80\n+    container_port: 80\n+```\n+The host_forwarding key is used specify a list of dictionaries.  Each dictionary allows you to specify a mapping from the containers ip space to your mac's ip space.<br />\n+**host_name** is the local url you would like to hit.<br />\n+**host_port** is the port on which you will hit the host_name.<br />\n+**container_port** is the port the app is running on in the docker container.<br />\n+\n+### image and build\n+```\n+build .\n+```\n+OR\n+```\n+image: docker.gamechanger.io/gcweb\n+```\n+The image and build keys are linked because one, but not both, must be specified. These keys are used to specify how to get a base image for this app's container.<br />\n+**build** is a path to a Dockerfile's parent directory.<br />\n+**image** is a local or remote image.  Dusty (using docker-compose) will attempt to pull the image if it is not found locally.<br />\n+Both keys are direct mappings to keys in docker-compose.<br />\n+\n+### commands\n+```\n+commands:\n+  once:\n+    - apt-get update\n+    - apt-get install -y nodejs npm\n+    - cp /usr/bin/nodejs /usr/bin/node\n+    - cd /gc/gcweb/grunt &\n+  always:\n+    - mkdir -p /var/log/gc\n+    - cd /gc/gcweb\n+    - python manage.py runserver --noreload\n+```\n+The commands key is used to specify a list of once and always commands.  These commands are run at different times in the container's life cycle.<br />\n+The once commands will only be run the first time an app is started. This mainly occurs if you are running `dusty up`.<br />\n+The always commands are run every time the app restarts. This includes on `dusty up`, but also when you do `dusty restart <app_name>`.<br />\n+Two sets of commands allows you to do the heavy work of installation in the once command. This frees your restart commands to be very fast and responsive.<br />\n+Both the once and always commands are run from an sh file.  This gives you all the flexibility of writing an sh file, including running things in the background (&).<br />\n+We are also keeping track of the once and always commands progress using logs automatically created for you in your containers. The always' commands' log is `/var/log/dusty_always.log`. The once's commands' log is `/var/log/dusty_once.log`.<br />\n+\n+### scripts\n+```\n+scripts:\n+    - name: grunt\n+      description: Build assets compiled by Grunt (CSS, JS, that sort of thing)\n+      command:\n+        - cd /gc/gcweb/grunt\n+        - /gc/gcweb/grunt/node_modules/.bin/grunt build\n+    - name: grunt-clean\n+      description: Remove all compiled files generated by Grunt\n+      command:\n+        - cd /gc/gcweb/grunt\n+        - /gc/gcweb/grunt/node_modules/.bin/grunt clean\n+```\n+The scripts key is used to specify a list of scripts that can be run in each container.<br />\n+**name** specifies how you would call the the script. If the current spec is for app1, I could execute the following two scripts:<br />\n+* `dusty scripts app1 grunt`\n+* `dusty scripts app1 grunt-clean`\n+\n+Scripts are run in an sh file (like the once and always commands).<br />\n+Scripts can accept arguments.  Arguments will be passed through to the final command specified by the command key.<br />\n+\n+### compose\n+```\n+compose:\n+  environment:\n+    gcenv: local\n+    PYTHONPATH: /gc/gclib/python:/gc\n+    MONGO_URI: coreMongo\n+    NUMBERS_DB_URI: coreMongo\n+    CACHE_DB_URI: coreMongo\n+    REDIS_HOST: coreRedis\n+    DOCKETS_REDIS_HOST: coreRedis\n+    SESSION_REDIS_HOST: coreRedis\n+    SSO_REDIS_HOST: coreRedis","path":"docs/dusty-specs/app-specs.md","position":129,"original_position":129,"commit_id":"31571434e15ea985f2e8541b41bb29afd90ec36c","original_commit_id":"101489ea1fe0f2f6918ea2a9ef68a0769fbd2160","user":{"login":"thieman","id":1414305,"avatar_url":"https://avatars.githubusercontent.com/u/1414305?v=3","gravatar_id":"","url":"https://api.github.com/users/thieman","html_url":"https://github.com/thieman","followers_url":"https://api.github.com/users/thieman/followers","following_url":"https://api.github.com/users/thieman/following{/other_user}","gists_url":"https://api.github.com/users/thieman/gists{/gist_id}","starred_url":"https://api.github.com/users/thieman/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/thieman/subscriptions","organizations_url":"https://api.github.com/users/thieman/orgs","repos_url":"https://api.github.com/users/thieman/repos","events_url":"https://api.github.com/users/thieman/events{/privacy}","received_events_url":"https://api.github.com/users/thieman/received_events","type":"User","site_admin":false},"body":"Simplify heavily","created_at":"2015-06-24T17:41:46Z","updated_at":"2015-06-24T17:41:46Z","html_url":"https://github.com/gamechanger/dusty/pull/294#discussion_r33174227","pull_request_url":"https://api.github.com/repos/gamechanger/dusty/pulls/294","_links":{"self":{"href":"https://api.github.com/repos/gamechanger/dusty/pulls/comments/33174227"},"html":{"href":"https://github.com/gamechanger/dusty/pull/294#discussion_r33174227"},"pull_request":{"href":"https://api.github.com/repos/gamechanger/dusty/pulls/294"}}},"pull_request":{"url":"https://api.github.com/repos/gamechanger/dusty/pulls/294","id":38453675,"html_url":"https://github.com/gamechanger/dusty/pull/294","diff_url":"https://github.com/gamechanger/dusty/pull/294.diff","patch_url":"https://github.com/gamechanger/dusty/pull/294.patch","issue_url":"https://api.github.com/repos/gamechanger/dusty/issues/294","number":294,"state":"open","locked":false,"title":"add in rough copy of the apps specs","user":{"login":"paetling","id":3281726,"avatar_url":"https://avatars.githubusercontent.com/u/3281726?v=3","gravatar_id":"","url":"https://api.github.com/users/paetling","html_url":"https://github.com/paetling","followers_url":"https://api.github.com/users/paetling/followers","following_url":"https://api.github.com/users/paetling/following{/other_user}","gists_url":"https://api.github.com/users/paetling/gists{/gist_id}","starred_url":"https://api.github.com/users/paetling/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/paetling/subscriptions","organizations_url":"https://api.github.com/users/paetling/orgs","repos_url":"https://api.github.com/users/paetling/repos","events_url":"https://api.github.com/users/paetling/events{/privacy}","received_events_url":"https://api.github.com/users/paetling/received_events","type":"User","site_admin":false},"body":"WIP","created_at":"2015-06-24T15:20:50Z","updated_at":"2015-06-24T17:41:46Z","closed_at":null,"merged_at":null,"merge_commit_sha":"37875d223c16f621e1a3814774b2a447d4a326f5","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/gamechanger/dusty/pulls/294/commits","review_comments_url":"https://api.github.com/repos/gamechanger/dusty/pulls/294/comments","review_comment_url":"https://api.github.com/repos/gamechanger/dusty/pulls/comments{/number}","comments_url":"https://api.github.com/repos/gamechanger/dusty/issues/294/comments","statuses_url":"https://api.github.com/repos/gamechanger/dusty/statuses/31571434e15ea985f2e8541b41bb29afd90ec36c","head":{"label":"gamechanger:ae-specs_docs","ref":"ae-specs_docs","sha":"31571434e15ea985f2e8541b41bb29afd90ec36c","user":{"login":"gamechanger","id":43876,"avatar_url":"https://avatars.githubusercontent.com/u/43876?v=3","gravatar_id":"","url":"https://api.github.com/users/gamechanger","html_url":"https://github.com/gamechanger","followers_url":"https://api.github.com/users/gamechanger/followers","following_url":"https://api.github.com/users/gamechanger/following{/other_user}","gists_url":"https://api.github.com/users/gamechanger/gists{/gist_id}","starred_url":"https://api.github.com/users/gamechanger/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gamechanger/subscriptions","organizations_url":"https://api.github.com/users/gamechanger/orgs","repos_url":"https://api.github.com/users/gamechanger/repos","events_url":"https://api.github.com/users/gamechanger/events{/privacy}","received_events_url":"https://api.github.com/users/gamechanger/received_events","type":"Organization","site_admin":false},"repo":{"id":35429030,"name":"dusty","full_name":"gamechanger/dusty","owner":{"login":"gamechanger","id":43876,"avatar_url":"https://avatars.githubusercontent.com/u/43876?v=3","gravatar_id":"","url":"https://api.github.com/users/gamechanger","html_url":"https://github.com/gamechanger","followers_url":"https://api.github.com/users/gamechanger/followers","following_url":"https://api.github.com/users/gamechanger/following{/other_user}","gists_url":"https://api.github.com/users/gamechanger/gists{/gist_id}","starred_url":"https://api.github.com/users/gamechanger/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gamechanger/subscriptions","organizations_url":"https://api.github.com/users/gamechanger/orgs","repos_url":"https://api.github.com/users/gamechanger/repos","events_url":"https://api.github.com/users/gamechanger/events{/privacy}","received_events_url":"https://api.github.com/users/gamechanger/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/gamechanger/dusty","description":"Docker-powered development environments","fork":false,"url":"https://api.github.com/repos/gamechanger/dusty","forks_url":"https://api.github.com/repos/gamechanger/dusty/forks","keys_url":"https://api.github.com/repos/gamechanger/dusty/keys{/key_id}","collaborators_url":"https://api.github.com/repos/gamechanger/dusty/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/gamechanger/dusty/teams","hooks_url":"https://api.github.com/repos/gamechanger/dusty/hooks","issue_events_url":"https://api.github.com/repos/gamechanger/dusty/issues/events{/number}","events_url":"https://api.github.com/repos/gamechanger/dusty/events","assignees_url":"https://api.github.com/repos/gamechanger/dusty/assignees{/user}","branches_url":"https://api.github.com/repos/gamechanger/dusty/branches{/branch}","tags_url":"https://api.github.com/repos/gamechanger/dusty/tags","blobs_url":"https://api.github.com/repos/gamechanger/dusty/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/gamechanger/dusty/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/gamechanger/dusty/git/refs{/sha}","trees_url":"https://api.github.com/repos/gamechanger/dusty/git/trees{/sha}","statuses_url":"https://api.github.com/repos/gamechanger/dusty/statuses/{sha}","languages_url":"https://api.github.com/repos/gamechanger/dusty/languages","stargazers_url":"https://api.github.com/repos/gamechanger/dusty/stargazers","contributors_url":"https://api.github.com/repos/gamechanger/dusty/contributors","subscribers_url":"https://api.github.com/repos/gamechanger/dusty/subscribers","subscription_url":"https://api.github.com/repos/gamechanger/dusty/subscription","commits_url":"https://api.github.com/repos/gamechanger/dusty/commits{/sha}","git_commits_url":"https://api.github.com/repos/gamechanger/dusty/git/commits{/sha}","comments_url":"https://api.github.com/repos/gamechanger/dusty/comments{/number}","issue_comment_url":"https://api.github.com/repos/gamechanger/dusty/issues/comments{/number}","contents_url":"https://api.github.com/repos/gamechanger/dusty/contents/{+path}","compare_url":"https://api.github.com/repos/gamechanger/dusty/compare/{base}...{head}","merges_url":"https://api.github.com/repos/gamechanger/dusty/merges","archive_url":"https://api.github.com/repos/gamechanger/dusty/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/gamechanger/dusty/downloads","issues_url":"https://api.github.com/repos/gamechanger/dusty/issues{/number}","pulls_url":"https://api.github.com/repos/gamechanger/dusty/pulls{/number}","milestones_url":"https://api.github.com/repos/gamechanger/dusty/milestones{/number}","notifications_url":"https://api.github.com/repos/gamechanger/dusty/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/gamechanger/dusty/labels{/name}","releases_url":"https://api.github.com/repos/gamechanger/dusty/releases{/id}","created_at":"2015-05-11T14:27:56Z","updated_at":"2015-06-23T18:39:54Z","pushed_at":"2015-06-24T17:37:22Z","git_url":"git://github.com/gamechanger/dusty.git","ssh_url":"git@github.com:gamechanger/dusty.git","clone_url":"https://github.com/gamechanger/dusty.git","svn_url":"https://github.com/gamechanger/dusty","homepage":"","size":14792,"stargazers_count":10,"watchers_count":10,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":2,"mirror_url":null,"open_issues_count":3,"forks":2,"open_issues":3,"watchers":10,"default_branch":"master"}},"base":{"label":"gamechanger:master","ref":"master","sha":"c1ddfd1aed0cd98d42382d295ca984614bcc4531","user":{"login":"gamechanger","id":43876,"avatar_url":"https://avatars.githubusercontent.com/u/43876?v=3","gravatar_id":"","url":"https://api.github.com/users/gamechanger","html_url":"https://github.com/gamechanger","followers_url":"https://api.github.com/users/gamechanger/followers","following_url":"https://api.github.com/users/gamechanger/following{/other_user}","gists_url":"https://api.github.com/users/gamechanger/gists{/gist_id}","starred_url":"https://api.github.com/users/gamechanger/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gamechanger/subscriptions","organizations_url":"https://api.github.com/users/gamechanger/orgs","repos_url":"https://api.github.com/users/gamechanger/repos","events_url":"https://api.github.com/users/gamechanger/events{/privacy}","received_events_url":"https://api.github.com/users/gamechanger/received_events","type":"Organization","site_admin":false},"repo":{"id":35429030,"name":"dusty","full_name":"gamechanger/dusty","owner":{"login":"gamechanger","id":43876,"avatar_url":"https://avatars.githubusercontent.com/u/43876?v=3","gravatar_id":"","url":"https://api.github.com/users/gamechanger","html_url":"https://github.com/gamechanger","followers_url":"https://api.github.com/users/gamechanger/followers","following_url":"https://api.github.com/users/gamechanger/following{/other_user}","gists_url":"https://api.github.com/users/gamechanger/gists{/gist_id}","starred_url":"https://api.github.com/users/gamechanger/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gamechanger/subscriptions","organizations_url":"https://api.github.com/users/gamechanger/orgs","repos_url":"https://api.github.com/users/gamechanger/repos","events_url":"https://api.github.com/users/gamechanger/events{/privacy}","received_events_url":"https://api.github.com/users/gamechanger/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/gamechanger/dusty","description":"Docker-powered development environments","fork":false,"url":"https://api.github.com/repos/gamechanger/dusty","forks_url":"https://api.github.com/repos/gamechanger/dusty/forks","keys_url":"https://api.github.com/repos/gamechanger/dusty/keys{/key_id}","collaborators_url":"https://api.github.com/repos/gamechanger/dusty/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/gamechanger/dusty/teams","hooks_url":"https://api.github.com/repos/gamechanger/dusty/hooks","issue_events_url":"https://api.github.com/repos/gamechanger/dusty/issues/events{/number}","events_url":"https://api.github.com/repos/gamechanger/dusty/events","assignees_url":"https://api.github.com/repos/gamechanger/dusty/assignees{/user}","branches_url":"https://api.github.com/repos/gamechanger/dusty/branches{/branch}","tags_url":"https://api.github.com/repos/gamechanger/dusty/tags","blobs_url":"https://api.github.com/repos/gamechanger/dusty/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/gamechanger/dusty/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/gamechanger/dusty/git/refs{/sha}","trees_url":"https://api.github.com/repos/gamechanger/dusty/git/trees{/sha}","statuses_url":"https://api.github.com/repos/gamechanger/dusty/statuses/{sha}","languages_url":"https://api.github.com/repos/gamechanger/dusty/languages","stargazers_url":"https://api.github.com/repos/gamechanger/dusty/stargazers","contributors_url":"https://api.github.com/repos/gamechanger/dusty/contributors","subscribers_url":"https://api.github.com/repos/gamechanger/dusty/subscribers","subscription_url":"https://api.github.com/repos/gamechanger/dusty/subscription","commits_url":"https://api.github.com/repos/gamechanger/dusty/commits{/sha}","git_commits_url":"https://api.github.com/repos/gamechanger/dusty/git/commits{/sha}","comments_url":"https://api.github.com/repos/gamechanger/dusty/comments{/number}","issue_comment_url":"https://api.github.com/repos/gamechanger/dusty/issues/comments{/number}","contents_url":"https://api.github.com/repos/gamechanger/dusty/contents/{+path}","compare_url":"https://api.github.com/repos/gamechanger/dusty/compare/{base}...{head}","merges_url":"https://api.github.com/repos/gamechanger/dusty/merges","archive_url":"https://api.github.com/repos/gamechanger/dusty/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/gamechanger/dusty/downloads","issues_url":"https://api.github.com/repos/gamechanger/dusty/issues{/number}","pulls_url":"https://api.github.com/repos/gamechanger/dusty/pulls{/number}","milestones_url":"https://api.github.com/repos/gamechanger/dusty/milestones{/number}","notifications_url":"https://api.github.com/repos/gamechanger/dusty/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/gamechanger/dusty/labels{/name}","releases_url":"https://api.github.com/repos/gamechanger/dusty/releases{/id}","created_at":"2015-05-11T14:27:56Z","updated_at":"2015-06-23T18:39:54Z","pushed_at":"2015-06-24T17:37:22Z","git_url":"git://github.com/gamechanger/dusty.git","ssh_url":"git@github.com:gamechanger/dusty.git","clone_url":"https://github.com/gamechanger/dusty.git","svn_url":"https://github.com/gamechanger/dusty","homepage":"","size":14792,"stargazers_count":10,"watchers_count":10,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":2,"mirror_url":null,"open_issues_count":3,"forks":2,"open_issues":3,"watchers":10,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/gamechanger/dusty/pulls/294"},"html":{"href":"https://github.com/gamechanger/dusty/pull/294"},"issue":{"href":"https://api.github.com/repos/gamechanger/dusty/issues/294"},"comments":{"href":"https://api.github.com/repos/gamechanger/dusty/issues/294/comments"},"review_comments":{"href":"https://api.github.com/repos/gamechanger/dusty/pulls/294/comments"},"review_comment":{"href":"https://api.github.com/repos/gamechanger/dusty/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/gamechanger/dusty/pulls/294/commits"},"statuses":{"href":"https://api.github.com/repos/gamechanger/dusty/statuses/31571434e15ea985f2e8541b41bb29afd90ec36c"}}}}