nido
v2.7.9
Published
Nido: =====
Keywords
Readme
Nido:
Nido is a software deployment tool used and maintained by Newicon.net enabling zero downtime deployment.
Install
sudo npm install nido -gSimilar to capistrano based deployment:
- Looks in the current directory for the git repository.
- Uses the repository as a key to lookup project specific details.
- Communicates with the central deployment server (the hub) to lookup server details
- Runs the deployment tasks
On The server
Deployment will create the following directory structure on the target server:
/your/project/path
|--releases
| |--20150513120631
|--shared
| |--repo
| |--...
|--current -> /your/project/path/releases/20150513120631The current directory is a symlink to the latest release.
Every deployment will create a new directory in releases. When the deployment has finished a symlink called current will be pointed to the new release. By default nido keeps the last 5 releases.
If something went wrong during the deployment process, or something is wrong with your new release, simply run the following command to roll back to the previous working release:
nido rollback productionGet started
In your project, to be deployable via nido, you need to create a nido.js file
The contents of this file should look something like this:
module.exports = function(nido, env){
nido = nido('neon'); // load the recipe - available recipes are in the recipes folder of nido project
nido.set('environments', {
// local development environment
local: {
env:'dev',
debug:true,
domain:'mysite.com',
deployPath: '~/Sites/mysite.com',
db: {
database: 'mysite_dev',
username: 'root',
password: 'root'
},
gitBranch: "develop",
siteName: "My Site",
},
// test server
test: {
env:'test',
debug:true,
domain:'mysite.test.newicon.net',
server: 'test.default.newicon.uk0.bigv.io',
db: {
database: 'mysite_test',
username: 'mysite_test',
password: 'mysitepassword'
},
gitBranch: "staging",
siteName: 'My Site Test',
},
// staging server
staging: {
env: 'prod',
debug: false,
domain:'staging.mysite.com',
server: 'mysite.wpress.newicon.uk0.bigv.io',
db: {
database: 'mysite_stage',
username: 'mysite_stage',
password: 'mysitestagepass'
},
gitBranch: "staging",
siteName: 'My Site Staging',
},
// production server
production: {
env: 'prod',
debug: false,
domain:'mysite.com',
server: 'mysite.wpress.newicon.uk0.bigv.io',
db: {
database: 'mysite_production',
username: 'mysite_prod',
password: 'QWEFqwe13123erfWERF!£'
},
gitBranch: "master",
siteName: 'My Site',
},
});
// add an additional public/movies directory
nido.set('sharedDirs', ['var', 'public/assets', 'public/movies']);
return nido;
}Exclude tables
- New feature in version >=2.2.2. Backward-compatible with previous versions as the steps simply fall through if the config lines are not specified in
nido.js. - In the project-specific nido.js, add these lines. The
globalExcludedTablesvar will be excluded in all pull/push operations. - Under each environment, there are additional
excludePullandexcludePushfields which are arrays to exclude from the respective pull from and push to environment. - For example, globally, we would like to exclude the damn Wordfence tables from all database pull/push operations.
- Put the tables to exclude under the target's
excludePullandexcludePushrespectively. Similarly for tables to include. - Examples of use cases:
- Pull production database (exclude Wordfence). Wordfence tables are already defined globally. Put anything else to exclude under production's
excludePullarray. - Push to staging. We want to include Gravity Forms tables so that we can debug and see the form submissions. Put anything to exclude under staging's
excludePusharray. - Push to production (exclude Gravity Forms tables). We don't push Gravity Forms tables as we don't want to overwrite any existing entries. Put the Gravity Forms tables into production's
excludePusharray.
- Pull production database (exclude Wordfence). Wordfence tables are already defined globally. Put anything else to exclude under production's
wp.set('globalExcludedTables', ['wp_wfBadLeechers', 'wp_wfBlockedIPLog', 'wp_wfBlocks', 'wp_wfBlocksAdv', 'wp_wfConfig', 'wp_wfCrawlers', 'wp_wfFileMods', 'wp_wfHits', 'wp_wfHoover', 'wp_wfissues', 'wp_wfLeechers', 'wp_wfLockedOut', 'wp_wfLocs', 'wp_wfLogins', 'wp_wfNet404s', 'wp_wfReverseCache', 'wp_wfScanners', 'wp_wfStatus', 'wp_wfThrottleLog', 'wp_wfVulnScanners']);
test: {
...
db: {
database: <test database>,
excludePull: ['wp_wf*'],
includePull: ['wp_wfConfig'],
excludePush: ['wp_wf*', 'wp_rg_*'],
includePush: ['wp_rg_*', 'wp_wfConfig'],
},
staging: {
...
db: {
database: <test database>,
excludePull: ['wp_wf*'],
includePull: ['wp_wfConfig'],
excludePush: ['wp_wf*', 'wp_rg_*'],
includePush: ['wp_rg_*', 'wp_wfConfig'],
},
production: {
...
db: {
database: <production database>,
excludePull: ['wp_wf*'],
includePull: ['wp_wfConfig'],
excludePush: ['wp_wf*', 'wp_rg_*'],
includePush: [],
},
- Wildcards (
*) are supported in the table names. First Nido queries the list of tables in the remote database. Then, the wildcards are expanded by selecting the remote database's matching table names. - How it works:
- The global exclude will be combined with the local excludePull (a union preserving only unique entries).
- The local includePull is the super-override. (combinedExcludeList - includePull). E.g. in test,
excludePush: ['wp_wf*', 'wp_rg_*'], includePush: ['wp_rg_*', 'wp_wfConfig'].wp_rg_*will be removed from the exclude list andwp_wfConfigwill also be removed but the remainingwp_wf*tables will remain excluded.
- Tables that are excluded from mysqldump won't have
DROP table. Therefore, it is SAFE to push to production.
Local Database Anonymisation
- New feature in version >=2.5.0. Backward-compatible with previous versions as it's a new optional feature which does not alter the current feature-set in any way.
- Uses faker.js to replace fields in the local (only) database in order to anonymise sensitive data (for example customer names, emails, and addresses).
- Attempting to use in any environment other than local will fail.
- In your project you should create a json file will be used to specify which fields to anonymise and how, in this case lets call it 'anonymise-db.json'. Here is a simple example entry:
[
{
"table": "customers",
"primary_key": "customer_id",
"field": "email",
"faker_action": "{{internet.email}}",
"faker_unique": true
},
{
"table": "addresses",
"primary_key": "address_id",
"fields": [
{
"field": "address",
"faker_action": "{{address.streetAddress}} {{address.streetName}}"
},
{
"field": "city",
"faker_action": "{{address.city}}"
}
]
}
]- Available options are:
table - specifies the table in which to anonymise
field - specifies the field in which the replacement will occur
fields - [optionally use instead of field] specify multiple fields to update on this table at once
faker_action - using faker's moustache string format
faker_unique - [optional] ensures that each entry is unique (useful if a field has a unique constraint)
select_where - [optional] adds a sql where clause when initially obtaining the primary_keys used to perform the replacement
description - [optional] adds a description (which only used in the nido output) The documentation for faker's moustache string format can be found here.
- Next in your nido.js under the local environment definition we need to point to the json file using the 'anonymise' key:
...
local: {
...
anonymise : 'anonymise-db.json'
}
...- You can now run
$nido anonymisedb local - WARNING : Make a backup of your database before using this feature, particularly while you are creating and testing your json definition file!
- BIGGER WARNING : !! Be very very very careful not to push this anonymised data to your live server !!
Troubleshooting:
- If you define too many fields in a grouped field definition and the table is InnoDB then it's possible for Deadlock condition to occur, if this happens split half the fields into a new json section of it's own for the same table.
Notes:
- Useful for implementing a GDPR or privacy policy.
- Currently the locale is hardcoded as 'en_GB', which is specified at the top of /lib/anonymiser.js, if you wish to change this consult the faker.js documentation.
- Currently there is no consistency between records, for example if you replace customers' forenames, surnames & emails the emails will not match the name.
