> 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-docker.md).

# 使用 Docker 部署

使用 docker run 或 Docker Compose 執行 MyIP，並讓你的實例保持最新。

Docker 是自架 MyIP 的建議方式。一個映像檔包含了應用程式的兩個部分：已建置的 Vue 前端與 Express 後端。

## 映像檔

| 登錄庫        | 映像檔                              |
| ---------- | -------------------------------- |
| Docker Hub | `jason5ng32/myip:latest`         |
| GitHub 套件  | `ghcr.io/jason5ng32/myip:latest` |

兩者都由相同的發佈版本建置，並針對以下平台發佈： `linux/amd64` 以及 `linux/arm64`。每個發佈版本也會另外附帶一個版本標籤，與 `:latest` 搭配使用——如果你想要可重現的升級，請鎖定其中一個。

## 執行它

{% tabs %}
{% tab title="docker run" %}
{% code title="docker run" %}

```bash
docker run -d \\
  -p 18966:18966 \\
  -e MAXMIND_ACCOUNT_ID="your-account-id" \\
  -e MAXMIND_LICENSE_KEY="your-license-key" \\
  -e MAXMIND_AUTO_UPDATE="true" \\
  -e ALLOWED_DOMAINS="myip.example.com" \
  -e CAIDA_AUTO_UPDATE="true" \
  -e GOOGLE_MAP_API_KEY="your-key" \
  -e IPINFO_API_KEY="your-key" \
  -e SECURITY_RATE_LIMIT="500" \
  -e LOG_LEVEL="info" \
  --name myip \\
  --restart always \\
  jason5ng32/myip:latest
```

{% endcode %}
{% endtab %}

{% tab title="Docker Compose" %}
{% code title="compose.yaml" %}

```yaml
services:
  myip:
    image: jason5ng32/myip:latest
    container_name: myip
    restart: always
    ports:
      - "18966:18966"
    environment:
      # 必要 — 請參閱 MaxMind 設定
      MAXMIND_ACCOUNT_ID: "your-account-id"
      MAXMIND_LICENSE_KEY: "your-license-key"
      MAXMIND_AUTO_UPDATE: "true"
      # 只要你透過網域提供 MyIP，就必須設定
      ALLOWED_DOMAINS: "myip.example.com"
      # 選用
      CAIDA_AUTO_UPDATE: "true"
      GOOGLE_MAP_API_KEY: "your-key"
      IPINFO_API_KEY: "your-key"
      SECURITY_RATE_LIMIT: "500"
      LOG_LEVEL: "info"
```

{% endcode %}

使用以下指令啟動： `docker compose up -d`.
{% endtab %}
{% endtabs %}

只有 `MAXMIND_ACCOUNT_ID`, `MAXMIND_LICENSE_KEY` 以及 `MAXMIND_AUTO_UPDATE` 是讓執行中的實例正常運作所需的。以上其他項目皆為選用——完整清單位於 [環境變數](/developer/zh-tw/reference/environment-variables.md).

{% hint style="info" %}
比起直接把密鑰寫在指令中，更建議使用 env 檔：把變數放在 `.env` 與你的 compose 檔案放在一起，Compose 就會自動讀取；或者傳入 `--env-file .env` 到 `docker run`.
{% endhint %}

## 連接埠

容器會執行兩個 Node 行程：

| 行程                             | 連接埠                       | 已發佈？ |
| ------------------------------ | ------------------------- | ---- |
| 前端 — 提供已建置的 SPA 並代理 `/api` 到後端 | `18966` (`FRONTEND_PORT`) | 是    |
| 後端 — Express API               | `11966` (`BACKEND_PORT`)  | 無    |

前端會代理 `/api` 到 `http://localhost:<BACKEND_PORT>` **在容器內**，所以你永遠不會公開後端連接埠。映像檔只會暴露 `18966` 。

若要讓 MyIP 透過不同的主機連接埠提供服務，請修改對應關係左側：

```bash
-p 8080:18966
```

如果你更改了 `FRONTEND_PORT`，請將對應關係右側一起改成相符值。

## `VITE_*` 這些變數在預先建置的映像檔中無法使用

名稱以 `VITE_` 開頭的變數會在 **建置時** 由 Vite 讀取並烘焙進 JavaScript bundle。發布的映像檔是在 CI 中建置的，沒有 `.env` 檔案，因此在執行時用 `-e` 傳入不會對前端產生任何影響。

這也適用於 `VITE_CURL_IPV4_DOMAIN`, `VITE_CURL_IPV6_DOMAIN`, `VITE_CURL_IPV64_DOMAIN`, `VITE_GOOGLE_ANALYTICS_ID`, `VITE_SITE_URL` 以及 `VITE_SENTRY_DSN_FRONTEND`。若要設定它們，你需要自行建置映像檔（或使用 [使用 Node.js 部署](/developer/zh-tw/getting-started/deploy-with-nodejs.md)):

```bash
git clone https://github.com/jason5ng32/MyIP.git
cd MyIP
cp .env.example .env   # 填入 VITE_* 的值
docker build -t myip-custom .
```

{% hint style="info" %}
其中有兩個例外，因為後端也會在 **執行時** 讀取它們： `VITE_SENTRY_DSN_FRONTEND` 決定 `/api/monitoring` tunnel 是否掛載（請參閱 [錯誤監控](/developer/zh-tw/configuration/error-monitoring.md)），且 `VITE_SITE_URL` 建置 `User-Agent` 送往上游供應商。如果你在建置時烘焙進去其中任何一個，請也在執行時把相同的值傳給容器。
{% endhint %}

## 資料存放位置

MyIP 會在執行時下載一些資料集。它們位於 **在容器內**，在 `/app/common/`:

| 路徑                        | 內容                                                        |
| ------------------------- | --------------------------------------------------------- |
| `/app/common/maxmind-db/` | `GeoLite2-City.mmdb`, `GeoLite2-ASN.mmdb`，另外還有更新程式的狀態與鎖定檔 |
| `/app/common/as-org-db/`  | CAIDA `as-org2info.txt` — ASN 組織名稱                        |
| `/app/common/as-rel-db/`  | CAIDA `as-rel2.txt` — ASN 連通圖                             |

這些內容都不會烘焙進映像檔中（MaxMind 的 GeoLite2 授權禁止再散佈），而且它們也都不是什麼珍貴資產——每次重新啟動都會重新下載。重建容器只代表 MyIP 會在第一次開機時再次抓取它們。

如果你不想在每次升級時都重新下載，請掛載卷：

{% code title="compose.yaml（節錄）" %}

```yaml
    volumes:
      - myip-maxmind:/app/common/maxmind-db
      - myip-asorg:/app/common/as-org-db
      - myip-asrel:/app/common/as-rel-db

volumes:
  myip-maxmind:
  myip-asorg:
  myip-asrel:
```

{% endcode %}

## 升級

{% tabs %}
{% tab title="docker run" %}

```bash
docker pull jason5ng32/myip:latest
docker stop myip && docker rm myip
# 然後重新執行你原本的 `docker run` 指令
```

{% endtab %}

{% tab title="Docker Compose" %}

```bash
docker compose pull
docker compose up -d
```

{% endtab %}
{% endtabs %}

在沒有卷的情況下升級後，第一次開機會重新下載 GeoLite2 和 CAIDA 資料集。這需要一點時間——後端會等到 MaxMind 載入完成後才開始監聽（最長上限 5 分鐘）。

## 查看狀態

```bash
docker logs -f myip
```

正常啟動時會顯示後端與前端的監聽，以及 MaxMind 的載入：

```
🚀 後端伺服器已在 http://localhost:11966 準備就緒
🚀 靜態檔案伺服器已在 http://localhost:18966 準備就緒
📦 MaxMind 資料庫已載入（啟動）
```

如果你看到 `❌ 在資料庫成功載入之前，MaxMind API 會回傳 503`，請前往 [MaxMind 設定](/developer/zh-tw/getting-started/maxmind-setup.md#troubleshooting).

## 後續步驟

* [MaxMind 設定](/developer/zh-tw/getting-started/maxmind-setup.md) — 必要憑證，以及自動更新器的運作方式
* [反向代理與網域](/developer/zh-tw/getting-started/reverse-proxy-and-domains.md) — TLS、Nginx/Caddy、 `ALLOWED_DOMAINS`
* [安全性選項](/developer/zh-tw/configuration/security-options.md) — 速率限制與濫用防護
* [記錄](/developer/zh-tw/configuration/logging.md) — 記錄層級、JSON 輸出、HTTP 請求日誌


---

# 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-docker.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.
