Skip to content

文章

在Ubuntu上使用Nodejs设置持续集成

2015年8月15日 • 16 分钟阅读

在Ubuntu上使用Nodejs设置持续集成

我经历了血、汗和泪水才为你带来这个。我忍受了死亡谷的炎热,登上了麦金利山的峰顶。我付出了很多。

本文中分享的大部分内容不是我的原创作品。在可能的情况下,我会链接回原始作品。

本文假设你能够在Linux中自如地操作。

我找不到一份关于在生产环境中在Ubuntu上托管和管理Nodejs应用程序的综合指南。我汇集了多篇关于这个主题的文章。到本文结束时,我希望你能够设置自己的Ubuntu服务器,并通过持续集成服务器部署Nodejs。

环境

我在Windows上使用TeamCity,然后将代码从GitHub部署到AWS上托管的Ubuntu。

技术

本文使用了以下技术:

  • AWS上的Ubuntu 14.04
  • Plink 0.64
  • TeamCity 9.1
  • GitHub
  • Nginx 1.9.3

设置Ubuntu

我不会在这里详细介绍。亚马逊网络服务(AWS)使这变得相当容易。无论它在哪里或是否在你自己的服务器上都没关系。

我遇到了一些问题。首先,确保端口80已打开。我犯了一个愚蠢的错误,试图在端口80关闭的情况下连接。一旦我发现我的错误,我感到像一只犀牛的屁股。

从源代码安装Nodejs

Nodejs是一种使用Google的V8 javascript引擎的服务器技术。自2010年发布以来,它变得广泛流行。

以下说明最初来自Digital Ocean文章

你总是可以选择从apt-get安装Nodejs,但它会落后几个版本。要获得最新版本,请从源代码安装Nodejs。

在本节结束时,我们将下载最新的稳定版本的node(截至本文),我们将构建源代码并安装Nodejs。

登录到你的服务器。我们将从更新包列表开始。

sudo apt-get update

我还建议你升级所有包。这对于Nodejs不是必需的,但保持服务器更新是一个很好的做法。

sudo apt-get upgrade

你的服务器已经是最新的。现在是下载源代码的时候了。

cd ~

在撰写本文时,12.7是Nodejs的最新稳定版本。查看nodejs.org了解最新版本。

wget https://nodejs.org/dist/v0.12.7/node-v0.12.7.tar.gz

提取你下载的存档。

tar xvf node-v*

进入新创建的目录

cd node-v*

配置并构建Nodejs。

./configure

make

安装Nodejs

sudo make install

删除下载和提取的文件。当然,这是可选的。

cd ~

rm -rf node-v*

恭喜!Nodejs现在已安装!这并不是很难。

设置Nginx

来源

Nodejs可以充当Web服务器,但这不是我想要暴露给世界的。一个工业级的、加固的、功能丰富的Web服务器更适合这个任务。我已经转向Nginx来完成这个任务。

它是一个成熟的Web服务器,具有我们需要的功能。要运行多个Nodejs实例,我们需要端口转发。

你可能在想,为什么我们需要同时运行多个Nodejs实例。这是一个公平的问题……在我的场景中,我有一个服务器,我需要在同一台机器上运行DEV、QA和PROD。是的,我知道这不理想,但我不想为每个环境建立3个服务器。

首先让我们安装Nginx

sudo -s

add-apt-repository ppa:nginx/stable

apt-get update 

apt-get install nginx

一旦Nginx成功安装,我们需要在域上进行设置。我将假设你希望每个网站都在自己的域/子域上。如果你不想这样做,想使用不同的子文件夹,这是可行的,也很容易做到。我不会在这里介绍这种情况。有大量的文档说明如何做到这一点。关于设置不同域和端口转发到相应Nodejs实例的文档很少。这就是我要介绍的内容。

现在Nginx已安装,在/etc/nginx/sites-available/创建一个yourdomain.com的文件

sudo nano /etc/nginx/sites-available/yourdomain.com

将以下配置添加到新创建的文件中

# the IP(s) on which your node server is running. I chose port 9001.
upstream app_myapp1 {
    server 127.0.0.1:9001;
    keepalive 8;
}

# the nginx server instance
server {
    listen 80;
    server_name yourdomain.com;
    access_log /var/log/nginx/yourdomain.log;

    # pass the request to the node.js server with the correct headers
    # and much more can be added, see nginx config options
    location / {
        proxy_http_version 1.1;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;

        proxy_pass http://app_myapp1;

    }
 }

确保将”yourdomain.com”替换为你的实际域。保存并退出编辑器。

在sites-enabled目录中创建此文件的符号链接。

cd /etc/nginx/sites-enabled/ 

ln -s /etc/nginx/sites-available/yourdomain.com yourdomain.com

要测试一切是否正常工作,请创建一个简单的node应用程序并将其保存到/var/www/yourdomain.com/app.js并运行它。

如果你没有现成的简单nodejs应用程序,这里有一个。

var http = require('http');

http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World\n');}).listen(9001, "127.0.0.1");
console.log('Server running at http://127.0.0.1:9001/');

让我们重启Nginx。

sudo /etc/init.d/nginx restart

不要忘记启动你的Nodejs实例(如果你还没有的话)。

cd /var/www/yourdomain/ && node app.js

如果一切正常工作,当你导航到yourdomain.com时,你会看到”Hello World”。

要为不同的Nodejs实例添加另一个域,你需要重复上述步骤。具体来说,你需要更改上游名称、端口和新Nginx配置文件中的域。proxy_pass地址必须与nginx配置文件中的上游名称匹配。查看上游名称和proxy_pass值,你会看到我的意思。

总结一下,我们从源代码安装了NodeJS,我们刚刚完成了Nginx的安装。我们配置并测试了Nginx和Nodejs的端口转发

安装PM2

你可能在问”PM2是什么?“就像我第一次听到它时一样。PM2是Nodejs应用程序的进程管理器。Nodejs没有附带太多功能。这是它的吸引力的一部分。缺点是,你必须提供前面的层。PM2就是其中之一。

PM2管理Nodejs进程的生命周期。当它被终止时,PM2会重新启动它。当服务器重启时,PM2会为你重新启动所有Nodejs进程。它还具有广泛的开发生命周期流程。我们不会介绍PM2的这个方面。我鼓励你阅读编写良好的文档

假设你已登录到终端,我们将通过NPM开始安装PM2。Npm是Nodejs包管理器(npm)。当你安装Nodejs时,它已被安装。

sudo npm install pm2 -g

就这样。PM2现在已安装。

使用PM2

PM2很容易使用。

PM2的hello world很简单。

pm2 start hello.js

这将你的应用程序添加到PM2的进程列表中。每次启动应用程序时都会输出此列表。

在此示例中,有两个Nodejs应用程序正在运行。一个叫api.dev,一个叫api.pre。

PM2自动将应用程序的名称分配给列表中的”App name”。

开箱即用,PM2不会将自己配置为在服务器重启时启动。该命令对于不同的Linux发行版是不同的。我在Ubuntu上运行,所以我将执行Ubuntu命令。

pm2 start ubuntu

我们还没有完全完成。我们必须添加PM2二进制文件的路径。幸运的是,前一个命令的输出告诉我们如何做到这一点。

输出:

[PM2] You have to run this command as root
[PM2] Execute the following command :
[PM2] sudo env PATH=$PATH:/usr/local/bin pm2 startup ubuntu -u sammy
运行生成的命令(类似于上面突出显示的输出)以设置PM2在启动时启动(使用你自己的输出中的命令):

 sudo env PATH=$PATH:/usr/local/bin pm2 startup ubuntu -u sammy

其他PM2用法示例(可选)

按应用程序名称停止应用程序

pm2 stop example

按应用程序名称重启

pm2 restart example

PM2管理的当前应用程序列表

pm2 list

启动进程时指定名称。如果你调用,PM2使用javascript文件作为名称。这可能对你不起作用。以下是如何指定名称的方法。

pm2 start www.js --name api.pre

这应该足以让你开始使用PM2。要了解有关PM2功能的更多信息,请访问GitHub仓库

你可能在想,“以Betsey的牛的名义,Plink是什么?“至少那是我的想法。我仍然不确定该怎么想。我从未见过这样的东西。

你看过电影Wall-e吗?Wall-e拿出了一个勺叉。首先他试图把它放在叉子里,但它不适合,然后他试图把它放在勺子里,但它也不适合。好吧,那就是Plink。它是Putty(SSH)和Windows命令行的混合体。

Plink基本上允许你在登录到Linux(可能还有Unix)shell时从Windows命令行运行bash命令。

首先下载Plink。它只是一个可执行文件。我建议将其放在C:/Program Files (x86)/Plink中。我们稍后需要引用它。

如果你在AWS中运行Ubuntu实例。你已经为Putty设置了证书(我假设你在使用Putty)。

如果你没有,你需要确保你有一个与AWS中的Ubuntu兼容的ssh证书。

如果你不使用AWS,你可以在命令行中指定用户名和密码,不用担心ssh证书。

这是一个使用Plink连接到Ubuntu的命令行示例。

"C:\Program Files (x86)\Plink\plink.exe" -ssh ubuntu@xx.xx.xx.xx -i "C:\Program Files (x86)\Plink\ssh certs\aws-ubuntu.ppk" 

这可能有点超前,但要在Ubuntu服务器上运行ssh脚本,我们将完整路径添加到Plink命令的末尾。

"C:\Program Files (x86)\Plink\plink.exe" -ssh ubuntu@xx.xx.xx.xx -i "C:\Program Files (x86)\Plink\ssh certs\aws-ubuntu.ppk" /var/www/deploy-dev-ui.sh

就这样,亲爱的读者,这就是Plink。

理解NODE_ENV

NODE_ENV是一个由expressjs推广的环境变量。在启动node实例之前,将NODE_ENV设置为环境。在代码中,你可以根据环境加载特定文件。

设置NODE_ENV
Linux & Mac: export NODE_ENV=PROD
Windows: set NODE_ENV=PROD

环境变量通过使用process.env.NODE_ENV在Nodejs实例内检索。

示例

var environment = process.env.NODE_ENV

或使用expressjs

app.get('env')

*注意:app.get('env')默认为”development”。

将所有内容整合在一起

NodejsPM2NginxPlink已安装,希望能正常工作。我们现在需要将所有这些部分整合到一个持续集成解决方案中。

/var/www/yourdomain.com中克隆你的GitHub仓库。虽然SSH比HTTPS更安全,但我建议使用HTTPS。我知道这不理想,但我无法让Plink与Ubuntu上的GitHub一起工作。不详细说明,Plink和GitHub SSH证书格式不同,通过Plink通过SSH调用GitHub不起作用。如果你能找出问题所在,请告诉我!

要使GitHub拉取无需手动操作,用户名和密码需要成为源URL的一部分。

以下是如何设置源URL的方法。当然,你需要在适当的地方替换你的信息。

git remote set-url origin  https://username:password@github.com/username/yourdomain.git

克隆你的仓库。

cd /var/www/yourdomain.com
git clone https://username:password@github.com/username/yourdomain.git .

注意,如果此目录不是完全空的(包括隐藏文件),Git将不会将仓库克隆到此目录。

要查找目录中的隐藏文件,请运行此命令

ls -a

对于粘合剂,我们使用shell脚本。这是我的脚本的副本。

#!/bin/bash

echo "> Current PM2 Apps"
pm2 list

echo "> Stopping running API"
pm2 stop api.dev

echo "> Set Environment variable."
export NODE_ENV=DEV

echo "> Changing directory to dev.momentz.com."
cd /var/www/yourdomain.com

echo "> Listing the contents of the directory."
ls -a

echo "> Remove untracked directories in addition to untracked files."
git clean -f -d

echo "> Pull updates from Github."
git pull

echo "> Install npm updates."
sudo npm install

echo "> Transpile the ECMAScript 2015 code"
gulp babel

echo "> Restart the API"
pm2 start transpiled/www.js --name api.dev

echo "> List folder directories"
ls -a

echo "> All done."

我用TeamCity启动这个shell脚本,但你可以用任何东西启动。

这是原始命令。

"C:\Program Files (x86)\Plink\plink.exe" -ssh ubuntu@xx.xx.xx.xx -i "C:\Program Files (x86)\Plink\ssh certs\aws-ubuntu.ppk" /var/www/deploy-yourdomain.sh
exit
>&2

就这样。

总结

这个过程有一些粗糙的边缘……我希望随着时间的推移能够打磨这些边缘。如果你有建议,请在评论中留下。

这份文档在我的GitHub仓库中。技术在变化,所以如果你发现错误,请更新它。然后我会更新这篇文章。

作者:Chuck Conway 是一位 AI 工程师,拥有近 30 年的软件工程经验。他构建实用的 AI 系统——内容管道、基础设施代理和解决实际问题的工具——并分享他沿途的学习成果。在社交媒体上与他联系:X (@chuckconway) 或访问他的 YouTubeSubStack

↑ 返回顶部

你可能也喜欢