> For the complete documentation index, see [llms.txt](https://docs.ipcheck.ing/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ipcheck.ing/developer/zh/getting-started/deploy-with-nodejs.md).

# 使用 Node.js 部署

从源码运行是正确的选择，当你想自定义构建时——更改品牌标识、添加工具，或设置任何 `VITE_*` 变量，而 Docker 的预构建镜像做不到。

## 先决条件

| 要求             | 说明                                                                                |
| -------------- | --------------------------------------------------------------------------------- |
| **Node.js 24** | 官方 Docker 镜像基于 `node:24-alpine`. 较旧的主版本未经过测试。                                     |
| **pnpm**       | 仓库在以下位置固定了 pnpm 版本： `package.json` (`packageManager`）。使用 Corepack，这样你就能获得完全相同的版本。 |
| **git**        | 用于克隆和拉取更新。                                                                        |

{% tabs %}
{% tab title="Corepack（推荐）" %}
Corepack 随 Node.js 一起提供，并会自动提供固定的 pnpm 版本：

```bash
corepack enable
```

无需全局安装，也不会出现版本漂移。
{% endtab %}

{% tab title="npm" %}

```bash
npm install -g pnpm
```

可在任何地方使用，但你需要自行确保 pnpm 尽量接近固定版本。
{% endtab %}
{% endtabs %}

## 安装并构建

{% stepper %}
{% step %}

#### 克隆

```bash
git clone https://github.com/jason5ng32/MyIP.git
cd MyIP
```

{% endstep %}

{% step %}

#### 配置环境

```bash
cp .env.example .env
```

打开 `.env` 并至少填写 MaxMind 凭据：

{% code title=".env" %}

```bash
BACKEND_PORT="11966"
FRONTEND_PORT="18966"
MAXMIND_ACCOUNT_ID="你的账户 ID"
MAXMIND_LICENSE_KEY="你的许可密钥"
MAXMIND_AUTO_UPDATE="true"
ALLOWED_DOMAINS="myip.example.com"
```

{% endcode %}

其他变量都是可选的——参见 [环境变量](/developer/zh/reference/environment-variables.md).

{% hint style="warning" %}
在构建之前设置你的 `VITE_*` 变量 **之前** 进行构建。Vite 会在构建时读取它们并将其打包进 bundle；之后再修改它们就需要再次 `pnpm run build`.
{% endhint %}
{% endstep %}

{% step %}

#### 安装依赖

```bash
pnpm install
```

{% endstep %}

{% step %}

#### 构建前端

```bash
pnpm run build
```

这会生成 `dist/`，即前端服务器提供的静态 bundle。
{% endstep %}

{% step %}

#### 启动

```bash
pnpm start
```

打开 <http://localhost:18966>.
{% endstep %}
{% endstepper %}

## 这两个进程

`pnpm start` 在一个终端中运行应用的两部分（借助 `concurrently`):

| 进程 | 脚本                   | 默认端口                      | 角色                                                 |
| -- | -------------------- | ------------------------- | -------------------------------------------------- |
| 前端 | `frontend-server.js` | `18966` (`FRONTEND_PORT`) | 提供 `dist/` 使用优化的缓存头提供服务，处理 SPA 历史回退，并代理 `/api` 到后端 |
| 后端 | `backend-server.js`  | `11966` (`BACKEND_PORT`)  | Express API，以及 MaxMind 和 CAIDA 数据集更新器              |

用户只会与前端端口通信。后端不需要从宿主机外部可访问——前端会代理 `/api` 到 `http://localhost:<BACKEND_PORT>` 为它们处理。

你也可以分别运行它们：

```bash
pnpm run start-frontend
pnpm run start-backend
```

{% hint style="info" %}
`start-backend` 会用以下参数启动 Node： `--import ./sentry-instrument.js`。该标志必须在 Express 加载之前出现，Sentry 的 ESM 埋点才能附加上去。没有 `SENTRY_DSN_BACKEND` 时它不会产生任何作用，因此可以安全地在每个部署中保留。
{% endhint %}

## 在 pm2 下运行

`pnpm start` 会随着你的 shell 退出而结束。对于真正的部署，请使用仓库自带的 pm2 配置——它已经包含了正确的 Node 标志。

{% stepper %}
{% step %}

#### 安装 pm2

```bash
npm install -g pm2
```

{% endstep %}

{% step %}

#### 启动两个应用

```bash
pm2 start ecosystem.config.cjs
```

这会注册两个进程： `myip-backend` 以及 `myip-frontend`.
{% endstep %}

{% step %}

#### 重启后继续运行

```bash
pm2 save
pm2 startup
```

然后运行 pm2 输出的命令。
{% endstep %}
{% endstepper %}

有用的命令：

```bash
pm2 status
pm2 logs myip-backend
pm2 restart ecosystem.config.cjs
pm2 stop myip-frontend
```

{% hint style="info" %}
MaxMind 更新器会在下载前获取文件锁，因此在多个 pm2 实例下运行后端不会产生两个并发下载，也不会生成一个写到一半的数据库。
{% endhint %}

## 升级

```bash
git pull
pnpm install
pnpm run build
pm2 restart ecosystem.config.cjs
```

不要跳过 `pnpm run build` ——运行中的应用提供的是其中的内容， `dist/`，而不是你更新后的源码。

## 数据存放位置

数据集会下载到工作树中，并被排除在 git 之外：

* `common/maxmind-db/` — `GeoLite2-City.mmdb`, `GeoLite2-ASN.mmdb`，以及更新器状态和锁文件
* `common/as-org-db/`, `common/as-rel-db/` ——用于 ASN 组织名称和 ASN 连通图的 CAIDA 数据集

它们会在以下操作后保留 `git pull`，因此升级不会重新下载任何内容。

## 下一步

* [MaxMind 设置](/developer/zh/getting-started/maxmind-setup.md) ——包括手动 `.mmdb` 选项，它只在这条部署路径下有效
* [反向代理与域名](/developer/zh/getting-started/reverse-proxy-and-domains.md) ——TLS 和 `ALLOWED_DOMAINS`
* [开发环境](/developer/zh/development/dev-environment.md) — `pnpm dev` ，如果你打算修改代码，则使用热重载
* [环境变量](/developer/zh/reference/environment-variables.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.ipcheck.ing/developer/zh/getting-started/deploy-with-nodejs.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
