【问题标题】:How to deploy node app to remote host from Jenkins?如何从 Jenkins 将节点应用程序部署到远程主机?
【发布时间】:2018-09-22 21:31:55
【问题描述】:

这是节点应用目录根目录下的 Jenkins 文件:

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

我将 Jenkins 配置为连接到远程 gitlab node proj repo 以检查节点项目以及 Jenkinsfile 并运行项目的 Jenkinsfile。这部分工作正常,但是现在要执行什么操作(请注意,Jenkins 服务器和运行节点 js 的服务器以及 gitlab repo 都是相互远程的):

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

如何做到这一点?

我是否需要在运行 jenkins 的服务器上设置私钥/公钥对,以便 jenkins 服务器可以执行 scp 将文件复制到运行节点应用程序的远程服务器?

【问题讨论】:

  • 正确。完成后,您可以使用 scp 复制文件并使用 ssh 在远程服务器上运行这些命令。
  • @ace:您尝试了所有三个答案吗?你能选择最适合bounty的方式吗?

标签: node.js jenkins deployment gitlab


【解决方案1】:

我建议我们可以在这种情况下使用Rocketeer

这是我的 Jenkins 服务器上用于 NodeJS 应用程序的 Rocketeer

$ 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
  • 您可以管理 NodeJS 应用程序的远程环境:开发、暂存、生产(config.php 文件)
  • 它将在您的 Gitlab 上提取最新的源代码并保留发布版本,如 Capistranoremote.php 文件)
  • 在部署最新的源代码(hooks.php 文件)后,它可以运行你的pm2 command line
  • 它已经帮助运行npm install NodeJS 包。

这是我的 Jenkins 工作设置:

源代码管理

构建触发器

构建

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

develop 表示连接到 Develop Remote Server(.rocketeer\config.php 文件)

'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,
    ],
],

并在hooks.php文件处运行pm2命令行配置

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

希望对你有帮助!!

【讨论】:

    【解决方案2】:

    现在要执行的操作(注意Jenkins服务器和运行节点js的服务器以及gitlab repo都是相互远程的):

    这些命令应该在 Git 存储库的文件部分中,这意味着在管道使用的工作区中签出。

    从那里,您可以将该脚本 scp 到服务器:

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

    并通过 ssh 执行,前提是远程用户的私钥/公钥部署在代理上(或通过ssh-agent plugin 传递):

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

    不过,就像mentioned here 一样,诀窍在于 ssh 会话的 PATH 相当有限,并且可能不包括节点,如果节点 安装在像 /usr/bin 这样的标准路径中.
    所以你可能想修改你的脚本以便为你的可执行文件使用绝对路径(比如/absolute/path/to/node

    【讨论】:

    • so 名为 'script' 的文件是用 #!/bin/sh 声明的 bash shell 脚本?它看起来是一个很好的解决方案,但问题似乎是现在所有命令都在单独的脚本文件中执行,而不是在 Jenkinsfile 中作为步骤执行。在后一种情况下,如果任何步骤失败,例如步骤“pm2 stop mynodeproj”失败,Jenkins 管道构建将停止并变红。但是在您的解决方案中,Jenkins 将不知道脚本中的任何命令是否失败?
    • @ace 您可以使用#!/bin/sh -x 开始您的脚本:如果脚本执行失败,您将确切看到哪一行失败,即)
    • 还不清楚如何对远程服务器运行节点执行 scp 源代码?我的意思是,如果我将文件从本地 PC 推送到 gitlap 存储库,这将触发 Jenkins 检查更改的文件。在此之后,Jenkins 将如何仅将此更改的文件 scp 到运行节点应用程序的远程服务器?此外,您的脚本解决方案可能必须在两个脚本中中断,一个脚本首先停止正在运行的节点应用程序,然后在第二个脚本运行其余命令之后,Jenkins scp 将源文件更改为远程服务器。我是否需要在运行节点应用程序的远程服务器上设置 git repo 并配置 Jenkins 以推送到它?
    • @ace 我在答案中提到了如何 scp 文件。 scp 用于没有 Jenkins 或 Git 的远程服务器。
    【解决方案3】:

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

    最简单的解决方案

    1.使用 Jenkins 文件

    如果您使用的是管道项目,那么您会注意到一个管道语法选项,只需选择 ssh Publisher:send artifacts over SSH(您需要插件 Publish over SSH 插件)

    添加 SSH 服务器

    • 源文件:提及您希望传输的文件(**/*.war 需要 仅限 WAR 文件)
    • 删除前缀:目标(WAR 文件通常是 位于目标文件夹中,所以我告诉我不想要目标 文件夹仅复制我的 WAR)
    • 远程目录:留空( 因为你把它从你的项目中拿走了)
    • Exec command : 复制文件后要执行的命令(例如启动 tomcat 或解压缩任何属性文件并放置在特定位置 - 在您的情况下是从服务器启动节点的命令)

    最后只需单击 Generate Pipeline Script 和 BOOM,您就可以得到脚本(它在内部执行一个 scp),只需将其复制并粘贴到您的 Pipeline 文件中即可完成 :)

    )

    2.通过 SSH 发布

    您可以在 Post Build Action 的普通 Jenkins 项目中执行相同的操作(仅按照上述步骤添加详细信息) 如果您没有流水线项目(如果您没有/不知道流水线项目会有所帮助)

    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?

    是的,它是必需的(推荐),您可以在 Jenkins 的 Manage Jenkins 下添加如下所示的细节,Configure Jenkins 在 Publish over SSH 下,您可以测试您的连接。

    希望这有用:)

    【讨论】:

      【解决方案4】:

      您可能需要考虑使用 ansible 执行此操作,只需从以下位置调用您的 ansible playbook:Build -> Execute Shell

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

      您可以让 ansible 管理您的所有远程环境。

      【讨论】:

        猜你喜欢
        • 2019-11-06
        • 1970-01-01
        • 2018-02-15
        • 2020-11-29
        • 2015-05-09
        • 1970-01-01
        • 1970-01-01
        • 2019-11-08
        • 2015-02-18
        相关资源
        最近更新 更多