> 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/reference/environment-variables.md).

# 環境變數

MyIP 讀取的每個環境變數、其用途，以及預設值。

這是權威清單。下方每個變數都會在程式碼的某處被讀取（`process.env.*` 在伺服器上， `import.meta.env.*` 在瀏覽器捆綁包中）。未列於此處的內容都會被忽略。

複製 `.env.example` 至 `.env` 以開始：

{% code title="shell" %}

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

{% endcode %}

`dotenv` 會在第一次 `.env` 從儲存庫根目錄中的 `backend-server.js`, `frontend-server.js`, `common/logger.js`, `sentry-instrument.js`，以及 `vite.config.js`.

## 建置時 vs 執行時

MyIP 有兩種類型的變數，把它們混淆是最常見的部署錯誤。

| 類型  | 前綴      | 由…讀取                                                           | 生效時機     |
| --- | ------- | -------------------------------------------------------------- | -------- |
| 執行時 | 無前綴     | Node.js 程序（`backend-server.js`, `frontend-server.js`，API 處理程序） | 在程序重新啟動時 |
| 建置時 | `VITE_` | Vite，在…期間 `pnpm run build`                                     | 只有在重新建置後 |

`VITE_*` 值會 **被內嵌到 JavaScript 捆綁包中** 由 Vite 在建置時完成。應用程式在瀏覽器中執行時，不會從環境讀取它們。變更某個 `VITE_*` 變數並重新啟動伺服器都沒用——你必須重新建置。

{% hint style="warning" %}
**Docker 影響。** 官方的 `jason5ng32/myip:latest` 映像檔在 `pnpm run build` 映像建置時執行，當時沒有 `.env` 存在（`.env` 列於 `.dockerignore`）。傳入 `-e VITE_CURL_IPV4_DOMAIN=...` 給該映像檔，對 **前端捆綁包沒有任何影響**。若要在 Docker 中使用建置時變數，你必須在建置時讓這些值存在，並自行建置映像檔。
{% endhint %}

## 所有變數一覽

點擊變數名稱即可跳到完整說明。

| 變數                                                                        | 預設值            | 範圍       | 必要             |
| ------------------------------------------------------------------------- | -------------- | -------- | -------------- |
| [MAXMIND\_ACCOUNT\_ID](#maxmind-account-id)                               | `""`           | 執行時      | MaxMind 功能     |
| [MAXMIND\_LICENSE\_KEY](#maxmind-license-key)                             | `""`           | 執行時      | MaxMind 功能     |
| [MAXMIND\_AUTO\_UPDATE](#maxmind-auto-update)                             | `"false"`      | 執行時      | —              |
| [CAIDA\_AUTO\_UPDATE](#caida-auto-update)                                 | `"false"`      | 執行時      | —              |
| [BACKEND\_PORT](#backend-port)                                            | `11966`        | 執行時      | —              |
| [FRONTEND\_PORT](#frontend-port)                                          | `18966`        | 執行時      | —              |
| [ALLOWED\_DOMAINS](#allowed-domains)                                      | `""`           | 執行時      | 非 localhost 部署 |
| [SECURITY\_RATE\_LIMIT](#security-rate-limit)                             | `0`            | 執行時      | —              |
| [SECURITY\_DELAY\_AFTER](#security-delay-after)                           | `0`            | 執行時      | —              |
| [SECURITY\_BLACKLIST\_LOG\_FILE\_PATH](#security-blacklist-log-file-path) | `""`           | 執行時      | —              |
| [LOG\_LEVEL](#log-level)                                                  | `"info"`       | 執行時      | —              |
| [LOG\_FORMAT](#log-format)                                                | pretty         | 執行時      | —              |
| [LOG\_HTTP](#log-http)                                                    | `"false"`      | 執行時      | —              |
| [VITE\_SENTRY\_DSN\_FRONTEND](#vite-sentry-dsn-frontend)                  | `""`           | 建置 + 執行時 | —              |
| [SENTRY\_DSN\_BACKEND](#sentry-dsn-backend)                               | `""`           | 執行時      | —              |
| [SENTRY\_ENVIRONMENT](#sentry-environment)                                | `"production"` | 執行時 + 建置 | —              |
| [SENTRY\_ORG](#sentry-org)                                                | `""`           | 建置       | —              |
| [SENTRY\_PROJECT\_FRONTEND](#sentry-project-frontend)                     | `""`           | 建置       | —              |
| [SENTRY\_AUTH\_TOKEN](#sentry-auth-token)                                 | `""`           | 建置       | —              |
| [GOOGLE\_MAP\_API\_KEY](#google-map-api-key)                              | `""`           | 執行時      | —              |
| [IPINFO\_API\_KEY](#ipinfo-api-key)                                       | `""`           | 執行時      | —              |
| [IPAPIIS\_API\_KEY](#ipapiis-api-key)                                     | `""`           | 執行時      | —              |
| [IP2LOCATION\_API\_KEY](#ip2location-api-key)                             | `""`           | 執行時      | —              |
| [CLOUDFLARE\_API\_KEY](#cloudflare-api-key)                               | `""`           | 執行時      | 報告分享           |
| [MAC\_LOOKUP\_API\_KEY](#mac-lookup-api-key)                              | `""`           | 執行時      | —              |
| [RIPESTAT\_SOURCE\_APP](#ripestat-source-app)                             | `"myip"`       | 執行時      | —              |
| [CLOUDFLARE\_ACCOUNT\_ID](#cloudflare-account-id)                         | `""`           | 執行時      | 報告分享           |
| [CLOUDFLARE\_KV\_NAMESPACE\_ID](#cloudflare-kv-namespace-id)              | `""`           | 執行時      | 報告分享           |
| [VITE\_CURL\_IPV4\_DOMAIN](#vite-curl-ipv4-domain)                        | `""`           | 建置       | 三者全有或全無        |
| [VITE\_CURL\_IPV6\_DOMAIN](#vite-curl-ipv6-domain)                        | `""`           | 建置       | 三者全有或全無        |
| [VITE\_CURL\_IPV64\_DOMAIN](#vite-curl-ipv64-domain)                      | `""`           | 建置       | 三者全有或全無        |
| [VITE\_SITE\_URL](#vite-site-url)                                         | `""`           | 建置 + 執行時 | —              |
| [VITE\_DOCS\_URL](#vite-docs-url)                                         | `""`           | 建置       | —              |
| [VITE\_PULSE\_BEACON\_URL](#vite-pulse-beacon-url)                        | `""`           | 建置       | —              |
| [VITE\_GOOGLE\_ANALYTICS\_ID](#vite-google-analytics-id)                  | `""`           | 建置       | —              |
| [VITE\_INVISIBILITY\_TEST\_KEY](#vite-invisibility-test-key)              | `""`           | 建置       | —              |
| [IPCHECKING\_API\_KEY](#ipchecking-api-key)                               | `""`           | 執行時      | —              |
| [IPCHECKING\_API\_ENDPOINT](#ipchecking-api-endpoint)                     | `""`           | 執行時      | —              |

## 必要——MaxMind 與離線資料集

MyIP 自身的 IP 地理定位來源，以及整個 UI 中的國家徽章，都是由本機的 MaxMind GeoLite2 資料庫提供。若沒有它們， `GET /api/maxmind` 會回應 **503**。參見 [MaxMind 設定](/developer/zh-tw/getting-started/maxmind-setup.md).

#### `MAXMIND_ACCOUNT_ID` <a href="#maxmind-account-id" id="maxmind-account-id"></a>

預設值 `""` · 執行時 · **MaxMind 功能所必需**

MaxMind 帳號 ID。搭配 `MAXMIND_LICENSE_KEY` 在下載 GeoLite2 資料庫時，作為 HTTP Basic 憑證使用。

#### `MAXMIND_LICENSE_KEY` <a href="#maxmind-license-key" id="maxmind-license-key"></a>

預設值 `""` · 執行時 · **MaxMind 功能所必需**

MaxMind 授權金鑰，從你帳號的「管理授權金鑰」頁面產生。

#### `MAXMIND_AUTO_UPDATE` <a href="#maxmind-auto-update" id="maxmind-auto-update"></a>

預設值 `"false"` · 執行時 · 選填

`"true"` 啟動定期更新器：在啟動 60 秒後首次檢查，之後每 24 小時一次。

#### `CAIDA_AUTO_UPDATE` <a href="#caida-auto-update" id="caida-auto-update"></a>

預設值 `"false"` · 執行時 · 選填

`"true"` 每 24 小時重新整理 CAIDA 資料集——as2org 用於 ASN 組織名稱，as-rel2 用於 ASN 連通圖。

{% hint style="info" %}
`MAXMIND_AUTO_UPDATE` 控制 **只有定期排程器**。啟動時「若資料庫缺失就下載」的流程不會查詢它——如果有有效憑證，資料庫仍會在首次啟動時抓取（上限為 5 分鐘逾時）。同樣地， `CAIDA_AUTO_UPDATE=false` 仍會讓缺少的 CAIDA 快照在啟動時下載；它只會停用每日更新。
{% endhint %}

後端絕不會因為缺少資料庫而拒絕啟動。它只會記錄警告，仍然繼續監聽。

## 連接埠

#### `BACKEND_PORT` <a href="#backend-port" id="backend-port"></a>

預設值 `11966` · 執行時 · 選填

Express API 伺服器綁定的連接埠。也會被 `frontend-server.js` 使用，並作為 Vite 開發伺服器的 `/api` 代理目標。

#### `FRONTEND_PORT` <a href="#frontend-port" id="frontend-port"></a>

預設值 `18966` · 執行時 · 選填

生產環境中靜態/SPA 伺服器綁定的連接埠，以及開發環境中的 Vite 開發伺服器連接埠。

兩者都會以 `parseInt(..., 10)`。Dockerfile `EXPOSE`s `18966` 只會對外暴露；後端連接埠仍保持在容器內部。

## 安全性

請參閱 [安全選項](/developer/zh-tw/configuration/security-options.md) 和 [反向代理與網域](/developer/zh-tw/getting-started/reverse-proxy-and-domains.md).

#### `ALLOWED_DOMAINS` <a href="#allowed-domains" id="allowed-domains"></a>

預設值 `""` · 執行時 · **對非 localhost 部署而言實際上是必要的**

以逗號分隔的主機名稱允許清單，用於全域 `Referer` 的閘門，適用於 `/api/*`. `localhost` 一律允許；其他所有項目都必須列在這裡，否則你網域的每個 API 呼叫都會得到 403。

#### `SECURITY_RATE_LIMIT` <a href="#security-rate-limit" id="security-rate-limit"></a>

預設值 `0` （已停用）· 執行時 · 選填

最大 `/api/*` 每個用戶端 IP 每 **20 分鐘** 視窗內的請求數量。超過上限 → `429 {"message":"請求過多"}`. `0` 或未設定會完全停用限制器。

#### `SECURITY_DELAY_AFTER` <a href="#security-delay-after" id="security-delay-after"></a>

預設值 `0` （已停用）· 執行時 · 選填

在超過這麼多 `/api/*` 同一 IP 在 **60 分鐘** 視窗內的請求之後，每個後續請求都會延遲 `hits × 400 ms`. `0` 或未設定會停用它。

#### `SECURITY_BLACKLIST_LOG_FILE_PATH` <a href="#security-blacklist-log-file-path" id="security-blacklist-log-file-path"></a>

預設值 `""` · 執行時 · 選填

可選的磁碟記錄，記錄被限速的 IP，例如 `"logs/blacklist-ip.log"`，以儲存庫根目錄為基準解析。空白表示不會寫入任何檔案； `IP 被限速` 警告都會被記錄。

行為說明，直接來自程式碼：

* **Referer 比對是精確的主機名稱比對。** `ALLOWED_DOMAINS=example.com` 會 **不會** 允許 `sub.example.com` ——請列出你提供服務的每一個主機名稱。
* 帶有 **沒有** `Referer` 標頭的請求會被拒絕，並回傳 `403 {"error":"你在做什麼？"}`。帶有不允許的 `Referer` 會得到 `403 {"error":"存取遭拒"}`.
* 兩個限制器都 **略過** `/api/monitoring`；Sentry 隧道有自己的固定限制器（每個 IP 每 20 分鐘 600 個請求）。
* 速率限制器只會在進入受限狀態時記錄日誌，不會在每個被封鎖的請求都記錄。
* `app.set('trust proxy', 1)` 已設定，因此前方只應放置一個受信任的代理。用戶端 IP 會依序從 `cf-connecting-ip`，接著從 `x-forwarded-for` （第一個項目），再接著從 `cf-connecting-ipv6`，最後從 socket 位址取得。

## 記錄

請參閱 [記錄](/developer/zh-tw/configuration/logging.md).

#### `LOG_LEVEL` <a href="#log-level" id="log-level"></a>

預設值 `"info"` · 執行時 · 選填

最低 pino 層級： `debug` / `info` / `warn` / `錯誤`。較低層級的訊息會被捨棄——包括同步到 Sentry 的部分。

#### `LOG_FORMAT` <a href="#log-format" id="log-format"></a>

預設 pretty · 執行時 · 選填

`"json"` 為日誌傳送器每行輸出一筆 JSON 事件。任何其他值（或未設定）都會使用彩色的 `pino-pretty` 輸出。

#### `LOG_HTTP` <a href="#log-http" id="log-http"></a>

預設值 `"false"` · 執行時 · 選填

`"true"` 掛載 `pino-http` 於 `/api/*`：每個請求一行，包含方法、URL 與狀態。掛載在速率限制器之前，因此 429 也會被記錄。

## Sentry

全部皆為選填。若未設定 DSN，則不會載入任何 Sentry SDK，捆綁包中也不會包含任何 Sentry 程式碼。請參閱 [錯誤監控（Sentry）](/developer/zh-tw/configuration/error-monitoring.md).

#### `VITE_SENTRY_DSN_FRONTEND` <a href="#vite-sentry-dsn-frontend" id="vite-sentry-dsn-frontend"></a>

預設值 `""` · 建置 **和** 執行時 · 選填

前端 DSN，在建置時被烘焙進捆綁包中。 **執行時也會讀取** 由 `backend-server.js` — `POST /api/monitoring` （第一方 envelope 隧道）只有在伺服器程序上設定此值時才會掛載。

#### `SENTRY_DSN_BACKEND` <a href="#sentry-dsn-backend" id="sentry-dsn-backend"></a>

預設值 `""` · 執行時 · 選填

後端 DSN，由 `sentry-instrument.js` （透過 `node --import`載入），以及由 `common/logger.js`，它會鏡射 `warn+` 行到 Sentry Logs，並將 `error+` 提升為 Issues。

#### `SENTRY_ENVIRONMENT` <a href="#sentry-environment" id="sentry-environment"></a>

預設值 `"production"` · 執行時 + 建置 · 選填

後端 Sentry 事件的環境標籤。也會控制 source map 上傳：只有在此值未設定或 `production`.

#### `SENTRY_ORG` <a href="#sentry-org" id="sentry-org"></a>

預設值 `""` · 建置 · 選填

用於建置時 source map 上傳的 Sentry 組織 slug。

#### `SENTRY_PROJECT_FRONTEND` <a href="#sentry-project-frontend" id="sentry-project-frontend"></a>

預設值 `""` · 建置 · 選填

用於建置時 source map 上傳的 Sentry 專案 slug。

#### `SENTRY_AUTH_TOKEN` <a href="#sentry-auth-token" id="sentry-auth-token"></a>

預設值 `""` · 建置 · 選填

用於建置時 source map 上傳的驗證權杖。未設定時，Vite 完全不會產生 source map，因此它們永遠不會公開由 `dist/`提供。建置時祕密——絕不會暴露給瀏覽器。

{% hint style="warning" %}
如果你自行建置 Docker 映像檔並將 `VITE_SENTRY_DSN_FRONTEND` 也內嵌進去，請在執行時也將相同的值傳給容器。否則捆綁包會將 envelope 傳送到 `/api/monitoring`，這是後端從未掛載的路由，而每份報告都會回傳 404。
{% endhint %}

## 選填 API 金鑰

每個金鑰可解鎖一個 IP 資料來源或工具。 `GET /api/configs` 會回報哪些項目已設定——只回傳布林值，絕不回傳實際值——而前端會在缺少金鑰時隱藏對應的 UI。請參閱 [選填 API 金鑰](/developer/zh-tw/configuration/optional-api-keys.md) 和 [IP 資料來源](/developer/zh-tw/architecture/ip-data-sources.md).

#### `GOOGLE_MAP_API_KEY` <a href="#google-map-api-key" id="google-map-api-key"></a>

預設值 `""` · 執行時 · 選填

Google Static Maps 金鑰，由 `/api/map`。可接受以逗號分隔的清單；每個請求會隨機挑選一把金鑰。

#### `IPINFO_API_KEY` <a href="#ipinfo-api-key" id="ipinfo-api-key"></a>

預設值 `""` · 執行時 · 選填

ipinfo.io 權杖，用於 `/api/ipinfo`。支援逗號分隔清單。即使沒有金鑰，端點仍可運作，但速率為 ipinfo.io 的匿名限制。

#### `IPAPIIS_API_KEY` <a href="#ipapiis-api-key" id="ipapiis-api-key"></a>

預設值 `""` · 執行時 · 選填

api.ipapi.is 金鑰，用於 `/api/ipapiis`。支援逗號分隔清單。

#### `IP2LOCATION_API_KEY` <a href="#ip2location-api-key" id="ip2location-api-key"></a>

預設值 `""` · 執行時 · 選填

ip2location.io 金鑰，用於 `/api/ip2location`。支援逗號分隔清單。

#### `CLOUDFLARE_API_KEY` <a href="#cloudflare-api-key" id="cloudflare-api-key"></a>

預設值 `""` · 執行時 · **報告分享所必需**

具有兩種角色的 Cloudflare API 權杖：作為 Cloudflare Radar 的 Bearer 權杖（所有 `?view=` 的 `/api/cfradar` ——ASN 個人資料、國家線上活動熱圖與故障資訊流都共用相同的 Radar 讀取權限，因此沒有任何 view 需要額外的權杖範圍），以及——搭配 [報告分享](#report-sharing-cloudflare-kv) ——用於將可分享報告儲存在 Workers KV 的憑證。KV 角色另外還需要 **Workers KV 儲存：編輯** 權限。設定後也會顯示 **Earth Online** 導覽列中的面板——僅故障資訊流，除非 [`VITE_PULSE_BEACON_URL`](#vite-pulse-beacon-url) 另外加入社交部分。

#### `MAC_LOOKUP_API_KEY` <a href="#mac-lookup-api-key" id="mac-lookup-api-key"></a>

預設值 `""` · 執行時 · 選填

maclookup.app 金鑰，用於 `/api/macchecker`。沒有它端點也能運作，但使用匿名速率。

#### `RIPESTAT_SOURCE_APP` <a href="#ripestat-source-app" id="ripestat-source-app"></a>

預設值 `"myip"` · 執行時 · 選填

傳送給 RIPEstat 的值，作為 `sourceapp` 查詢參數，因此 RIPE 可以將流量歸因於你的部署。

{% hint style="info" %}
`/api/ipapiis` 和 `/api/ip2location` 透過呼叫 `.split(',')` 對金鑰直接分割，且沒有空值檢查。當金鑰未設定時，處理程序會拋出例外並回傳 500。前端在該狀態下不會呼叫它們，因為 `/api/configs` 會將來源回報為不可用，而 UI 會將其隱藏。
{% endhint %}

## 報告分享（Cloudflare KV） <a href="#report-sharing-cloudflare-kv" id="report-sharing-cloudflare-kv"></a>

可分享的診斷報告會透過 REST API 儲存在 Cloudflare Workers KV 中。 **三者全都** 變數—— [`CLOUDFLARE_API_KEY`](#cloudflare-api-key) 加上下方兩個——都必須設定，否則 `POST /api/report` 和 `GET /api/report/:id` 兩者都會回應 `503 {"error":"Report sharing is not configured"}` 和 `/api/configs` 報告 `reportSharing: false`，這會隱藏分享 UI。

#### `CLOUDFLARE_ACCOUNT_ID` <a href="#cloudflare-account-id" id="cloudflare-account-id"></a>

預設值 `""` · 執行時 · **報告分享所必需**

擁有該 KV 命名空間的 Cloudflare 帳號 ID。

#### `CLOUDFLARE_KV_NAMESPACE_ID` <a href="#cloudflare-kv-namespace-id" id="cloudflare-kv-namespace-id"></a>

預設值 `""` · 執行時 · **報告分享所必需**

該命名空間的 **十六進位 ID** ，來自儀表板——不是顯示名稱。

報告限制，來自 `common/report-schema.js`：可選保留期限為 1、3 或 7 天（其他值都會強制降為 1 天），而儲存的 payload 上限為 256 KB（`413` 超過此上限）。Express JSON body 限制為 500 KB，刻意高於報告上限。

## Curl API

#### `VITE_CURL_IPV4_DOMAIN` <a href="#vite-curl-ipv4-domain" id="vite-curl-ipv4-domain"></a>

預設值 `""` · 建置 · 三者全有或全無

在 curl API 卡片中顯示的僅 IPv4 主機名稱。

#### `VITE_CURL_IPV6_DOMAIN` <a href="#vite-curl-ipv6-domain" id="vite-curl-ipv6-domain"></a>

預設值 `""` · 建置 · 三者全有或全無

僅 IPv6 主機名稱。

#### `VITE_CURL_IPV64_DOMAIN` <a href="#vite-curl-ipv64-domain" id="vite-curl-ipv64-domain"></a>

預設值 `""` · 建置 · 三者全有或全無

雙棧主機名稱。

{% hint style="warning" %}
curl API 卡片只有在以下情況才會渲染： **三者全都** 皆非空白—— `curlDomainsHadSet` 位於 `frontend/store.js` 將它們以 AND 方式合併。設定一個或兩個都不會顯示任何內容。而且因為這些是 `VITE_*`，它們必須在建置時存在。
{% endhint %}

這些變數只提供顯示給使用者的主機名稱。MyIP 本身不提供那些端點——你需要把 DNS 記錄指向你自行執行的任何純文字 IP 回應服務。

## 其他

#### `VITE_SITE_URL` <a href="#vite-site-url" id="vite-site-url"></a>

預設值 `""` · 建置 **和** 執行時 · 選填

你的部署絕對來源網址。於建置時會填入 `__SITE_URL__` 位於 `index.html` （canonical / OG 標籤）；當為空時，整個標記區塊會被移除。於執行時它會成為上游的最後一段 `User-Agent` (`MyIP/v7.2.0/https://example.com`），因此分支版本會向上游 API 表明自己的身分，而不是冒充 ipcheck.ing。結尾斜線會被去除。

#### `VITE_DOCS_URL` <a href="#vite-docs-url" id="vite-docs-url"></a>

預設值 `""` · 建置 · 選填

支援應用程式內文件助理以及頁腳中「說明中心」連結的 GitBook 文件網站來源，例如 `https://docs.ipcheck.ing`。結尾斜線會被去除；嵌入腳本會從 `<origin>/~gitbook/embed/script.js` 首次使用時載入，絕不在頁面載入時載入。

為空時，助理與頁腳連結都不會被納入捆綁包。導覽列入口還需要 canonical 部署——請參閱 [與 IPCheck.ing 綁定的功能](/developer/zh-tw/configuration/features-tied-to-ipcheck-ing.md).

#### `VITE_PULSE_BEACON_URL` <a href="#vite-pulse-beacon-url" id="vite-pulse-beacon-url"></a>

預設值 `""` · 建置 · 選填

社交部分背後的聚合服務完整網址，用於 **Earth Online**，也就是導覽列中的即時訪客面板。結尾斜線會被去除；前端會附加 `/beacon`, `/status` 和 `/stats` 到其後。

當為空——在…中的預設值 `.env.example` ——社交部分就會關閉：沒有狀態撰寫器、沒有 Latest 動態、沒有訪客地圖、沒有訪客 beacon、隱私頁面也不會有相關區塊。面板本身不依賴這個變數：其全域故障資訊流是透過 `GET /api/cfradar?view=outages`，因此導覽列入口和 <kbd>p</kbd> 捷徑仍會在任何具有 [`CLOUDFLARE_API_KEY`](#cloudflare-api-key)。聚合服務不是開源的，所以將此值設為你自己的相容後端以外的任何內容都沒有用。請參閱 [與 IPCheck.ing 綁定的功能](/developer/zh-tw/configuration/features-tied-to-ipcheck-ing.md).

#### `VITE_GOOGLE_ANALYTICS_ID` <a href="#vite-google-analytics-id" id="vite-google-analytics-id"></a>

預設值 `""` · 建置 · 選填

Google Analytics 測量 ID。當為空時， `gtag.js` 絕不會被注入，且隱私頁面會回報分析功能已停用。自架者應保持空白。

#### `VITE_INVISIBILITY_TEST_KEY` <a href="#vite-invisibility-test-key" id="vite-invisibility-test-key"></a>

預設值 `""` · 建置 · 選填

傳入作為 `pdKey` 傳給 Invisibility Test 使用的第三方代理偵測腳本。只有在同時具備 `IPCHECKING_API_KEY`。未出現在 `.env.example`.

#### `IPCHECKING_API_KEY` <a href="#ipchecking-api-key" id="ipchecking-api-key"></a>

預設值 `""` · 執行時 · 選填

私有 IPCheck.ing 伴隨 API 的 API 金鑰。控制 `/api/ipchecking`, `/api/getuserinfo`, `PUT /api/updateuserachievement`, `/api/invisibility`, `/api/dnsleaktest/session/:token`，以及 `POST /api/persona/evaluate` ——沒有它那些路由會回傳 `500 {"error":"缺少 API 金鑰"}`。也會顯示為 `ipChecking` 位於 `/api/configs`。不在 `.env.example`.

#### `IPCHECKING_API_ENDPOINT` <a href="#ipchecking-api-endpoint" id="ipchecking-api-endpoint"></a>

預設值 `""` · 執行時 · 選填

該伴隨 API 的基礎 URL，與 `IPCHECKING_API_KEY`。不在 `.env.example`.

{% hint style="info" %}
`IPCHECKING_API_KEY` / `IPCHECKING_API_ENDPOINT` 和 `VITE_INVISIBILITY_TEST_KEY` 屬於閉源的伴隨服務。自架的分支無法取得它們，而它們所控制的功能會在非-`ipcheck.ing` 部署中隱藏。請參閱 [與 IPCheck.ing 綁定的功能](/developer/zh-tw/configuration/features-tied-to-ipcheck-ing.md).
{% endhint %}

## 舊別名

有兩個變數已重新命名。舊拼法仍會作為後備讀取，因此現有部署在升級時不會失去功能。請優先使用新名稱。

| 舊名稱                | 目前名稱                 | 讀取位置                                                          |
| ------------------ | -------------------- | ------------------------------------------------------------- |
| `IPINFO_API_TOKEN` | `IPINFO_API_KEY`     | `api/ipinfo-io.js`, `api/configs.js`                          |
| `CLOUDFLARE_API`   | `CLOUDFLARE_API_KEY` | `common/cf-radar.js`, `api/share-report.js`, `api/configs.js` |

解析順序為 `NEW || OLD` — 如果兩者都已設定，則新名稱優先。

## 最小可運作設定

{% code title=".env" %}

```bash
BACKEND_PORT=11966
FRONTEND_PORT=18966
ALLOWED_DOMAINS="myip.example.com"
MAXMIND_ACCOUNT_ID="your-account-id"
MAXMIND_LICENSE_KEY="your-license-key"
MAXMIND_AUTO_UPDATE="true"
```

{% endcode %}

其他所有項目皆為可選，且只會新增資料來源或工具。請參閱 [快速入門](/developer/zh-tw/getting-started/quickstart.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/reference/environment-variables.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.
