• Stars
    star
    1,345
  • Rank 33,838 (Top 0.7 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 11 years ago
  • Updated over 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Git push deploy for Node.js

POD - git push deploy for Node.js

screenshot

NPM version Build Status

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.

A Quick Taste

On the server:

$ pod create myapp

On 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 push

You 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 master

That'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.

Prerequisites

  • Node >= 0.10.x
  • git
  • properly set up ssh so you can push to a repo on the VPS via ssh

Installation

$ [sudo] npm install -g pod

To 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 <username> /path/to/node /path/to/pod startall

The 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

CLI Usage


  Usage: pod [command]

  Commands:

    create <app>            Create a new app
    remote <app> <repo>     Create a app from a remote GitHub repo
    rm <app>                Delete an app
    start <app>             Start an app monitored by pm2
    stop <app>              Stop an app
    restart <app>           Restart an app that's already running
    list                    List apps and status
    startall                Start all apps not already running
    stopall                 Stop all apps
    restartall              Restart all running apps
    prune                   Clean up dead files
    hooks                   Update hooks after a pod upgrade
    web [command]           Start/stop/restart the web interface
    help                    You are reading it right now

Web Service

$ 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.

Using a remote GitHub repo

Walkthrough

You can setup an app to track a remote GitHub repo by using the pod remote command:

$ pod remote my-remote-app username/repo

After 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.

Configuration

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:

{
    // where pod puts all the stuff
    "root": "/srv",

    // default env
    "node_env": "development",

    // this can be overwritten in each app's package.json's "main" field
    // or in the app's configuration below using the "script" field
    "default_script": "app.js",

    // minimum uptime to be considered stable,
    // in milliseconds. If not set, all restarts
    // are considered unstable.
    "min_uptime": 3600000,

    // max times of unstable restarts allowed
    // before the app is auto stopped.
    "max_restarts": 10

    // config for the web interface
    "web": {
        // set these! default is admin/admin
        "username": "admin",
        "password": "admin",
        "port": 19999,
        // allow jsonp for web interface, defaults to false
        "jsonp": true
    },

    "apps": {
        "example1": {

            // passed to the app as process.env.NODE_ENV
            // if not set, will inherit from global settings
            "node_env": "production",

            // passed to the app as process.env.PORT
            // if not set, pod will try to parse from app's
            // main file (for displaying only), but not
            // guarunteed to be correct.
            "port": 8080,

            // pod will look for this script before checking
            // in package.json of the app.
            "script": "dist/server.js",

            // *** any valid pm2 config here gets passed to pm2. ***

            // spin up 2 instances using cluster module
            "instances": 2,

            // pass in additional command line args to the app
            "args": "['--toto=heya coco', '-d', '1']",

            // file paths for stdout, stderr logs and pid.
            // will be in ~/.pm2/ if not specified
            "error_file": "/absolute/path/to/stderr.log",
            "out_file": "/absolute/path/to/stdout.log"
        },
        "example2": {
            // you can override global settings
            "min_uptime": 1000,
            "max_restarts": 200
        },
        "my-remote-app": {
            "remote": "yyx990803/my-remote-app", // github shorthand
            "branch": "test" // if not specified, defaults to master
        }
    },

    // pass environment variables to all apps
    "env": {
        "SERVER_NAME": "Commodore",
        "CERT_DIR": "/path/to/certs"
    }
}

Using PM2 Directly

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.

Custom Post-receive Hook

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 here

You 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.

Using the API

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.

Docker images

Ready to go docker images:

Changelog

0.9.1

  • Move to latest pm2
  • Added support for Node 7.x

0.9.0

  • Support env option in .podrc which passes environment variables to all apps managed by pod.
  • Fixed GitHub ping event error when using remote GitHub repo.

0.8.6

  • Added support for Bitbucket webhooks.
  • Added ability to specify entry point in app's config in .podrc by using the script field.
  • Fixed issue with the readline module blocking stdin. This caused issues when attempting to clone a repository that required a username/password.

0.8.0

  • Upgrade pm2 to 0.12.9, which should make pod now work properly with Node 0.11/0.12 and latest stable iojs.
  • Fix web services to accommodate github webhook format change (#29)
  • Now links the pm2 executable automatically when installed

0.7.4

  • Fix web service strip() function so it processes github ssh urls correctly. (Thanks to @mathisonian)
  • Behavior regarding main field in package.json is now more npm compliant. (e.g. it now allows omitting file extensions)

0.7.3

  • Add a bit more information for first time use
  • Renamed the web service process name to pod-web-service from pod-web-interface.
  • Fixed web service not refreshing config on each request

0.7.2

  • Add styling for the web interface.

0.7.1

  • Now pod automatically converts outdated config files to 0.7.0 compatible format.

0.7.0

  • Config file now conforms to underscore-style naming: nodeEnv is now node_env, and defaultScript is now default_script. Consult the configuration section for more details.
  • Added pod web and pod remote commands. See web interface and using a remote github repo for more details.
  • Removed pod config and pod edit.
  • Drop support for Node v0.8.

0.6.0

  • The post receive hook now uses 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.
  • Added 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.
  • Upgraded to pm2 0.6.7

License

MIT

More Repositories

1

build-your-own-mint

Build your own personal finance analytics using Plaid, Google Sheets and CircleCI.
HTML
2,456
star
2

vue-hooks

Experimental React hooks implementation in Vue
JavaScript
1,592
star
3

zoomerang

drop in zoom anything
JavaScript
1,221
star
4

vue-lit

Proof of concept custom elements "framework"
JavaScript
1,105
star
5

HTML5-Clear-v2

HTML5 Clear version 2
JavaScript
948
star
6

vite-vs-next-turbo-hmr

Benchmarking Vite vs. Next + turbopack HMR performance
JavaScript
919
star
7

laravel-vue-cli-3

Example project using Vue CLI 3 with Laravel
PHP
850
star
8

HTML5-Clear

[DEPRECATED] A replica of the Clear iphone app in HTML5
JavaScript
719
star
9

register-service-worker

A script to simplify service worker registration with hooks for common events.
JavaScript
635
star
10

vue-wordle

Wordle built with Vue, aka VVordle
TypeScript
573
star
11

launch-editor

Open file in editor from Node.js.
JavaScript
531
star
12

semi

To semicolon or not to semicolon; that is the question
JavaScript
304
star
13

vue-svelte-size-analysis

Comparing generated code size of Vue and Svelte components
JavaScript
300
star
14

okie

Dead simple worker threads pool
TypeScript
257
star
15

starz

Count a GitHub user's total stars
JavaScript
145
star
16

circular-json-es6

circular JSON.stringify and JSON.parse, for environments with native ES6 Map
JavaScript
128
star
17

pug-plain-loader

webpack loader that transforms pug templates to plain HTML
JavaScript
114
star
18

release-tag

GitHub action for auto creating a release on tag push
JavaScript
107
star
19

Speech.js

Simple wrapper for Chrome's web speech recognition API
JavaScript
97
star
20

retweeter

Auto retweet from another account using CircleCI scheduled workflows
JavaScript
59
star
21

matrix.js

Featherweight CSS3 3D engine
JavaScript
58
star
22

buble

a fork of buble with some vue-specific hacks, used in vue-template-es2015-compiler
JavaScript
54
star
23

nightwatch-helpers

custom assertions and commands for easier nightwatch tests
JavaScript
53
star
24

shell-task

Proof-of-concept then-able shell commands in node.
JavaScript
46
star
25

creative-html5

A class about JavaScript, html5 and creative coding.
JavaScript
46
star
26

vue-template-explorer

See how vue templates get compiled into render functions under the hood
Vue
44
star
27

QR.js

Simple HTML5 Canvas-based QR Code generation
JavaScript
42
star
28

vue-tsc-3.3-type-repro

Vue
37
star
29

material-color-scheme-es6

Material Theme color scheme tweaked for ES6
JavaScript
32
star
30

semi-sublime

Sublime Text 3 plugin for Semi
Python
32
star
31

vite-pre-transform-test

JavaScript
29
star
32

speech

component for Chrome speech recognition wrapper
JavaScript
29
star
33

raveal

Radially reveal an element
JavaScript
27
star
34

webpack-hmr-repro

JavaScript
27
star
35

cjs-module-lexer-rollup-reexports

JavaScript
25
star
36

roetem

meteor-like experiment with vue and rethinkdb
JavaScript
24
star
37

gulp-component

component plugin for gulp
JavaScript
22
star
38

tucao

吐槽专用
21
star
39

thread-loader-bug

JavaScript
20
star
40

browser-audio

Simple cross browser audio player
JavaScript
19
star
41

rollup-tostringtag-symbol-conflict

JavaScript
19
star
42

resolve-type-test

TypeScript
19
star
43

babel-preset-flow-vue

JavaScript
17
star
44

popSlides

javascript popup slideshow plugin based on jQuery
JavaScript
17
star
45

esbuild-exports-signature-repro

JavaScript
16
star
46

vue

vue bug
HTML
14
star
47

Puzzle-Demo

A slider puzzle game with CSS3 transitions.
JavaScript
14
star
48

rollup-commonjs-bug

JavaScript
14
star
49

capper

Capture canvas animations.
JavaScript
12
star
50

Socket-Play

iPhone-controlled HTML5 game concept demo
JavaScript
12
star
51

Kinect-Keylight

Kinect version of @hakimel 's Keylight
C++
11
star
52

showme

show me the code (for an npm package)
JavaScript
11
star
53

workerify

Component for easy inline web worker
JavaScript
10
star
54

de-indent

remove extra indent from a block of code
JavaScript
10
star
55

new

Scaffold a new project.
JavaScript
8
star
56

Telekinesis

User gesture input simulation.
JavaScript
8
star
57

whipcream

Chai-style chaining sugar for webdriverjs
JavaScript
8
star
58

babel-plugin-transform-es2015-classes-simple

JavaScript
7
star
59

emitter-fsm

EventEmitter based finite state machine
JavaScript
6
star
60

templates

Personal project scaffolding templates
JavaScript
5
star
61

choreo.js

Event-based flow control for interactive walkthroughs
JavaScript
4
star
62

gulp-jscoverage

JSCoverage instrumentation plugin for gulp
JavaScript
4
star
63

fancytext

Text with fancy transitions
JavaScript
4
star
64

gruntfile-yaml

write grunt config in yaml.
JavaScript
4
star
65

roller

One-dimensional touch scroller with momentum and elastic pagination
JavaScript
4
star
66

test-cli-preset

JavaScript
3
star
67

generator-extension

A Chrome extension generator
JavaScript
3
star
68

generator-dude

A personal Yeoman generator
JavaScript
3
star
69

blaze-local-state

Local reactive state for Blaze templates
JavaScript
3
star
70

tester

webhook tests.
JavaScript
2
star
71

gulp-component-updater

Gulp-friendly module to auto add/delete files in your component.json
JavaScript
2
star
72

grunt-component-add

Automatically add files to component.json
JavaScript
1
star