[](https://res.cloudinary.com/practicaldev/image/fetch/s--X-aiw6-I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn- images-1.medium.com/max/500/1%2AlnXvsEAIgA1cLp20M20Q4Q.gif)

原始图像:https://maraaverick.rbind.io/2017/11/docker-izing-your-work-in-r/和https://tutuappapkdownload.com/expo- APK/

在 Docker 容器中运行 Expo/React Native 有时会导致问题。在此示例中,我将在来宾 VM (Ubuntu) 中运行 Docker 🐳,该 VM 将在我的主机 (Windows) 上运行。我的主机也将运行另一个虚拟机作为 Android 模拟器 (Genymotion) 以供 Expo 连接。您可以在此处](https://dev.to/hmajid2301/react-nativeexpo-with-virtualbox-and-genymotion-3bl-temp-slug-8350851),#PlugPlugPlug 🔌🔌🔌 获得有关如何将两个 VM 连接在一起的更详细的帖子[。由于我已经在这两个虚拟机上建立了网络,就 Expo 而言,它也可以在主机 (Windows) 上运行。同样在此示例中,我将在 Android 设备上进行测试。

先决条件

  • 安装 Docker

  • (可选)安装docker-compose

  • 要测试的 Android 设备/模拟器

包.json

[](https://res.cloudinary.com/practicaldev/image/fetch/s--LEKO3CLL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1. medium.com/max/1024/1%2AGYvaZ5hVpe4lQ3Rf2mq97A.png)

包.json

我将在以下示例中使用的 package.json 文件是一个非常简单的文件,仅包含运行 Expo 所需的最少包。

Dockerfile

[](https://res.cloudinary.com/practicaldev/image/fetch/s--iNom9Onw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1。 medium.com/max/1024/1%2AHLrfzHNuXn6BHpgmoAzHoA.png)

Dockerfile

FROM node:latest

告诉我们我们使用哪个 Docker Image 作为基础,在本例中是官方的 node.js 镜像。这是因为它已经安装了很多我们需要的依赖项,例如 yarnnpm

ENV ADB\_IP="192.168.1.1"
ENV REACT\_NATIVE\_PACKAGER\_HOSTNAME="192.255.255.255"

设置可以在 Docker 容器运行时访问的环境变量。严格来说,这些不需要在这里,因为我们总是可以在运行时注入到 Docker 容器中,但我喜欢记录环境变量。

ADB_IP 是要连接的 Android 设备📱 的 IP。 REACT_NATIVE_PACKAGER_HOSTNAME 环境变量非常重要,因为它设置了 Expo (cli) 在哪个 IP 地址上运行,这是您的手机将尝试连接的 IP 地址。如果设置不正确,您将收到类似于图 1 的错误。您可以使用以下命令在 Linux 上计算出正确的 IP 地址。第一个应该托管 IP(我的机器上是 192.168.27.128)。

hostname -I
192.168.27.128 192.168.130.128 172.17.0.1 172.19.0.1 172.18.0.1

需要设置此环境变量的原因是因为默认情况下,React Native 打包程序(expo 依赖)选择它在机器上看到的第一个 IP,因此您可以在主机上正常运行 expo,但是当您在 Docker 中运行时您无法连接到它的容器,因为它正在尝试使用 Docker IP 地址(以 172.xxx.xxx.xxx 开头的地址之一)。

EXPOSE 19000
EXPOSE 19001

这本质上是元数据,让 Docker 容器的用户知道他们可以访问这些端口上的数据。

RUN apt-get update && \
 apt-get install android-tools-adb

安装 Android Debugging Bridge (ADB),它用于连接到 Android 设备并调试应用程序。

COPY package.json yarn.lock app.json ./
RUN yarn --network-timeout 100000

将一些重要文件从主机复制到 Docker 容器。 _ package.json _ 和 _ yarn.lock _ 用于安装依赖项,expo 至少需要 app.json

CMD adb connect $ADB\_IP && \
 yarn run android
 # runs expo-cli start --android

[](https://res.cloudinary.com/practicaldev/image/fetch/s--jRMynIa---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1 .medium.com/max/819/1%2AZYbIrUe9j6TmwssuPBJIXw.png)

图 1:无法连接错误😢

运行 Docker

此命令在 Docker 映像第一次运行时运行,所有其他命令都用于构建映像本身。这使用传递给 Docker 容器的环境变量并连接到 $ADB_IP 上的 Android 设备。然后运行 package.json 中的 android 命令。然后,您可以简单地运行以下命令来构建和启动 Docker 容器。

[](https://res.cloudinary.com/practicaldev/image/fetch/s--4IEeEVKW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1。 medium.com/max/1024/1%2AIcXbBc7wMexVQhGkC51J9g.png)

Docker 构建/运行命令

  • -t 用于给图片命名(expo-android)

  • .告诉 Docker Dockerfile 在哪里(在当前目录中)

  • — env 设置 Docker 容器开始运行时使用的环境(使用这些新值覆盖 REACT\NATIVE\PACKAGER\HOSTNAME 和 ADB_IP)

  • -p 发布端口,在本例中,它将主机上的端口 19000 映射到 Docker 容器上的端口 19000(以及 19001),因为我们需要访问端口 19000 和 19001 以便 Expo (expo-cli) 可以连接到我们的安卓设备。

码头工人-compose.yml

[](https://res.cloudinary.com/practicaldev/image/fetch/s--FA8OOA1R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1。 medium.com/max/790/1%2AprYM2gdRWurpCgYiI58vUA.png)

码头工人-compose.yml

由于 expo 被用于构建手机应用程序,Docker 不会在生产中使用。我更喜欢使用 docker-compose 来构建和运行,这意味着我可以运行一个简单的命令,一步完成构建和运行。快速抛开 docker-compose 非常适合开发,尤其是当您需要运行多个 Docker 容器,但并不是真正构建用于生产环境时。看看使用容器编排工具,例如 Kubernetes。

我还将主机上的当前目录挂载到 docker 容器上的 /app/ 目录,这样在我的主机上更改的任何文件也将在 Docker 容器中更改,而不必再次构建 Docker 容器.

[](https://res.cloudinary.com/practicaldev/image/fetch/s--OpBc1yQn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1。 medium.com/max/706/1%2A6MCPmNosDhRT9oSEKfSXyQ.png)

docker-compose 构建/运行命令。

.env

[](https://res.cloudinary.com/practicaldev/image/fetch/s--yCW0NdJB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1。 medium.com/max/1024/1%2AK2zO9L8rWsCtULuY3D9wrw.png)

.env

用于将环境变量(使用 docker-compose)传递给 Docker 容器的示例 .env 文件。

附录

  • 带有碳的代码图像

  • Docker 解释

  • GitHub 问题围绕无法连接错误

  • Genymotion 模拟器

  • GIF 叠加创建者

Logo

云原生社区为您提供最前沿的新闻资讯和知识内容

更多推荐