> 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-tw/getting-started/deploy-with-nodejs.md).

# 使用 Node.js 部署

直接使用 Node.js 與 pnpm 建置並執行 MyIP，並可選用 pm2 進行程序管理。

從原始碼執行是你想自訂建置時的正確選擇——更改品牌、加入工具，或設定任何 `VITE_*` 變數，而 Docker 的預建映像無法做到。

## 先決條件

| 需求             | 備註                                                                 |
| -------------- | ------------------------------------------------------------------ |
| **Node.js 24** | 官方 Docker 映像建立於 `node:24-alpine`。較舊的主要版本未經測試。                      |
| **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="your-account-id"
MAXMIND_LICENSE_KEY="your-license-key"
MAXMIND_AUTO_UPDATE="true"
ALLOWED_DOMAINS="myip.example.com"
```

{% endcode %}

其他變數皆為可選——請參閱 [環境變數](/developer/zh-tw/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 instrumentation 才能附加。若沒有 `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-tw/getting-started/maxmind-setup.md) ——包括手動 `.mmdb` 選項，這只適用於此部署路徑
* [反向代理與網域](/developer/zh-tw/getting-started/reverse-proxy-and-domains.md) ——TLS 與 `ALLOWED_DOMAINS`
* [開發環境](/developer/zh-tw/development/dev-environment.md) — `pnpm dev` 若你打算變更程式碼，則可使用熱重載
* [環境變數](/developer/zh-tw/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-tw/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.
