# Introduction

[NodeBootstrap](http://www.nodebootstrap.io) is a project skeleton generator tool, which allows you to start a new Node project with a lot of essential batteries included. Some of the features out of the box include:

1. Comfortable dockerized setup, with code hot-reloading out of the box.
2. Well-structured Express.js installation for writing modularized, clean code
3. Advanced setup for automated tests
4. Database Migrations
5. Input validation and error-handling
6. Multi-core support for high-performance node computing

## Installation

Installing NodeBootstrap is very easy. It is distributed as an NPM package so you need Node installed on your machine (we recommend using [nvm](https://github.com/creationix/nvm)). Once you have Node in place, installing Nodebootstrap is as easy as running;

```
npm install -g nodebootstrap
```

Once you have nodebootstrap in place, you can bootstrap several types of code (Dockerized microservice, just a plain-old express webapp or non-dockerized API). The default mode is a Dockerized microservice (which we highly recommend). To install it, you are going to need a working Docker setup on your machine. It is easy to get Docker installed on your computer. Installers for major systems are available at: <https://www.docker.com/community-edition>

Once you have Docker in place, you can bootstrap a new Dockerized microservice by running:

```
nodebootstrap first-microservice
```

and following instructions of the installer.

To see all of the options of nodebootstrap (including: how to change destination folder), please run:

```
nodebootstrap -h
```

Once the installation completes, you will have a functional version of the new project. Installer will output instructions about where to access the project and how to finish building it.


# NodeBootstrap

[NodeBootstrap](http://www.nodebootstrap.io) is a project skeleton generator tool, which allows you to start a new Node project with a lot of essential batteries included. Some of the features out of the box include:

1. Comfortable dockerized setup, with code hot-reloading out of the box.
2. Well-structured Express.js installation for writing modularized, clean code
3. Advanced setup for automated tests
4. Database Migrations
5. Input validation and error-handling
6. Multi-core support for high-performance node computing

## Installation

Installing NodeBootstrap is very easy. It is distributed as an NPM package so you need Node installed on your machine (we recommend using [nvm](https://github.com/creationix/nvm)). Once you have Node in place, installing Nodebootstrap is as easy as running;

```
npm install -g nodebootstrap
```

Once you have nodebootstrap in place, you can bootstrap several types of code (Dockerized microservice, just a plain-old express webapp or non-dockerized API). The default mode is a Dockerized microservice (which we highly recommend). To install it, you are going to need a working Docker setup on your machine. It is easy to get Docker installed on your computer. Installers for major systems are available at: <https://www.docker.com/community-edition>

Once you have Docker in place, you can bootstrap a new Dockerized microservice by running:

```
nodebootstrap first-microservice
```

and following instructions of the installer.

To see all of the options of nodebootstrap (including: how to change destination folder), please run:

```
nodebootstrap -h
```

Once the installation completes, you will have a functional version of the new project. Installer will output instructions about where to access the project and how to finish building it.


# Usage - Microservices Mode

If you created NodeBootstrap project in microservices mode, you can control its lifecycle entirely using make commands.

## Run/Stop container:

```
# run:
> make start
# stop:
> make stop
# clean rebuild:
> make clean
```

## Inspecting health of the containers:

```
> make ps
```

## Monitoring Logs:

```
> make logs
```

## Running Automated Tests

1. Make sure the microservice is up (if not: run `make clean` or `make start`)
2. Run: `make test`

Coverage reports are stored under `coverage` sub-folder.

## Installing a new package

Installing a package:

```
npm run install-package <packagename>
```

Install a package in dev-dependencies:

```
npm run install-dev-package <packagename>
```

## Database Migrations (Currently: MySQL)

```
# Create migration:
> npm run migration-create <migration-name>
# e.g.:
> npm run migration-create create-users-table
# Run migrations:
> make migrate
```


# Code Organization

## Makefile

Contains most of the commands that you use to manage the lifecycle of your application, during development.

## config

Configuration files for various environments, set by $NODE\_ENV environmental variable. default is the baseline that is inherited by all others. Don’t create an explicit environment called default.

Environment variables are able to override configuration of the values in files. It is recommended to use environment variables anywhere but the development environment. See: <https://12factor.net/> for more about it.

## lib

This is where various modules your application consists of go under. Ideally, you should design all your modules as self-contained code that could be cleanly installed and uninstalled to add/remove distinct functionality, without touching other parts of the code. NodeBootstrap goes extra mile to promote self-contained modules. Self contained modules allow higher degree of reuse.

## node\_modules

This is where third-party modules installed via npm go under. Typically you install these using `npm install -S modulename` command.

## public

Dedicates space for static assets (images, js, css). The benefit of this folder is that you can point a web-server (e.g. Nginx or Apache) directly to this folder and not “bother” node on serving these files.

## test

This is where you put your various types of automated tests. Node Bootstrap comes fully configured for Mocha unit and integration tests and even: Casper/Phantom drivers for Mocha to write powerful acceptance tests targeted at web applications. Istanbul coverage reports and batteries are included.

## views

Place to put your shared template files under. Node Bootstrap is, by default, pre-configured for Handlebars templates, but you can use any other Express-friendly templating engine, even: alongside Handlebars, if you want. Typically templates should be encapsulated in their respective modules (which also have views folders, see the sample modules under “lib”), but in case you need to share some templates across various modules: this is where you’d do it.


# Encapsulated Modules

In addition to setting up boilerplate best-practices, central design principle of NodeBootstrap is to compose applications with re-usable, fully encapsulated set of modules.

[TJ Holowaychuk](https://twitter.com/tjholowaychuk) explains this approach in a video screencast: <http://vimeo.com/56166857>

In a more “spaghetti” Node project you may see HTTP route handlers in the main script or application area, tangled together. What TJ argues for and NodeBootstrap implements is: letting each module declare their own handlers, so if you are installing a “user management” or “blog” module, all you need to do is NPM install that module and indicate from the main app where in the URL path the routes get attached.

Feel free to check-out more details about module design per NodeBootstrap in the source code of the [sample module](https://github.com/inadarei/nodebootstrap-microservice/tree/master/lib/homedoc).

For a more advanced example, see: <https://github.com/inadarei/nodebootstrap-microservice/tree/master/lib/users>


# File Limits

Hot reloading uses native file watching features of unix-compatible systems. This is extremely handy and efficient, but unfortunately most systems have very low limits on watched and open files. If you use hot reloading a lot, you should expect to see: `Error: watch EMFILE` or similar.

To solve the problem you need to raise your filesystem limits. This may be a two-step process. On Linux, there’re hard limits (something root user can change in /etc/limits.conf or /ets/security/limits.conf) that govern the limits individual users can alter from command-line.

You should probably put`ulimit -n 10000`in your .profile file, because it does not persist between restarts.

For OS-X and Solaris-specific instructions see [a Stackoverflow Answer](http://stackoverflow.com/questions/34588/how-do-i-change-the-number-of-open-files-limit-in-linux/34645#34645)


# Test Data

One of the most challenging aspects of writing advanced automated tests is providing your tests with reliable test data. Especially if you are writing a database-driven application - you can write tests that check response, but how do you make sure that database had the data that tests expect?

Nodebootstrap uses a database migrations system that can greatly assist here. The basic idea is that we can write migration scripts that insert reliable test data in a database, thus ensuring that our tests run against expected data in all developer environments and in integration (ci/cd) environment. There is a bit of a trick required to make it work, however, which we explain below.

## Environment-Specific Migrations

By default, migrations generated with `make migration-create` run in any environment. If we just use them our test data will be created in all environments including production and some other environments where we may not wan them. So we need to tell our migrations, that create test data, to only run in specific environments.

To do so, in the javascript file for the migration, in both "up" and "down" functions, you need to add a snippet of code that looks like the following:

```javascript
const allowed = ["dev", "qa"];
if (!allowed.includes(db.internals.argv.env)) {
  console.log(`Environment ${db.internals.argv.env} is not ${allowed}. Skipping ${filePath}`);
  return new Promise( function( resolve, reject ) { resolve(""); });
}
```

Which tells db-migrate to skip the migrations for any environment except for "dev" and "cicd" environments.

You normally would want to add this code after the line declaring the `filePath` variable. You may also choose to analyze disallowed environments, rather than allowed ones, in which case the end result will look something like the following:

```javascript
exports.up = function(db) {
  var filePath = path.join(__dirname, 'sqls', '20171120013239-sample-user-data-up.sql');
  const disallowed = ["production", "staging"];
  if (disallowed.includes(db.internals.argv.env)) {
    console.log(`Environment ${db.internals.argv.env} is one of disallowed: ${disallowed}. Skipping ${filePath}`);
    return new Promise( function( resolve, reject ) { resolve(""); });
  }
// ... rest of the up function
}

exports.down = function(db) {
  var filePath = path.join(__dirname, 'sqls', '20171120013239-sample-user-data-down.sql');
  const disallowed = ["production", "staging"];
  if (disallowed.includes(db.internals.argv.env)) {
    console.log(`Environment ${db.internals.argv.env} is one of disallowed: ${disallowed}. Skipping ${filePath}`);
    return new Promise( function( resolve, reject ) { resolve(""); });
  }
// ... rest of the down function
}
```

You can see example environment-specific migration in NodeBootstrap: <https://github.com/inadarei/nodebootstrap-microservice/blob/master/migrations/20170420012051-create-users-table.js#L21> Please note that to execute db-migrate in environment-aware mode, we also had to make following mods to the Makefile:

1. Add [environment-detection](https://github.com/inadarei/nodebootstrap-microservice/blob/master/Makefile#L5) at the top of the Makefile
2. Execute db-migration in [environment-specific mode](https://github.com/inadarei/nodebootstrap-microservice/blob/master/Makefile#L51), in the `db migrate` target.

We have also submitted a ticket to db-migrate authors, proposing a solution that makes environment-specific migrations tad bit less tedious: <https://github.com/db-migrate/node-db-migrate/issues/536>

Feel free to visit db-migrate's issue queue to vote on the proposal, or help with the code, if you would like to see the solution implemented, but even meanwhile: using environment-specific migrations is a very effective way of writing complex, reliable automated tests.

We hope you enjoy this feature of Nodebootstrap/db-migrate and that it helps you build more reliable software.


