12
votes

This is Jenkins file in the root of node app directory:

pipeline {
    agent any
    triggers {
        pollSCM('* * * * *')
    }
    stages {
        stage("deploy") {
            steps {
            sh "scp"
            }
        }
    } 
}

I configured Jenkins to connect to remote gitlab node proj repo to checkout node project along with Jenkinsfile and run the project's Jenkinsfile. This part works fine but what to do now to perform (note that Jenkins server and the server on which node js is running as well as gitlab repo are all remote to each other):

run these commands on remote server on which node app is running

cd ~/mynodeproj 

pm2 stop mynodeproj 

copy project source files from Jenkins server to remote server where 
node app is running 

npm install 

export NODE_ENV=production 

pm2 start mynodeproj

How to achieve this?

Do I need to setup private/public keypair on server running jenkins so that jenkins server can do scp to copy file to remote server running node app?

4
Correct. Once you've done that, you can then use scp to copy the files and ssh to run these commands at the remote server.Vasan
@ace: Did you try all three answers? Can you choose what's the best way for bountyQuynh Nguyen

4 Answers

6
votes

I'm suggest we can use Rocketeer for this case.

Here is Rocketeer tree on my Jenkins Server for NodeJS App

$ tree .rocketeer/
.rocketeer/
├── config.php
├── hooks.php
├── logs
│   ├── develop--20170613.log
│   ├── develop--20170614.log
│   ├── develop--20170616.log
│   ├── staging--20180323.log
│   ├── staging--20180324.log
│   ├── staging--20180326.log
│   ├── production--20180223.log
│   ├── production--20180226.log
│   ├── production--20180227.log
│   ├── production--20180227.log
│   └── custom-environment--20180328.log
├── paths.php
├── remote.php
├── scm.php
├── stages.php
└── strategies.php
  • You can manage remote environment of NodeJS App: Develop, Staging, Production (at config.php file)
  • It's will pull newest source code on your Gitlab and keep releases version like Capistrano (at remote.php file)
  • It's can run your pm2 command line after deployed newest source code (at hooks.php file)
  • It's already help run npm install NodeJS packages.

So here is my Jenkins Job setting:

Source Code Management

enter image description here

Build Triggers

enter image description here

Build

enter image description here

#!/bin/bash -el
cd $JENKINS_HOME/app-deploy/app-socketio
rocketeer deploy --on="develop"

develop mean connect to Develop Remote Server (at .rocketeer\config.php file)

'connections'      => [
    'develop' => [
        'host'      => '35.xx.xx.xx',
        'username'  => 'ec2-user',
        'password'  => '',
        'key'       => '/var/lib/jenkins/.ssh/foo.pem',
        'keyphrase' => '',
        'agent'     => '',
        'db_role'   => true,
    ],
    'staging' => [
        'host'      => '34.xx.xx.xx',
        'username'  => 'ec2-user',
        'password'  => '',
        'key'       => '/var/lib/jenkins/.ssh/bar.pem',
        'keyphrase' => '',
        'agent'     => '',
        'db_role'   => true,

    ],
    'production' => [
        'host'      => '18.xx.xx.xx:63612',
        'username'  => 'ec2-user',
        'password'  => '',
        'key'       => '/var/lib/jenkins/.ssh/woot.pem',
        'keyphrase' => '',
        'agent'     => '',
        'db_role'   => true,
    ],
    'custom-environment' => [
        'host'      => '13.xx.xx.xx:63612',
        'username'  => 'ec2-user',
        'password'  => '',
        'key'       => '/var/lib/jenkins/.ssh/test.pem',
        'keyphrase' => '',
        'agent'     => '',
        'db_role'   => true,
    ],
],

And run pm2 command line configure at hooks.php file

'after'  => [
    'setup'   => [],
    'deploy'  => [
            "pm2 delete mynodeproj", //Delete old pm2 task
            "pm2 start src/mynodeproj.js", //Start new mynodeproj
    ],
    'cleanup' => [],
],

Hope this can help you!!

4
votes

What to do now to perform (note that Jenkins server and the server on which node js is running as well as gitlab repo are all remote to each other):

Those command should be in a file part of your Git repo, meaning checked out in the workspace used by the pipeline.

From there, you can scp that script to the server:

sh 'scp -r script user@server:/path/server'

And execute it through ssh, provided the private/public key of the remote user is deployed on the agent (or passed through the ssh-agent plugin):

sh 'ssh user@server /path/server/script'

The trick though, as mentioned here, is that the PATH of an ssh session is fairly limited, and might not include node, if node is not installed in a standard path like /usr/bin.
So you might want to modify your script in order to use absolute paths for your executable (like /absolute/path/to/node)

4
votes

Your question is how to deploy your application to remote host from jenkins

easiest solution

1.using Jenkins File

If your using a pipeline project, then you will notice a Pipeline Syntax option, just select ssh Publisher:send artifacts over SSH (you'llneed the plugin Publish over SSH plugin)

enter image description here Add an SSH server

  • Source Files :mention the files you wish to transfer (**/*.war takes the WAR file only)
  • Remove prefix : target(WAR files will generally be located in a target folder so i'm telling I don't want the target folder to be copied only my WAR)
  • Remote Directory : Leave it blank( since your taking it from your project)
  • Exec command : Commands to be executed after copying the files( like starting tomcat or unzip any properties files and place at a particular location - in your case the commands to start node from your server)

Finally just click Generate Pipeline Script and BOOM, you get the script (it internally does an scp) just copy and paste it into your Pipeline file and your done :)

enter image description here)

2.Publish over SSH

You can do the same thing( follow the above steps adding details only) in a normal Jenkins project in the Post Build Action If you don't have a Pipeline Project (helps if you don't have/know a Pipeline Project)

enter image description here

Do I need to setup private/public keypair on server running jenkins so that jenkins server can do scp to copy file to remote server running node app?

Yes its required(Recommended) you can add the deatils as shown below in Jenkins under Manage Jenkins, Configure Jenkins Under Publish over SSH and you can test your connection .

enter image description here

Hope this was useful :)

2
votes

You might want to consider doing this with ansible and just call your ansible playbook from: Build -> Execute Shell

https://dzone.com/articles/running-ansible-playbooks-from-jenkins

You can have ansible manage all your remote environments.