# Electrumx安装心得全纪录（Part 2）

## :tada:如何在Mac里面安装Docker并安装Electrumx

如果在Docker里安装，就不用关注Part1里说的那些Python依赖库的安装，但要对Docker本身的运行原理和命令行比较熟悉才能行。

### :smile:首先说下原理

你可以理解为网友帮你制作的Electrumx Docker Image（镜像），就是把python以及其依赖包都打包好了，你直接安装就可以了。在下图里，Bins\Libs就是这些Python环境和库；App就是Electrumx索引器程序

<figure><img src="https://1147012938-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fa8tR2RZ7SfMUYpW6MNum%2Fuploads%2FN4XMbkcAfIMek9WsPwSy%2F%E5%9B%BE%E7%89%87.png?alt=media&#x26;token=a2dd359d-baf5-47d2-ae08-0254e8210083" alt=""><figcaption><p>Dokcer原理</p></figcaption></figure>

如果已经安装好Docker并运行，大概的样子会是这样的：

<figure><img src="https://1147012938-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fa8tR2RZ7SfMUYpW6MNum%2Fuploads%2FtMMxXHR9PLS0XcShPs3G%2F%E5%9B%BE%E7%89%87.png?alt=media&#x26;token=2371dde4-3cd4-425e-950e-22cdfcdd0fcc" alt=""><figcaption><p>container(容器)，里面有正在跑的Electrumx程序</p></figcaption></figure>

<figure><img src="https://1147012938-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fa8tR2RZ7SfMUYpW6MNum%2Fuploads%2FSZwvY1gMjKN9tacrZTT5%2F%E5%9B%BE%E7%89%87.png?alt=media&#x26;token=db3500f7-0a17-4c64-8119-c0c545d8e8b9" alt=""><figcaption><p>运行的日志示意</p></figcaption></figure>

<figure><img src="https://1147012938-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fa8tR2RZ7SfMUYpW6MNum%2Fuploads%2FjGqhqfxwuEtD76KUamMj%2F%E5%9B%BE%E7%89%87.png?alt=media&#x26;token=e0087936-8f8d-41a4-aa2b-694beb18c238" alt=""><figcaption><p>Image镜像，你看我安装了了多少版本，真爱啊</p></figcaption></figure>

<figure><img src="https://1147012938-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fa8tR2RZ7SfMUYpW6MNum%2Fuploads%2FhFxfPx5f0Ng4H0R7Fouz%2F%E5%9B%BE%E7%89%87.png?alt=media&#x26;token=2a74ec56-d610-49eb-8846-e501fc2cecc4" alt=""><figcaption><p>Volume卷</p></figcaption></figure>

我们大致了解一下这几个核心概念（From Chatgpt）：

1. **Volumes（卷）**：
   * Volumes是Docker用来**持久化数据**的一种机制。它们允许容器和宿主机之间共享和存储数据，以便在容器删除或重新创建时数据不会丢失。Volumes可以用来存储数据库文件、日志文件、配置文件等任何需要持久保存的数据。
2. **Images（镜像）**：
   * **镜像是Docker容器**的基础，可以将其视为包含应用程序运行所需的所有文件和依赖项的模板。镜像包含了文件系统的完整副本，其中包括操作系统、应用程序代码、运行时环境等。
3. **Containers（容器）**：
   * 容器是Docker**中运行的实例**。它们是基于镜像创建的运行时环境，其中包含了应用程序代码、运行时环境和依赖项。容器可以被启动、停止、删除，并且可以与其他容器或主机进行通信。

所以，Images（镜像）是容器的模板，你可以理解为用光盘安装程序时代的光盘镜像，可以挂载到计算机的；Containers（容器）则是基于镜像运行的实例，你可以理解为通过光盘具体的安装程序；Volumes（卷）用于持久化数据，什么是持久化自己扩展学习。

在这里，我们用的是Nextdao制作的Docker的教程，我加上备注说一下安装过程：



### :smile:开始安装

首先打开官网github地址[https://github.com/Next-DAO/atomicals-electrumx-docker](https://github.com/Next-DAO/atomicals-electrumx-docker)，我们按照方法逐行做：

**解读Requirements，首先把Bitcoincore服务器端设置好**

> 1. `server=1`：
>    * 这个选项告诉 Bitcoin Core 启用服务器模式，允许其他 Bitcoin 客户端连接到这个节点。
> 2. `txindex=1`：
>    * 这个选项告诉 Bitcoin Core 启用交易索引，使得节点能够查询和索引所有交易，而不仅仅是已确认的交易。
> 3. `rpcauth=nextdao:cca838b4b19bdc6093f4e0312550361c$213834a29e8488804946c196781059a7ee0ac2b48dbf896b4c6852060d9d83dd`：
>    * 这个选项设置 RPC 认证凭据，用于远程过程调用（RPC）访问 Bitcoin Core 的 API。这里的字符串是通过 rpcauth.py 脚本生成的，包含了用户名和哈希密码。本质是用户名和密码都是nextdao。
> 4. `rpcallowip=127.0.0.1`：
>    * 这个选项指定允许连接到 RPC 服务的 IP 地址。这里只允许本地主机（127.0.0.1）连接。
> 5. `rpcallowip=172.0.0.0/8` 和 `rpcallowip=192.168.0.0/16`：
>    * 这两个选项指定了允许连接到 RPC 服务的 IP 地址范围。172.0.0.0/8 是一个保留的私有地址段，192.168.0.0/16 是另一个私有地址段，用于允许在局域网内的设备连接到 RPC 服务。
> 6. `rpcbind=0.0.0.0`：
>    * 这个选项指定了 RPC 服务绑定的 IP 地址。0.0.0.0 表示绑定到所有可用的网络接口，允许来自本地主机和局域网内设备的连接

在本地电脑（需要100G以上，实测到2024年2月份大概95G）设置一个全新的文件夹，比如我的叫electrumx-docker

<figure><img src="https://1147012938-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fa8tR2RZ7SfMUYpW6MNum%2Fuploads%2FV56cXg0f4zf6mOfgLpvZ%2F%E5%9B%BE%E7%89%87.png?alt=media&#x26;token=9c7dac65-5a33-4812-8ed3-380c3059a905" alt=""><figcaption><p>新建的文件夹</p></figcaption></figure>

#### 解读Usage：1. Download [docker-compose.yml](https://github.com/Next-DAO/atomicals-electrumx-docker/raw/main/docker-compose.yml) to a folder.

修改docker-compose.yml,默认是这样的：

```
version: '3'
services:
  electrumx:
    image: lucky2077/atomicals-electrumx:v1.3.9.0
    restart: always
    ports:
      - 50001:50001
      - 50002:50002
      - 8000:8000
      - 8080:8080
    healthcheck:
      test: "nc -z localhost 50001"
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 30s
    volumes:
      - ./electrumx-data:/data
    environment:
      - DAEMON_URL=nextdao:nextdao@127.0.0.1:8332
      - COIN=BitCoin
```

官方的备注是

```
Change 127.0.0.1 to lan ip of the bitcoin core host, eg: 192.168.50.2.
```

注意！这里信息量很大。我的经验是无论就是127.0.0.1，还是改为localhost还是公网的IP，比如我的是121.xx.xx.xx，也都连不上比特币节点。这是为何？

这是因为Docker内部虚拟出来了网络结构，127.0.0.1和locahhost已经不再是电脑的内部回环地址了！我们应该改为host.docker.internal

```
environment:
      - DAEMON_URL=nextdao:nextdao@host.docker.internal:8332
```

我们来问问chatgpt这是干什么的:

> `host.docker.internal` 是 Docker Desktop for Mac 或 Docker Desktop for Windows 中的一个特殊的 DNS 名称。它用于在容器内访问宿主机的服务。
>
> **在 Docker 中，通常容器是在自己的网络命名空间中运行的，它们默认无法直接访问宿主机上的服务**。但是，为了方便开发和调试，Docker 在 Docker Desktop for Mac 和 Docker Desktop for Windows 中引入了 `host.docker.internal` 这个特殊的 DNS 名称。**当你在容器内使用这个域名时，它会被解析为宿主机的 IP 地址**。
>
> 这使得容器内的应用程序能够轻松地与宿主机上的服务进行通信，无需知道宿主机的实际 IP 地址。这对于需要与本地开发环境中的服务进行交互的应用程序来说非常有用，因为它们可以像访问远程服务一样访问宿主机上的服务，而无需进行额外的配置。

你如果再好奇，用这个命令看看主机到底分配了一个什么IP地址给Docker

```
docker run --rm alpine nslookup host.docker.internal
```

我的结果显示是,可见其实是192.168.65.7分配给Docker了

<figure><img src="https://1147012938-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fa8tR2RZ7SfMUYpW6MNum%2Fuploads%2FSaPmhokBafygy95xdt0s%2F%E5%9B%BE%E7%89%87.png?alt=media&#x26;token=9d94f5ee-a80d-48de-95c4-ec5e2de2b456" alt=""><figcaption></figcaption></figure>

**这一点很重要，不然你的Docker启动后会遇到这样的报错**：

<figure><img src="https://1147012938-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fa8tR2RZ7SfMUYpW6MNum%2Fuploads%2FoAIp1gjXiu1YdKMa8a9p%2F%E5%9B%BE%E7%89%87.png?alt=media&#x26;token=99b30e4b-51ae-4313-86a2-86344072fd51" alt=""><figcaption></figcaption></figure>

### 解读2. Run the RPC server:

接着做，

<pre><code><strong>docker-compose pull &#x26;&#x26; docker-compose up -d
</strong></code></pre>

`docker-compose pull` 命令用于从远程镜像仓库拉取 Docker 镜像。这时你的docker 程序里 Image就多了一个镜像。

`docker-compose up -d` 命令用于启动 Docker Compose 配置文件中定义的服务，并且在后台运行，选项 `-d` 表示以守护进程模式（后台模式）运行服务。

这时候你会默认多一个Electrumx的目录结构是这样的，新建了一个叫electrumx-data的文件夹

<figure><img src="https://1147012938-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fa8tR2RZ7SfMUYpW6MNum%2Fuploads%2FR1UJ99RdGb2t8ngJUupR%2F%E5%9B%BE%E7%89%87.png?alt=media&#x26;token=d6c41a44-607f-4c2e-a7e4-099bb6762ab7" alt=""><figcaption></figcaption></figure>

打开文件夹的目录结构是这样的

<figure><img src="https://1147012938-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fa8tR2RZ7SfMUYpW6MNum%2Fuploads%2FLonTPbTpNkHZNoC9twc7%2F%E5%9B%BE%E7%89%87.png?alt=media&#x26;token=dd77020b-5eb0-4773-aaf5-cd41c519e9f9" alt=""><figcaption></figcaption></figure>

如果你看到跟我一样的目录结构，就对了，恭喜你。看看官方在这一步都是怎么说的:

* the electrumx indexes stored in `./electrumx-data` directory.

_备注_：在同一个目录下新建electrumx-data文件夹。这是因为我们在.env配置文件docker-compose.yml有如下这一行，这本质是挂载的数据目录，你可以在Containers-bind mounts里面找到同样的信息：

```
volumes:
      - ./electrumx-data:/data
```

* use `docker-compose logs -f` to check the logs.

_备注：其实在图形界面Container-log里面看得更完整一些_

* use `docker-compose down` to stop the server.

别担心，这个命令这只会停止和删除Container，你的数据还在。

如果要复用别人同步好的数据，怎么办？我们要修改数据挂载的地方，比如我的数据其实是在移动硬盘目录    /Volumes/Element/atomical-legacy下的，所以修改的方式是

```
volumes:
      - /Volumes/Element/atomical-legacy:/data
```

我为何这么啰嗦地写？很多新手肯定会像我一样，都不敢动手去改呢！



如果你的Docker里的Electrumx运行成功了，你可以看到log里面各种同步信息，更进一步地，你可以试试这个命令

```
docker-compose ps
```

看到类似的样子，这说明我们的electrumx服务在tcp的8080端口，tcp里的50001-50002都在监听

<figure><img src="https://1147012938-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fa8tR2RZ7SfMUYpW6MNum%2Fuploads%2FLd2RBWkreMCbceSTf0iv%2F%E5%9B%BE%E7%89%87.png?alt=media&#x26;token=d841f57a-0368-407e-bf08-665abb9401b8" alt=""><figcaption></figcaption></figure>

在mint quark那段时间，electrumx服务器还不支持http协议，所以那个时候我们还要再装一个proxy，但从无线挖矿开启后，官方升级到v1.3.9以后，已经支持http了，所以我们只需要安装一个程序。

OK，再检查一遍你是否装好了，跟着我在浏览器输入

```
localhost:8080/proxy
```

结果如下

<figure><img src="https://1147012938-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fa8tR2RZ7SfMUYpW6MNum%2Fuploads%2F9Rwtr17oSGOjuR0Inzbm%2F%E5%9B%BE%E7%89%87.png?alt=media&#x26;token=70a19046-fc40-4ed9-8baf-f79164e96f8c" alt=""><figcaption></figcaption></figure>

```
localhost:8080/proxy/health
```

<figure><img src="https://1147012938-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fa8tR2RZ7SfMUYpW6MNum%2Fuploads%2FK1TChUlgTdWKtNFXIzEK%2F%E5%9B%BE%E7%89%87.png?alt=media&#x26;token=e35e35a7-2e4f-4c96-b08a-f1fd12f3dc73" alt=""><figcaption></figcaption></figure>

注意，一般数据同步完了才会都显示true.

先写到这里。大致的安装思路和背后的原理就是这样，大家如果有不同环境遇到的问题可以留言，或者自行请教chatgpt。

***

欢迎关注作者并提出宝贵修改意见：[https://twitter.com/zzmjxy](https://twitter.com/zzmjxy)
