{"id":15290222,"url":"https://github.com/npm/ndm","last_synced_at":"2025-10-07T03:32:14.703Z","repository":{"id":57309506,"uuid":"20572990","full_name":"npm/ndm","owner":"npm","description":"ndm allows you to deploy OS-specific service-wrappers directly from npm-packages.","archived":true,"fork":false,"pushed_at":"2020-11-23T10:18:01.000Z","size":325,"stargazers_count":183,"open_issues_count":26,"forks_count":22,"subscribers_count":27,"default_branch":"master","last_synced_at":"2025-01-11T08:51:52.677Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/npm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-06-06T17:59:30.000Z","updated_at":"2024-12-16T05:22:57.000Z","dependencies_parsed_at":"2022-08-27T04:11:53.963Z","dependency_job_id":null,"html_url":"https://github.com/npm/ndm","commit_stats":null,"previous_names":[],"tags_count":66,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/npm%2Fndm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/npm%2Fndm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/npm%2Fndm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/npm%2Fndm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/npm","download_url":"https://codeload.github.com/npm/ndm/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235586048,"owners_count":19014028,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-09-30T16:06:27.254Z","updated_at":"2025-10-07T03:32:09.427Z","avatar_url":"https://github.com/npm.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ndm\n\n[![Build Status](https://travis-ci.org/npm/ndm.png)](https://travis-ci.org/npm/ndm)\n\nndm makes it easy to deploy a complex service-oriented-architecture by allowing you to deploy OS-specific service-wrappers directly from an npm package.\n\nndm currently supports Centos, OS X, and Ubuntu.\n\n**Table of Contents:**\n\n* [Installation](#install)\n* [What's service.json?](#servicejson)\n* [Getting Information From Your User](#interview)\n* [ndm API (create self-installing packages)](#api)\n\n## Installing \u003ca name=\"install\"\u003e\u003c/a\u003e\n\n* `npm install ndm -g`\n\nYou might need to run that as root with `sudo`.\n\n## Quick Start\n\nHow to build an ndm-ready package:\n\n1. Install ndm: `sudo npm install ndm -g`\n2. Create a project directory with a _package.json_: `npm init`\n3. Add service dependencies to your _package.json_: `npm install my-service-module --save`\n4. Generate your service.json: `ndm init`.\n5. Edit _service.json_ to add appropriate `args` and `envs` for your server.\n6. When you're ready, generate service wrappers (upstart, initctl, etc): `ndm install`.\n7. Start the service wrappers you've just generated: `ndm start`.\n\n## Anatomy of an ndm service\n\nndm can run a single services or a collection of services. It's structured like an npm package, with a **package.json** file listing its dependencies. Each service you want to run with ndm should be packaged as its own separate npm module that the ndm wrapper depends on. Then a **service.json** file describes how to run each service.\n\nAn ndm wrapper package looks like this:\n\n    wrapper/\n      package.json\n      service.json\n      logs/\n      node_modules/\n\n### Service dependencies\n\nA node-packaged service built for ndm can provide some hints in its package.json about how to run itself. Here's an example ndm-ready **package.json**:\n\n```json\n{\n  \"name\": \"be-awesome\",\n  \"version\": \"0.0.0\",\n  \"description\": \"a service designed to be run with ndm.\",\n  \"main\": \"index.js\",\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"dependencies\": {\n    \"ssh2\": \"^0.2.25\"\n  },\n  \"devDependencies\": {\n    \"mocha\": \"^1.20.0\"\n  },\n  \"script\": {\n    \"start\": \"node ./bin/awesome.js\"\n  },\n  \"service\": {\n    \"args\": {\n      \"--verbose\": \"false\"\n    },\n    \"env\": {\n      \"PORT\": \"5000\"\n    }\n  },\n}\n```\n\nNote the `environment` field and its subfields. `environment.args` is a map of arguments that should be passed to the ndm service. `ndm.env` is a map of environment variables that should be passed to your ndm service.\n\n### The `service.json` file \u003ca name=\"servicejson\"\u003e\u003c/a\u003e\n\nThe ndm wrapper must also have a **service.json** file, which describes how to run the services. Run `ndm init` to generate _service.json_ from your installed npm dependencies. The init script will copy default values from the `environment` stanza in each service's **package.json**. You can then edit the defaults if you need to change anything.\n\nHere's an example:\n\n```json\n{\n  \"baby-animals\": {\n    \"description\": \"baby animal thumbnailing service\",\n    \"scripts\": {\n      \"start\": \"./baby-animal.js\"\n    },\n    \"env\": {\n      \"PORT\": \"8000\",\n      \"USER\": \"bcoe\"\n    },\n    \"args\": {\n      \"--kitten\": \"cute\"\n    }\n  },\n  \"ndm-test2\": {\n    \"description\": \"the awesome service\",\n    \"processes\": 3,\n    \"module\": \"be-awesome\",\n    \"scripts\": {\n      \"start\": \"./bin/foo.js\"\n    },\n    \"env\": {\n      \"PORT\": \"5000\"\n    },\n    \"args\": {\n      \"--verbose\": \"false\"\n    }\n  },\n  \"env\": {\n    \"APP\": \"my-test-app-%i\",\n    \"NODE_ENV\": \"production\"\n  },\n  \"args\": {\n    \"--batman\": \"greatest-detective\"\n  }\n}\n```\n\n* **module:** the name of the npm module that should be the working directory for the service. If no module is specified, the key of the service will be used as the module name to look for.\n* **description:** description of the service.\n* **scripts:** scripts that can be executed by ndm. When generating service wrappers the `start` script is used.\n* **env:** string environment variables available within the script executed by the ndm wrapper.\n* **args:** command-line-arguments available to the script executed by the ndm wrapper.\n* **processes:** how many copies of the service should be run.\n  * useful for taking advantage of multiple cpus, defaults to 1 process.\n* **`%i`:** `%i` is a place-holder for the process # if you're running multiple processes.\n  * this can be useful if you want each process to bind to a different port, e.g., `800%i`.\n\nDefaults for all services are in the top-level `env` and `args` fields. Each services can override and extend the defaults in its own options stanza.\n\n### Updating dependencies\n\nTo add new dependencies:\n\n* Add a new dependency to the wrapper's **package.json** the way you would for any npm package:\u003cbr\u003e `npm install \u003cnew-service\u003e --save`\n* Add the new service to **service.json**:\u003cbr\u003e`ndm update`.\n\n## Installing the services\n\nTo install your ndm-wrapped services, copy the package directory to your host system using whatever means you prefer. Then from inside the directory, run `ndm install`.\n\nOn systems like Ubuntu, you'll need to run this as root so ndm has permission to add the upstart config file to `/etc/init`. On OS X, you can run it as any user to create a local launch control script.\n\nCommand line arguments can be passed to the service wrapper at generation time, by appending them after `--`:\n\n```bash\nndm install -- --verbose true\n```\n\n## Starting and stopping\n\nYou can start and stop the services manually using your host's native daemon control: `upstart`, `launchctl`, or `initctl`. Or you can use `ndm start` and `ndm stop` from inside an ndm wrapper directory to start \u0026 stop all the wrapped services.\n\n## Tailing Logs\n\nAll console.log and console.error output is recorded in the `logs/` directory, in files named `\u003cservice-name\u003e.log`. This is separate from whatever internally-managed logging the service might do.\n\n## Interviewing the User \u003ca name=\"interview\"\u003e\u003c/a\u003e\n\nRather than providing set-in-stone default values, you can opt to interview your user. To interview a user for important variables, write your default values in this form:\n\n```json\n\"env\": {\n  \"HOST\": {\n    \"default\": \"localhost\",\n    \"description\": \"what host should I bind to?\"\n  }\n}\n```\n\nBy running `ndm interview`, a user will then be asked to fill in these values in an interactive manner:\n\n```bash\nBenjamins-MacBook-Air:ndm benjamincoe$ node ./bin/ndm.js interview\nstarting interview:\n[?] url of front facing server: www.example.com\n[?] what environment should we run the app in: test\n[?] what do you think of dogs? I like 'em.\n```\n\n## .ndmrc\n\nAdd an `.ndmrc` file to your home directory, to override ndm's default settings.\n\nVariable names should be camel-case. As an example, the following `.ndmrc` would change the default logging location:\n\n```ini\n; override ndm CLI variables by adding\n; them to a .ndmrc file. Variables should be\n; cammel case.\nlogsDirectory=/foo/bar/logs\n```\n\n## The ndm API \u003ca name=\"api\"\u003e\u003c/a\u003e\n\nRather than using the ndm bin to manage services, you can use the ndm API to create a self-installable service:\n\n1. add ndm to your package.json dependencies.\n2. add a service.json to the root of your module with a scripts stanza which includes:\n  * a `start` script, which is what ndm will run by default.\n  * any other scripts that you'd like to expose via `runScript`.\n\n**service.json example:**\n\n```json\n{\n  \"ndm-test\": {\n    \"description\": \"ndm test service\",\n    \"scripts\": {\n      \"start\": \"node ./test.js\",\n      \"echo\": \"echo hello\",\n      \"node-echo\": \"node ./test2.js\"\n    },\n    \"env\": {\n      \"PORT\": 8000,\n      \"USER\": {\n        \"description\": \"enter a username.\"\n      }\n    }\n  }\n}\n```\n\n3. update your package's bin to look something like this (the argument passed to ndm's require is the name of the module in the sevice.json that you'd like to run):\n\n```\n#!/usr/bin/env node\n\nvar argv = require('yargs').argv,\n  ndm = require('ndm')('ndm-test');\n\nswitch(argv._[0]) {\n  case 'install':\n    ndm.install();\n    break;\n  case 'remove':\n    ndm.remove();\n    break;\n  case 'start':\n    ndm.start();\n    break;\n  case 'restart':\n    ndm.restart();\n    break;\n  case 'stop':\n    ndm.stop();\n    break;\n  case 'list-scripts':\n    ndm.listScripts();\n    break;\n  case 'run-script':\n    ndm.runScript();\n    break;\n}\n```\n\nndm-test is published to npm, try it out:\n\n```bash\nnpm install ndm-test -g\nndm-test install\nndm-test start\n```\n\n## Setting Node Flags\n\nFor each service in your service.json file, you can optionally set the following flags.\n\n* `maxOldSpaceSize`: sets the `--max-old-space-size` flag to to `N` megabytes.\n\n```json\n{\n  \"foo\": {\n    \"maxOldSpaceSize\": \"4096\"\n  }\n}\n```\n\n## Disclaimer\n\nndm is an experiment, based on ops challenges we've been facing at npm. This is a dot release. I'll be moving things around a lot in this library, as we use it for our own deployments.\n\nThe `ndm` stanza is not officially supported by npm.\n\n## LICENSE\n\nISC\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnpm%2Fndm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnpm%2Fndm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnpm%2Fndm/lists"}