Git push deploy for Node.js
Core API JSCoverage: 95.52%
Pod simplifies the workflow of setting up, updating and managing multiple Node.js apps on a Linux server. Perfect for hosting personal Node stuff on a VPS. There are essentially two parts: 1. git push deploy (by using git hooks) and 2. process management (by using pm2)
It doesn't manage DNS routing for you (personally I'm doing that in Nginx) but you can use pod to run a node-http-proxy server on port 80 that routes incoming requests to other apps.
On the server:
$ pod create myappOn your local machine:
$ git clone ssh://your-server/pod_dir/repos/myapp.git
# hack hack hack, commit
# make sure your main file is app.js
# or specify "main" in package.json
$ git pushYou can also just add it as a remote to an existing local repo:
$ git remote add deploy ssh://your-server/pod_dir/myapp.git
$ git push deploy masterThat's it! App should be automatically running after the push. For later pushes, app process will be restarted. There's more to it though, read on to find out more.
$ [sudo] npm install -g podTo make pod auto start all managed apps on system startup, you might also want to write a simple upstart script that contains something like this:
# /etc/init/pod.conf
start on (local-filesystems and net-device-up IFACE!=lo)
exec sudo -u /path/to/node /path/to/pod startallThe first time you run pod it will ask you where you want to put your stuff. The structure of the given directory will look like this:
.
├── repos # holds the bare .git repos
│ └── example.git
└── apps # holds the working copies
└── example
├──app.js
└──.podhook…$ pod web [stop|restart|status]This command will start the pod web service, by default at port 19999, which provides several functionalities:
/ : a web interface that displays current apps status./json : returns app status data in json format./jsonp : accepts jsonp. This route must be enabled in config./hooks/appname : trigger fetch/restart for corresponding remote apps.Both / and /json require a basic http authentication. Make sure to set the username and password in the config file.
You can setup an app to track a remote GitHub repo by using the pod remote command:
$ pod remote my-remote-app username/repoAfter this, add a webhook to your GitHub repo pointing at your web interface's /hooks/my-remote-app. The webhook will trigger a fetch and restart just like local apps. By default a remote app will be tracking the master branch only, if you want to track a different branch, you can change it in the config file.
You can also set up a remote app to track an arbitrary git address. However in that case you need to manually make a POST request conforming to the GitHub webhook payload.
Starting in 0.8.2, GitLab webhooks are also supported.
Starting in 0.8.6, Bitbucket webhooks are also supported.
The config file lives at ~/.podrc. Note since 0.7.0 all fields follow the underscore format so check your config file if things break after upgrading.
Example Config:
…Pod relies on pm2 for process management under the hood. When installing pod, the pm2 executable will also be linked globally. You can invoke pm2 commands for more detailed process information.
Logging is delegated to pm2. If you didn't set an app's out_file and error_file options, logs will default to be saved at ~/.pm2/logs.
If things go wrong and restarting is not fixing them, try pm2 kill. It terminates all pm2-managed processes and resets potential env variable problems.
All pod commands only concerns apps present in pod's config file, so it's fine if you use pm2 separately to run additional processes.
By default pod will run npm install for you everytime you push to the repo. To override this behavior and run custom shell script before restarting the app, just include a .podhook file in your app. If .podhook exits with code other than 0, the app will not be restarted and will hard reset to the commit before the push.
Example .podhook:
component install
npm install
grunt build
grunt test
passed=$?
if [[ $passed != 0 ]]; then
# test failed, exit. app's working tree on the server will be reset.
exit $passed
fi
# restart is automatic so no need to include that hereYou can also directly edit the post-receive script of an app found in pod-root-dir/repos/my-app.git/hooks/post-receive if you wish.
NOTE: the API can only be used after you've initiated the config file via command line.
require('pod') will return the API. You have to wait till it's ready to do anything with it:
var pod = require('pod')
pod.once('ready', function () {
// ... do stuff
})The API methods follow a conventional error-first callback style. Refer to the source for more details.
Ready to go docker images:
env option in .podrc which passes environment variables to all apps managed by pod..podrc by using the script field.readline module blocking stdin. This caused issues when attempting to clone a repository that required a username/password.strip() function so it processes github ssh urls correctly. (Thanks to @mathisonian)main field in package.json is now more npm compliant. (e.g. it now allows omitting file extensions)pod-web-service from pod-web-interface.nodeEnv is now node_env, and defaultScript is now default_script. Consult the configuration section for more details.pod web and pod remote commands. See web interface and using a remote github repo for more details.pod config and pod edit.git fetch --all + git reset --hard origin/master instead of a pull. This allows users to do forced pushes that isn't necesarrily ahead of the working copy.pod prune and pod hooks commands. Make sure to run pod hooks after upgrading pod, as you will want to update the hooks that are already created in your existing apps.No open issues yet, or sync has not completed.