Node.js: 快速入门

了解如何在 Stackhero 上快速且安全地部署 Node.js 服务

👋 欢迎使用 Stackhero 文档!

Stackhero 提供现成的 Node.js 云 解决方案,具有众多优势,包括:

  • 通过简单的 git push 在几秒钟内 部署您的应用程序。
  • 使用您自己的域名,并享受 HTTPS 证书的自动配置以增强安全性。
  • 享受自动备份一键更新以及简单、透明和可预测的定价带来的安心。
  • 通过专用私有 VM获得最佳的性能和强大的安全性

节省时间简化您的生活:只需 5 分钟即可试用 Stackhero 的 Node.js 云托管 解决方案!

在 Stackhero 上部署您的 Node.js 服务旨在让流程变得快速、高效且可靠。本指南将带您完成关键步骤,让您的应用在几分钟内上线,同时兼顾安全性与性能。

首先,让我们在 Stackhero 上创建一个 Node.js 服务。这将为您的应用部署打下基础,并让您享受 Stackhero 云托管的全部优势。

在开始之前,请确保您已准备好以下工具:

  1. Git: 您可以从 https://git-scm.com/downloads 下载。
  2. Windows 用户: 为获得更好的体验,建议使用 Windows Terminal,可在 Microsoft Store 获取。

主要的配置步骤是更新您的 SSH 公钥。该密钥允许 Stackhero 安全地访问您的代码仓库。

要查找您的公钥,可以在终端中运行以下任一命令:

cat ~/.ssh/id_rsa.pub

cat ~/.ssh/id_ed25519.pub

如果您还没有 SSH 密钥对,可以在 Linux 或 macOS 上运行 ssh-keygen,或在 Windows 上运行 ssh-keygen.exe 生成。

获得公钥后,登录 Stackhero 控制台,选择您的 Node.js 服务,进入配置部分,并将您的公钥粘贴到指定字段中。

Tip: 如果您希望 SSH 公钥对所有未来的服务都可用,可以全局设置。在 Stackhero 控制台点击右上角的头像,进入“您的个人资料”,然后粘贴您的 SSH 公钥。

为帮助您快速上手,我们提供了一个 Node.js 示例应用,展示了在 Stackhero 上的部署流程。您可以通过以下命令克隆该仓库:

git clone https://github.com/stackhero-io/nodejsGettingStarted.git stackhero-nodejs-getting-started
cd stackhero-nodejs-getting-started

通过 Git 在 Stackhero 上部署应用非常简单。在您的服务主页上,您会看到一条用于添加 Git 远程仓库的命令,大致如下:

git remote add stackhero ssh://stackhero@<XXXXXX>.stackhero-network.com:222/project.git

您可以将该命令复制粘贴到终端中以完成远程仓库的配置。

要部署,只需将代码推送到 Stackhero:

git push stackhero main

首次推送时,系统会提示您确认密钥指纹。只需输入“yes”继续。

几秒钟后,您的应用就会上线。您可以通过访问 Stackhero 控制台显示的网站 URL(例如 https://<XXXXXX>.stackhero-network.com)来验证应用状态。

就是这样,您的应用已经部署完成。

如需修改,只需更新 app.js 文件,提交并推送您的更改:

git add -A .
git commit -m "Update app.js"
git push stackhero main

如果您已经有一个 Node.js 应用,可以按照上述方式添加 Stackhero 远程仓库,然后用以下命令部署代码:

git push stackhero main

如果遇到如下错误:

error: failed to push some refs to '[...]'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
(e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

这意味着您的本地仓库与远程仓库不同步。您可以使用以下命令强制推送:

git push -f stackhero main

如果推送时看到如下信息:

error: src refspec main does not match any
error: failed to push some refs to 'ssh://<XXXXXX>.stackhero-network.com:222/project.git'

通常表示 main 分支不存在。您可以尝试推送 master 分支:

git push stackhero master

如果 Git 显示 "Everything up-to-date",但您的更改没有被部署,可能是因为您忘记提交更改。请尝试运行:

git add -A .
git commit -m "您的提交信息"
git push stackhero main

如果没有任何更改但仍想触发部署,可以强制创建一个空提交:

git commit --allow-empty -m "Force update"
git push stackhero main

如果您希望部署除 main 以外的分支(如 production),可以使用:

git push stackhero production:main

如果您使用标签并希望部署特定标签(如 v1.0),可以运行:

git push stackhero 'v1.0^{}:main'

^{} 确保推送与标签关联的提交。

如需部署特定提交,先用 git log 查找提交哈希,然后用以下命令部署:

git push -f stackhero <HASH>:main

您可能希望为生产和预发布(staging)环境分开部署。可通过以下命令将当前远程仓库从 stackhero 重命名为 stackhero-staging

git remote rename stackhero stackhero-staging

接着,在 Stackhero 控制台新建一个 Node.js 服务,并添加为 stackhero-production

git remote add stackhero-production ssh://stackhero@<XXXXXX>.stackhero-network.com:222/project.git

然后可以分别部署到不同环境:

git push stackhero-production main

git push stackhero-staging main

在 macOS 上,每次推送代码时可能会要求输入 SSH 密钥密码。为方便和安全,您可以通过以下命令将其保存到 macOS 钥匙串:

/usr/bin/ssh-add --apple-use-keychain ~/.ssh/id_rsa

此命令会保存您的密钥密码,后续部署时无需再次输入。

在使用预发布和生产环境时,安全管理密钥(如 token 或密码)非常重要。建议不要将敏感信息存储在代码仓库中,而是通过环境变量进行管理。

您可以在 Stackhero 控制台添加环境变量,并在 Node.js 代码中访问。例如,若定义了名为 mySecret 的变量,可在应用中这样访问:

process.env.mySecret

如果您的应用需要使用除 HTTP 以外的协议,可以在 Stackhero 控制台直接开放额外的 TCP 或 UDP 端口。只需指定公网入口端口、Node.js 服务上的目标端口以及协议类型(TCP 或 UDP)。

如需存储用户文件(如照片),建议使用对象存储(object storage)方案。这有助于在多个服务和实例间共享文件,并将代码与数据分离。我们推荐 MinIO,它兼容 Amazon S3 协议,速度快、易用且功能强大。

如果您更倾向于本地存储,可以使用 Node.js 实例自带的持久化存储,路径为 /persistent/storage/

注意: 请务必将数据存储在 /persistent/storage/ 文件夹内。

存储在该文件夹之外的数据,在实例重启或推送代码时可能会丢失。

当您部署新版本应用时,旧版本会在关闭前收到终止信号。这为您的应用提供了关闭数据库连接和其他服务的时间。

终止信号 SIGTERM 会发送到您的应用。您可以在代码中这样处理:

process.on('SIGTERM', () => {
  // 该日志会显示在 Stackhero 控制台的“日志”标签页
  console.info('SIGTERM signal received.');

  // 在此关闭数据库连接或其他服务
  // ...
});

默认情况下,Node.js 只使用单核和单线程。若要充分利用所有可用 CPU 核心,建议使用 Node.js 的 cluster API。官方文档见:https://nodejs.org/api/cluster.html

以下是一个简单示例,使用所有可用 CPU 创建 HTTP 服务器:

const cluster = require('cluster');
const http = require('http');
const cpusCount = require('os').cpus().length;

if (cluster.isMaster) {
  console.log(`Master ${process.pid} is running`);

  // Fork workers
  for (let i = 0; i < cpusCount; i++) {
    cluster.fork();
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`Worker ${worker.process.pid} died`);
  });
} else {
  // Workers 共享所有 TCP 连接,这里是 HTTP 服务器
  http.createServer((req, res) => {
    res.writeHead(200);
    res.end('hello world\n');
  }).listen(8000);

  console.log(`Worker ${process.pid} started`);
}