> For the complete documentation index, see [llms.txt](https://docs.decentraland.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.decentraland.org/contributor/contributor-zh/jiao-cheng/getting-started.md).

# 入门

有没有好奇过 Decentraland Catalyst 节点是如何工作的？有没有想过自己运行一个节点，却不知道该从哪里开始？你是否正在为 Decentraland 制作内容，并且发现要在生产服务器上完成整个开发和测试周期很困难？

如果你有这样的经历，别担心了。本教程将帮助你规划流程，弄清楚需要做哪些决策，然后一步步指导你启动服务器。另外，万一某些步骤没有按计划进行，文末还有一个故障排查部分，列出了一些最常见的问题以及如何修复。

准备好了吗？开始动手吧。

### 硬件要求

Decentraland 基金会的服务器部署在 Amazon AWS 上，使用 `t2.xlarge` 实例。因此，虽然这些服务器是面向公众使用的，但你自己的服务器也许可以使用更小的配置，具体取决于预期用途。

一个 AWS EC2 `t2.xlarge` 具有以下硬件：

* 4 个 vCPU。
* 16 GB RAM

至于文件存储 + 数据库存储，一个容量为 2 TB 的 SSD / HDD 应该绰绰有余。撰写本文时，基金会服务器在所有存储上总共只使用了略高于 1 TB 的空间。

### 软件前提条件

运行 catalyst-owner 需要以下内容：

* Linux / MacOS 操作系统
* Docker / docker-compose
* Git
* LiveKit 集群

### 在开始之前可以考虑的一些选项

* 你希望你的节点在互联网上公开暴露吗？如果是，你将需要一个可从互联网访问的实例，以及一个用于连接它的公网 URL。
* 该节点是否将用于场景、可穿戴物品等内容的开发？在这种情况下，硬件规格可以小得多，因为访问它的可能只有一两个人，而不是成百上千的用户。
* 你想同步所有实体类型吗？如果你是用它来开发场景，那么你可能不需要同步所有内容类型，因为 profile 会占用大量时间、带宽，最重要的是磁盘空间，而且对你的目标也没有帮助。

### LiveKit

Catalyst 的 Comms 服务需要一个外部 LiveKit 集群来协调玩家之间的通信。为此，有两个选择：使用 LiveKit Cloud 账户，或者运行你自己的 LiveKit 集群。

建议配置 [LiveKit Cloud 账户](https://cloud.livekit.io/) 它提供一个免费套餐，可管理 100 个用户，或者根据流量付费使用该服务。这个方案更简单，因为它不需要额外预置基础设施，而且服务本身可以管理扩缩容。否则就需要预置一个 LiveKit 集群。LiveKit 的文档写得非常好：

* [部署](https://docs.livekit.io/oss/deployment/)
* [分布式部署](https://docs.livekit.io/oss/deployment/distributed/)

*如果你想深入了解支持基于 LiveKit 传输的通信所需的技术细节，请查看* [*ADR-70 新通信架构*](https://adr.decentraland.org/adr/ADR-70)*.*

### 分步指南

首先要做的是克隆 [catalyst-owner](https://github.com/decentraland/catalyst-owner) GitHub 仓库

```bash
> git clone https://github.com/decentraland/catalyst-owner.git
正在克隆到 'catalyst-owner'...
remote: 正在枚举对象：2392，完成。
remote: 正在计数对象：100% (602/602)，完成。
remote: 正在压缩对象：100% (168/168)，完成。
remote: 总计 2392（delta 506），重复使用 481（delta 430），包重复使用 1790
接收对象中：100% (2392/2392)，926.05 KiB | 1.09 MiB/s，完成。
解析增量中：100% (1257/1257)，完成。
> cd catalyst-owner
```

完成后，就该为节点配置环境变量，并按需要进行修改了。

```bash
# 在 /catalyst-owner 文件夹中
> cp .env.example .env
> cp .env-advanced.example .env-advanced
```

现在请使用你喜欢的文本编辑器，对这些文件进行必要的修改。例如，设置 `EMAIL` 环境变量并填写有效邮箱是必需的，这样你才能收到关于 Certbot 证书过期的更新通知。

还可能需要为 `CATALYST_URL` 设置你自己的值，尤其是当你的服务器将公开暴露在互联网上时。若在本地机器上使用，默认的 `http://localhost` 就可以。

**Comms 服务**

一旦 LiveKit 集群可用，你就需要为 Comms 服务设置特定的 LiveKit 变量，例如：

```
LIVEKIT_HOST=wss://livekit-1.mydomain.org
LIVEKIT_API_KEY=API-JjHuvM
LIVEKIT_API_SECRET=J7YSHmNzkNCEfT2
ROOM_PREFIX=my-prefix
```

该 `ROOM_PREFIX` 变量是可选的，可以配置为标识 Catalyst 创建的 LiveKit 房间。如果有多个 Catalyst 使用同一个 LiveKit 集群，这会很有用。

**内容服务器**

有一个名为 `CONTENT_SERVER_STORAGE` 的变量，用于定义内容服务器将使用的本地文件夹来存储数据。其默认值为 `CONTENT_SERVER_STORAGE=./storage`。你可以更改这个值，将文件存到别处，或者至少确保引用的文件夹存在。你可能需要像这样创建它：

```bash
# 在 /catalyst-owner 文件夹中，或者在 CONTENT_SERVER_STORAGE 指向的任何位置
> mkdir storage
```

还有另一个有趣的变量 `SYNC_IGNORED_ENTITY_TYPES` 它允许在同步过程中忽略某些实体类型。如果你要把 Catalyst 服务器用于开发，也许不需要同步所有内容类型。你可以设置环境变量 `SYNC_IGNORED_ENTITY_TYPES="profile,store"` 这样就只会从 DAO 服务器拉取场景和可穿戴物品。这将节省服务器大量时间、带宽和磁盘存储。

> 💡 如需更完整的支持环境变量列表，请查看下面的 [环境变量](#environment-variables) 部分。

#### 启动 Catalyst 节点

设置好所有环境变量后，就可以启动节点了。这应该很简单，只需在根目录运行 `init.sh` 脚本即可。

```bash
# 在 /catalyst-owner 文件夹中

> ./init.sh
## 正在加载环境变量... [ 完成 ]
[ 完成 ]
## 正在检查是否配置了邮箱... [ 完成 ]
## 正在检查是否配置了存储... [ 完成 ]
## 正在检查是否配置了 catalyst url... [ 完成 ]
 警告：你运行的不是 Catalyst Content 和 Catalyst Lambdas 节点的最新镜像。
 警告：你运行的不是 Catalyst Archipelago 节点的最新镜像。
 警告：你运行的不是 Catalyst Explorer BFF 节点的最新镜像。
 - DOCKER_TAG:               45a5154f11b53d55aadfdf7f958e2fce6a964824
 - LIGHTHOUSE_DOCKER_TAG:    latest
 - CATALYST_URL:             http://localhost
 - CONTENT_SERVER_STORAGE:   ./storage
 - EMAIL:                    a@a.com
 - ETH_NETWORK:              mainnet
 - REGENERATE:               0

5 秒后启动...
45a5154f11b53d55aadfdf7f958e2fce6a964824：正在从 decentraland/catalyst-content 拉取
摘要：sha256:d6c2981c57cb9367fdb3228d15b07e4d26e62c902944115937de24ecd3ab6aac
状态：镜像已是最新，适用于 decentraland/catalyst-content:45a5154f11b53d55aadfdf7f958e2fce6a964824
docker.io/decentraland/catalyst-content:45a5154f11b53d55aadfdf7f958e2fce6a964824
45a5154f11b53d55aadfdf7f958e2fce6a964824：正在从 decentraland/catalyst-lambdas 拉取
摘要：sha256:5605812dd29316afc32e561d2a2ce1311f164f07ef3cd99a1cd60727518636e5
状态：镜像已是最新，适用于 decentraland/catalyst-lambdas:45a5154f11b53d55aadfdf7f958e2fce6a964824
docker.io/decentraland/catalyst-lambdas:45a5154f11b53d55aadfdf7f958e2fce6a964824
latest：正在从 decentraland/catalyst-lighthouse 拉取
摘要：sha256:fedc10b714823909f0a1c17955eed2f22a02e4f784090848d3253ef734e410d4
状态：镜像已是最新，适用于 decentraland/catalyst-lighthouse:latest
docker.io/decentraland/catalyst-lighthouse:latest
latest：正在从 decentraland/archipelago-service 拉取
摘要：sha256:e2c1d6fa96a5cfbbf6fb37e3840c0724fb5abeef8c366025a28fab3ad33d6480
状态：镜像已是最新，适用于 quay.io/decentraland/archipelago-service:latest
quay.io/decentraland/archipelago-service:latest
latest：正在从 decentraland/explorer-bff 拉取
摘要：sha256:fa9e305c44972a8613b01f4cd573d6fb84b0fb03ce953a506fbb06053202913c
状态：镜像已是最新，适用于 quay.io/decentraland/explorer-bff:latest
quay.io/decentraland/explorer-bff:latest
停止 nginx ... 完成
## 因为 CATALYST_URL 设置为 http://localhost，所以使用 HTTP
## 正在替换 nginx 服务器文件中的 $katalyst_host 值... [ 完成 ]
## 正在重启容器...
使用默认驱动创建网络 "catalyst-owner_default"
创建 catalyst-owner_comms-server_1 ... 完成
创建 node-exporter                   ... 完成
创建 catalyst-owner_lambdas_1      ... 完成
创建 postgres                      ... 完成
创建 catalyst-owner_certbot_1        ... 完成
创建 nats                            ... 完成
创建 postgres-exporter               ... 完成
创建 catalyst-owner_content-server_1 ... 完成
创建 catalyst-owner_archipelago_1    ... 完成
创建 catalyst-owner_explorer-bff_1   ... 完成
创建 nats-exporter                   ... 完成
创建 cadvisor                        ... 完成
创建 nginx                           ... 完成
## Catalyst 服务器已在 http://localhost 运行
```

如果一切顺利，我们现在已经有一个完整运行的 Decentraland 节点。你现在可以打开浏览器并输入该 URL。如果使用默认值，它应该是 [`http://localhost`](http://localhost/).

我们可以使用这个 docker 命令查看内容服务器日志：

```bash
> docker logs catalyst-owner_content-server_1
```

尽管服务器现在已经运行，但它还没有 100% 准备好投入使用。它需要从其他 [DAO 服务器](https://decentraland.github.io/catalyst-monitor) 同步内容，这样它才能为连接到它的用户提供相同的体验。同步可能需要很长时间。在良好的网络连接下，6 小时应该相当常见。所以……是时候喝杯咖啡、打个盹、好好睡一觉，明天再回来看看了。

判断同步是否完成的一种方法，是检查内容状态端点的结果： <http://localhost/content/status> （请在这里使用你的 URL）。

```json
{
  "synchronizationStatus": {
    "lastSyncWithDAO": 1658153514917,
    "synchronizationState": "Bootstrapping"
  },
  "snapshot": {
    "entities": {
      "profile": 1271331,
      "scene": 23477,
      "wearable": 17351,
      "store": 890
    },
    "lastUpdatedTime": 1658153414530
  },
  "version": "v3",
  "commitHash": "9a2e0d5d05d02646df2e1e5d00436d3166a07aa1",
  "catalystVersion": "4.8.6",
  "ethNetwork": "mainnet"
}
```

当 `synchronizationState` 为 `Bootstrapping`时，节点将暂时停止接受新的部署。这样可以确保在节点尚未在 DAO 网络中更新到最新状态之前，不会部署任何新实体。一旦状态变为 `Syncing`，这表示节点已成功追上，并且现在正在持续接收最新更新。这是节点完全正常工作并接受新部署的健康状态。

```json
{
  "synchronizationStatus": {
    "lastSyncWithDAO": 1658153872301,
    "synchronizationState": "Syncing"
  },
  "snapshot": {
    "entities": {
      "profile": 1271317,
      "scene": 23477,
      "store": 890,
      "wearable": 17350
    },
    "lastUpdatedTime": 1658152050030
  },
  "version": "v3",
  "commitHash": "9a2e0d5d05d02646df2e1e5d00436d3166a07aa1",
  "catalystVersion": "4.8.6",
  "ethNetwork": "mainnet"
}
```

如果你更偏向使用命令行，你可以在内容服务器 docker 镜像日志中 grep 这个消息： `开始从服务器指针变更同步实体`。一旦你看到这段文字，就说明内容服务器已经完全同步并可全面使用。

### 环境变量

以下是内容服务器所有环境变量及其默认值的完整列表，这些默认值在启动期间会记录到内容服务器日志中：

```jsx
STORAGE_ROOT_FOLDER: "/app/storage/content_server/"
DENYLIST_FILE_NAME: "denylist.txt"
DENYLIST_URLS: "https://config.decentraland.org/denylist"
SYNC_IGNORED_ENTITY_TYPES: ""
FOLDER_MIGRATION_MAX_CONCURRENCY: 1000
SERVER_PORT: 6969
LOG_REQUESTS: false
UPDATE_FROM_DAO_INTERVAL: 1800000
SYNC_WITH_SERVERS_INTERVAL: 45000
CHECK_SYNC_RANGE: 1200000
DECENTRALAND_ADDRESS: "0x1337e0507eb4ab47e08a179573ed4533d9e22a7b"
DEPLOYMENTS_DEFAULT_RATE_LIMIT_TTL: 60
DEPLOYMENTS_DEFAULT_RATE_LIMIT_MAX: 300
ETH_NETWORK: "mainnet"
LOG_LEVEL: "debug"
FETCH_REQUEST_TIMEOUT: "2m"
USE_COMPRESSION_MIDDLEWARE: false
BOOTSTRAP_FROM_SCRATCH: false
REQUEST_TTL_BACKWARDS: 1200000
LAND_MANAGER_SUBGRAPH_URL: "https://api.thegraph.com/subgraphs/name/decentraland/land-manager"
COLLECTIONS_L1_SUBGRAPH_URL: "https://api.thegraph.com/subgraphs/name/decentraland/collections-ethereum-mainnet"
COLLECTIONS_L2_SUBGRAPH_URL: "https://api.thegraph.com/subgraphs/name/decentraland/collections-matic-mainnet"
THIRD_PARTY_REGISTRY_L2_SUBGRAPH_URL: "https://api.thegraph.com/subgraphs/name/decentraland/tpr-matic-mainnet"
BLOCKS_L1_SUBGRAPH_URL: "https://api.thegraph.com/subgraphs/name/decentraland/blocks-ethereum-mainnet"
BLOCKS_L2_SUBGRAPH_URL: "https://api.thegraph.com/subgraphs/name/decentraland/blocks-matic-mainnet"
PSQL_DATABASE: "content"
PSQL_HOST: "postgres"
PSQL_SCHEMA: "public"
PSQL_PORT: "5432"
GARBAGE_COLLECTION: true
GARBAGE_COLLECTION_INTERVAL: 21600000
PG_IDLE_TIMEOUT: 30000
PG_QUERY_TIMEOUT: 60000
PG_STREAM_QUERY_TIMEOUT: 600000
SNAPSHOT_FREQUENCY_IN_MILLISECONDS: 21600000
CUSTOM_DAO: undefined
DISABLE_SYNCHRONIZATION: false
SYNC_STREAM_TIMEOUT: "10m"
CONTENT_SERVER_ADDRESS: "http://localhost/content/"
REPOSITORY_QUEUE_MAX_CONCURRENCY: 50
REPOSITORY_QUEUE_MAX_QUEUED: 300
REPOSITORY_QUEUE_TIMEOUT: "1m"
ENTITIES_CACHE_SIZE: 150000
DEPLOYMENT_RATE_LIMIT_MAX: {}
DEPLOYMENT_RATE_LIMIT_TTL: {}
VALIDATE_API: false
RETRY_FAILED_DEPLOYMENTS_DELAY_TIME: 900000
```

### 将你的节点用于生产环境

如果你想运行自己的服务器并帮助扩展网络，首先这非常棒，社区和基金会都非常感谢你这样做。

在这种情况下，你需要通过访问 [此链接](https://governance.decentraland.org/submit/catalyst/)向 DAO 申请批准以加入网络。你也可以申请 MANA 资助，以覆盖基础设施和管理费用。

重要的是，你的硬件规格应更接近上文“硬件要求”中建议的配置，因为该服务器将被任何进入 Decentraland 的社区成员使用。

### API 规格

有关内容、lambdas 和 comms 服务器 API 的更多细节，你可以查看 [API 规格](https://decentraland.github.io/catalyst-api-specs).

### 故障排查/常见问题

在启动服务器时可能会出一些问题。以下列出了一些最常见的问题以及修复方法。

#### 本地 postgres 占用了 5432 端口

如果你在一台用于开发的机器上运行该节点，或者该机器已经在托管其他服务，那么很可能那台机器上已经有一个 postgres 数据库服务器在运行。因此 5432 端口已经被占用了。

最简单的解决方法是停止本地已经运行的 postgres，然后使用以下命令重启 postgres docker 容器： `docker start postgres`.

如果你了解 docker compose，可以尝试调整 `docker-compose.yml` 和环境变量，看看是否能让它在其他端口上运行。为了保持这里的内容简单，我们在本教程中不会走这条路。

#### 本地 nginx 占用了 80 端口

80 端口（甚至 443 端口）也可能发生同样的情况。如果你在本地机器上运行 nginx，那么 80/443 端口很可能已经被该服务占用，因此 Catalyst Docker 容器将无法使用它们。

同样，最简单的方法是停止本地 nginx 服务，然后使用以下命令重启 docker 容器： `docker start nginx`。或者，你需要借助 `docker-compose.yml` 和 `.env` 让它在其他端口上运行。

### 更多参考文档

如果你想更好地了解 Catalyst 服务器做什么、包含哪些服务等，可以查看架构仓库 <https://github.com/decentraland/architecture，其中对各部分有详细说明。>

如果你想为 Catalyst 服务器代码做贡献，请务必查看 [贡献指南](https://github.com/decentraland/catalyst/blob/main/docs/CONTRIBUTING.md) 以了解我们的开发流程、如何提出错误修复和改进建议，以及如何构建和测试你的更改。

最后，如果你需要联系团队，可以通过 [Discord](https://discord.com/channels/417796904760639509/948230185457696820) 或提交 [GitHub 问题](https://github.com/decentraland/catalyst/issues).


---

# 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.decentraland.org/contributor/contributor-zh/jiao-cheng/getting-started.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.
