Gathering detailed insights and metrics for ssh-deploy-release
Gathering detailed insights and metrics for ssh-deploy-release
Gathering detailed insights and metrics for ssh-deploy-release
Gathering detailed insights and metrics for ssh-deploy-release
npm install ssh-deploy-release
Typescript
Module System
Node Version
NPM Version
64.6
Supply Chain
93.9
Quality
72.3
Maintenance
100
Vulnerability
95.8
License
JavaScript (99.99%)
HTML (0.01%)
Total Downloads
109,242
Last Day
103
Last Week
321
Last Month
1,907
Last Year
19,780
36 Stars
95 Commits
10 Forks
7 Watching
5 Branches
8 Contributors
Minified
Minified + Gzipped
Latest Version
4.0.1
Package Id
ssh-deploy-release@4.0.1
Unpacked Size
54.21 kB
Size
14.33 kB
File Count
11
NPM Version
8.9.0
Node Version
18.2.0
Cumulative downloads
Total Downloads
Last day
33.8%
103
Compared to previous day
Last week
-40.9%
321
Compared to previous week
Last month
9.9%
1,907
Compared to previous month
Last year
20.2%
19,780
Compared to previous year
Deploy releases over SSH with rsync, archive ZIP / TAR, symlinks, SCP ...
Example :
/deployPath
|
├── www --> symlink to ./releases/<currentRelease>
|
├── releases
| ├── 2017-02-08-17-14-21-867-UTC
| ├── ...
| └── 2017-02-09-18-01-10-765-UTC
| ├── ...
| └── logs --> symlink to shared/logs
|
├── synchronized --> folder synchronized with rsync
|
└── shared
└── logs
npm install ssh-deploy-release
1const Application = require('ssh-deploy-release'); 2 3const options = { 4 localPath: 'src', 5 host: 'my.server.com', 6 username: 'username', 7 password: 'password', 8 deployPath: '/var/www/vhost/path/to/project' 9}; 10 11const deployer = new Application(options); 12deployer.deployRelease(() => { 13 console.log('Ok !') 14});
1const Application = require('ssh-deploy-release'); 2 3const options = { 4 localPath: 'src', 5 host: 'my.server.com', 6 username: 'username', 7 password: 'password', 8 deployPath: '/var/www/vhost/path/to/project', 9 allowRemove: true 10}; 11 12const deployer = new Application(options); 13deployer.removeRelease(() => { 14 console.log('Ok !') 15});
1const Application = require('ssh-deploy-release'); 2 3const options = { 4 localPath: 'src', 5 host: 'my.server.com', 6 username: 'username', 7 password: 'password', 8 deployPath: '/var/www/vhost/path/to/project' 9}; 10 11const deployer = new Application(options); 12deployer.rollbackToPreviousRelease(() => { 13 console.log('Ok !') 14});
The previous release will be renamed before updating the symlink of the current version, for example
2019-01-09-10-53-35-265-UTC
will become
2019-01-09-13-46-45-457-UTC_rollback-to_2019-01-09-10-53-35-265-UTC
.
If rollbackToPreviousRelease
is called several times, the current version
will switch between the last two releases.
current date + "_rollbackTo_"
will be prepended to the release name on each call of
rollbackToPreviousRelease
so be careful not to exceed the size limit of the folder name.
You can use this to deploy from any platform supporting Node >= 8 to Linux servers (most UNIX systems should work as well but this hasn't been tested).
Due to how we implemented the deployment process on the remote environment (using shell command execution), supporting Windows would required a lot of specific code, which would make this package harder to maintain. We decided to focus on supporting Linux as its the platform most widely used by hosting providers.
ssh-deploy-release uses ssh2 to handle SSH connections.
The options
object is forwarded to ssh2
methods,
which means you can set all ssh2
options:
If true
, will display all commands.
Default : false
Port used to connect to the remote server.
Default : 22
Remote server hostname.
Username used to connect to the remote server.
Password used to connect to the remote server.
Default: null
Default: null
For an encrypted private key, this is the passphrase used to decrypt it.
Default: null
To connect using the machine's ssh-agent. The value must be the path to the ssh-agent socket (usually available in the
SSH_AUTH_SOCK
environment variable).
archive
: Deploy an archive and decompress it on the remote server.
synchronize
: Use rsync. Files are synchronized in the options.synchronized
folder on the remote server.
Default : archive
zip
: Use zip compression (unzip
command on remote)
tar
: Use tar gz compression (tar
command on remote)
Default : tar
Name of the archive.
Default : release.tar.gz
Delete the local archive after the deployment.
Default : true
SCP connection timeout duration.
Default : 20000
Callback passed to ssh2
client event
keyboard-interactive
.
Type: function (name, descr, lang, prompts, finish)
Name of the current release symbolic link. Relative to deployPath
.
Defaut : www
Name of the folder containing shared folders. Relative to deployPath
.
Default : shared
Name of the folder containing releases. Relative to deployPath
.
Default : releases
Name of the local folder to deploy.
Default : www
⚠ ️In case you need to deploy your whole project directory, do NOT set localPath
to an empty string, null
or .
. Use process.cwd()
to have node generate an
absolute path. In addition to this, if you use the archive mode,
don't forget to exclude the generated archive
(you can define its name using options.archiveName).
Example:
1const Application = require('ssh-deploy-release'); 2const process = require('process'); 3 4const deployer = new Application({ 5 localPath: process.cwd(), 6 exclude: ['release.tar.gz'], 7 archiveName: 'release.tar.gz', 8 host: 'my.server.com', 9 username: 'username', 10 password: 'password', 11 deployPath: '/var/www/vhost/path/to/project', 12});
Absolute path on the remote server where releases will be deployed. Do not specify currentReleaseLink (or www folder) in this path.
Name of the remote folder where rsync synchronize release.
Used when mode
is 'synchronize'.
Default : www
Additional options for rsync process.
Default : ''
1rsyncOptions : '--exclude-from="exclude.txt" --delete-excluded'
Enable the rsync --compression flag. This can be set to a boolean or an integer to explicitly set the compression level (--compress-level=NUM).
Default : true
Number of releases to keep on the remote server.
Default : 3
Name of the release. Must be different for each release.
Default : Use current timestamp.
List of paths to not deploy.
Paths must be relative to localPath
.
The format slightly differ depending on the mode
:
mode: 'archive'
**
.exclude: ['my-folder/**']
Read glob documentation for more information.
mode: 'synchronize'
exclude: ['my-folder']
For maximum portability, it's strongly advised to use both syntaxes when excluding folders.
For example: exclude: ['my-folder/**', 'my-folder']
Default : []
List of folders to "share" between releases. A symlink will be created for each item.
Item can be either a string or an object (to specify the mode to set to the symlink target).
1share: { 2 'images': 'assets/images', 3 'upload': { 4 symlink: 'app/upload', 5 mode: '777' // Will chmod 777 shared/upload 6 } 7}
Keys = Folder to share (relative to sharedFolder
)
Values = Symlink path (relative to release folder)
Default : {}
List of folders to create on the remote server.
Default : []
List of files to make writable on the remote server. (chmod ugo+w)
Default : []
List of files to make executable on the remote server. (chmod ugo+x)
Default : []
If true, the remote release folder can be deleted with removeRelease
method.
Default: false
The following object is passed to onXXX
callbacks :
1{ 2 // Loaded configuration 3 options: { }, 4 5 // Release 6 release: { 7 // Current release name 8 tag: '2017-01-25-08-40-15-138-UTC', 9 10 // Current release path on the remote server 11 path: '/opt/.../releases/2017-01-25-08-40-15-138-UTC', 12 }, 13 14 // Logger methods 15 logger: { 16 // Log fatal error and stop process 17 fatal: (message) => {}, 18 19 // Log 'subhead' message 20 subhead: (message) => {}, 21 22 // Log 'ok' message 23 ok: (message) => {}, 24 25 // Log 'error' message and continue process 26 error: (message) => {}, 27 28 // Log message, only if options.debug is true 29 debug: (message) => {}, 30 31 // Log message 32 log: (message) => {}, 33 34 // Start a spinner and display message 35 // return a stop() 36 startSpinner: (message) => { return {stop: () => {}}}, 37 }, 38 39 // Remote server methods 40 remote: { 41 // Excute command on the remote server 42 exec: (command, done, showLog) => {}, 43 44 // Excute multiple commands (array) on the remote server 45 execMultiple: (commands, done, showLog) => {}, 46 47 /* 48 * Upload local src file to target on the remote server. 49 * @param {string} src The path to the file to upload. 50 * May be either absolute or relative to the current working directory. 51 * @param {string} target The path of the uploaded file on the remote server. 52 * Must include the filename. The full directory hierarchy to the target must already exist. 53 * May be either absolute or relative to the remote user home directory. 54 * We strongly encourage you to use `options.deployPath` in your target path to produce an absolute path. 55 */ 56 upload: (src, target, done) => {}, 57 58 // Create a symbolic link on the remote server 59 createSymboliclink: (target, link, done) => {}, 60 61 // Chmod path on the remote server 62 chmod: (path, mode, done) => {}, 63 64 // Create folder on the remote server 65 createFolder: (path, done) => {}, 66 } 67}
onBeforeDeploy, onBeforeLink, onAfterDeploy, onBeforeRollback, onAfterRollback options.
1onAfterDeploy: 'apachectl graceful'
Or with a function :
1onBeforeLink: context => `chgrp -R www ${context.release.path}`
1onAfterDeploy: [ 2 'do something on the remote server', 3 'and another thing' 4]
Or with a function :
1onBeforeLink: (context) => { 2 context.logger.subhead('Fine tuning permissions on newly deployed release'); 3 return [ 4 `chgrp -R www ${context.release.path}`, 5 `chmod g+w ${context.release.path}/some/path/that/needs/to/be/writable/by/www/group`, 6 ]; 7}
1onAfterDeploy: context => { 2 return Promise((resolve, reject) => { 3 setTimeout(function () { 4 // Do something 5 resolve(); 6 }, 5000); 7 }); 8}
Executed before connecting to the SSH server to let you initiate a custom
connection. It must return a ssh2 Client instance, and call onReady
when that
connection is ready.
Type: function(context, onReady, onError, onClose): Client
Example: SSH jumps (connecting to your deployment server through a bastion)
1onBeforeConnect: (context, onReady, onError, onClose) => { 2 const bastion = new Client(); 3 const connection = new Client(); 4 5 bastion.on('error', onError); 6 bastion.on('close', onClose); 7 bastion.on('ready', () => { 8 bastion.forwardOut( 9 '127.0.0.1', 10 12345, 11 'www.example.com', 12 22, 13 (err, stream) => { 14 if (err) { 15 context.logger.fatal(`Error connection to the bastion: ${err}`); 16 bastion.end(); 17 onClose(); 18 return; 19 } 20 21 connection.connect({ 22 sock: stream, 23 user: 'www-user', 24 password: 'www-password', 25 }); 26 } 27 ); 28 }); 29 30 connection.on('error', (err) => { 31 context.logger.error(err); 32 bastion.end(); 33 }); 34 connection.on('close', () => { 35 bastion.end(); 36 }); 37 connection.on('ready', onReady); 38 39 bastion.connect({ 40 host: 'bastion.example.com', 41 user: 'bastion-user', 42 password: 'bastion-password', 43 }); 44 45 return connection; 46}
Executed before deployment.
Type: string | string[] | function(context, done): Promise | undefined
Executed before symlink creation.
Type: string | string[] | function(context, done): Promise | undefined
Executed after deployment.
Type: string | string[] | function(context, done): Promise | undefined
Executed before rollback to previous release.
Type: string | string[] | function(context, done): Promise | undefined
Executed after rollback to previous release.
Type: string | string[] | function(context, done): Promise | undefined
A command on a callback method is not executed or not found.
Try to add set -i && source ~/.bashrc &&
before your commmand :
onAfterDeploy:[
'set -i && source ~/.bashrc && my command'
]
See this issue : https://github.com/mscdex/ssh2/issues/77
1# Build (with Babel) 2npm run build 3 4# Build + watch (with Babel) 5npm run build -- --watch 6 7# Launch tests (Mocha + SinonJS) 8npm test 9 10# Launch tests + watch (Mocha + SinonJS) 11npm test -- --watch
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
Found 1/24 approved changesets -- score normalized to 0
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Reason
14 existing vulnerabilities detected
Details
Score
Last Scanned on 2025-01-27
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More