【Node.js】node-sshでファイルをアップロードする

ネコニウム研究所

PCを利用したモノづくりに関連する情報や超個人的なナレッジを掲載するブログ

【Node.js】node-sshでファイルをアップロードする

2021-11-17 |

故あって、Node.js で FTP を使わずに SSH を使ってファイルをアップロードしたい。

セキュリティ的にも鍵認証の SSH を使った方が良い。良いはず。

実行環境

  • CentOS Linux release 7.9.2009 (Core)
  • Node.js v12.22.7
  • npm 8.1.3
  • node-ssh ^12.0.1
  • path ^0.12.7

え?OS のバージョンが古い?
と、閉じた環境だから許して!

手順書

必要なパッケージをインストールする

今回は、ssh-nodepath を使用するので下記のコマンドを実行し、各パッケージをインストールする。

npm install ssh-node path --save-dev

アップロード用のスクリプトを書く

ssh-upload.js というファイルを作成し、下記のコードを入力する。

const path = require('path');

const {
    NodeSSH
} = require('node-ssh');
const ssh = new NodeSSH();

ssh.connect({
        host: 'hostname or ip address',
        port: 22,
        username: 'username',
        privateKey: 'key'
        passphrase: 'pass'
    })
    .then(function () {
        const failed = []
        const successful = []
        ssh.putDirectory('./dist', '/var/www/html', {
            recursive: true,
            concurrency: 10,
            validate: function (itemPath) {
                const baseName = path.basename(itemPath)
                return baseName.substr(0, 1) !== '.' && baseName !== 'node_modules'
            },
            tick: function (localPath, remotePath, error) {
                if (error) {
                    failed.push(localPath)
                } else {
                    successful.push(localPath)
                }
            }
        }).then(function (status) {
            console.log('the directory transfer was', status ? 'successful' : 'unsuccessful')
            console.log('failed transfers', failed.join(', '))
            console.log('successful transfers', successful.join(', '))
            process.exit(1);
        })
    })

解説

実際に使用するにあたって、変更が必要な箇所について解説する。

ログイン関連
ssh.connect({
        host: 'hostname or ip address',
        port: 22,
        username: 'username',
        privateKey: 'key'
        passphrase: 'pass'
    })

上記はそれぞれのログインの環境に合わせて、書き換える。
パスフレーズを使用していない場合は、passphrase を省略できる。

転送元と転送先
ssh.putDirectory('./dist', '/var/www/html', {

関数 ssh.putDirectory の第 1 引数に転送元、第 2 引数に転送先のディレクトリのパスを入力する。

除外ディレクトリ・ファイル
return baseName.substr(0, 1) !== '.' && baseName !== 'node_modules'

上記の条件式にアップロードしないディレクトリ・ファイルを入力する。
上記の例では、ディレクトリ node_modules をアップロードから除外している。

例として、ディレクトリ .vscode をアップロードから除外したい場合は下記のように入力する。

return baseName.substr(0, 1) !== '.' && baseName !== 'node_modules' && baseName !== '.vscode'

これ配列かなんかで書けると良いんですけどね。

スクリプトを実行する

下記のコマンドでスクリプトを実行する。

node ssh-upload

ターミナルに the directory transfer was successful と表示され、アップロードに成功したファイルの一覧が出力されれば成功だ!

まとめ

FTP を何らかの理由(FTP のポートを開放したくない等)で使えない Node.js の開発環境でファイルをアップロードするやり方として、ssh-node を使ったやり方を紹介しました。

ssh-node は、ファイルのアップロード以外にもリモート接続先のサーバーでコマンド実行できたり、いろいろ効率化を図れそうな感じです。
いろいろできる反面、下手なコマンドを実行したりしないよう注意が必要ですね!まじで!

引用・参考文献

下記の公式のページを参考に(ほぼそのまま)させて頂きました。
ありがとうございました。