Running Expo/React Native in Docker
Tags: reactnative, docker, dockercompose, expo
Published: 2018-12-07 23:17:25

---
title: Running Expo/React Native in Docker
published: true
tags: react-native,docker,docker-compose,expo
canonical_url: https://medium.com/@hmajid2301/running-expo-react-native-in-docker-ff9c4f2a4388
---

![](https://cdn-images-1.medium.com/max/500/1*lnXvsEAIgA1cLp20M20Q4Q.gif)<figcaption>Original Image: <a href="https://maraaverick.rbind.io/2017/11/docker-izing-your-work-in-r/">https://maraaverick.rbind.io/2017/11/docker-izing-your-work-in-r/</a> and <a href="https://tutuappapkdownload.com/expo-apk/">https://tutuappapkdownload.com/expo-apk/</a></figcaption>

Running Expo/React Native in a Docker container can sometimes cause issues. In this example, I will be running Docker 🐳 within a guest VM (Ubuntu) which will run on my host machine (Windows). My host machine will also be running another VM as the Android emulator (Genymotion) for Expo to connect to. You can get a more detailed post about how to connect two VMs together [here](https://dev.to/hmajid2301/react-nativeexpo-with-virtualbox-and-genymotion-3bl-temp-slug-8350851), #PlugPlugPlug 🔌🔌🔌. Since I’ve set up networking on those two VMs already as far as Expo is concerned it might as well be running on the host machine (Windows). Also in this example, I will be testing this on an Android device.

### Prerequisites

- [Install Docker](https://docs.docker.com/install/)
- [(optional) Install docker-compose](https://docs.docker.com/compose/install/)
- Android device/emulator to test on

### package.json

![](https://cdn-images-1.medium.com/max/1024/1*GYvaZ5hVpe4lQ3Rf2mq97A.png)<figcaption>package.json</figcaption>

The _package.json_ file I will be using the following example is a very barebones file, just including the minimum packages required to run Expo.

### Dockerfile

![](https://cdn-images-1.medium.com/max/1024/1*HLrfzHNuXn6BHpgmoAzHoA.png)<figcaption>Dockerfile</figcaption>

```
FROM node:latest
```

Tells us which Docker Image we are using as a base, in this case, the official _node.js_ image. This is because it will have a lot of the dependencies we need already installed such as _yarn_ and _npm_.

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

Sets an environment variable which can be accessed during runtime of the Docker container. Strictly speaking, these don’t need to be here because we can always inject into the Docker container at runtime, but I like to have the environment variables documented.

The _ADB\_IP_ is IP of the Android device 📱 to connect to. The _REACT\_NATIVE\_PACKAGER\_HOSTNAME_ environment variable is very important because it sets which IP address Expo (cli) is running on, this is the IP Address your phone will try to connect to. If this is not set correctly, you’ll get an error similar to Figure 1. You can work out the correct IP address on Linux by using the following command. The first one should host IP (192.168.27.128 on my machine).

```
hostname -I
192.168.27.128 192.168.130.128 172.17.0.1 172.19.0.1 172.18.0.1
```

The reason this environment variable needs to be set is because by default the React Native packager (which expo relies on) picks the first IP it sees on the machine, hence you can run expo on your host machine fine but when you run in a Docker container you cannot connect to it because it’s trying to use the Docker IP address (one of the ones starting with 172.xxx.xxx.xxx).

```
EXPOSE 19000
EXPOSE 19001
```

This is essentially meta data letting the user of the Docker container know that they can access data on those ports.

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

Install Android Debugging Bridge (ADB), which is used to connect to an Android device and debug the application.

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

Copy some important files from host to Docker container. _The package.json_ and _yarn.lock_ are used to install the dependencies and _app.json_ is required by expo as a bare minimum.

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

![](https://cdn-images-1.medium.com/max/819/1*ZYbIrUe9j6TmwssuPBJIXw.png)<figcaption>Figure 1: Could not connect error 😢</figcaption>

### Running Docker

This command runs when the Docker Image is first to run, every other command is used to build to the image itself. This uses an environment variable passed into the Docker container and connects to the Android device at $ADB\_IP. Then run the _android_ command in _package.json_. Then you can simply run the following commands to build and start your Docker container.

![](https://cdn-images-1.medium.com/max/1024/1*IcXbBc7wMexVQhGkC51J9g.png)<figcaption>Docker Build/Run command</figcaption>

- -t is used to name the image (expo-android)
- . tells Docker where the Dockerfile is (in the current directory)
- — env sets environment used by Docker container when it starts to run (REACT\_NATIVE\_PACKAGER\_HOSTNAME and ADB\_IP are overwritten using these new values)
- -p publishes ports, in this example, it maps port 19000 on the host to port 19000 on the Docker container (and also 19001), as we need to access port 19000 and 19001 so that Expo (expo-cli) can connect to our Android device.

### docker-compose.yml

![](https://cdn-images-1.medium.com/max/790/1*prYM2gdRWurpCgYiI58vUA.png)<figcaption>docker-compose.yml</figcaption>

Since expo is being used to build mobile phone applications Docker isn’t going to be used in production. I prefer to use docker-compose to do the building and running, it means I can run one simple command and do the building and running in one step. Quick aside docker-compose is great for development, especially when you need to run multiple Docker container, but is not really built to be used in production. Look at using a container orchestration tool such as Kubernetes.

I also mount my current directory on the host machine to /app/ directory on the docker container, this is so that any files that change on my the host machine will also change in the Docker container, rather than having to build the Docker container again.

![](https://cdn-images-1.medium.com/max/706/1*6MCPmNosDhRT9oSEKfSXyQ.png)<figcaption>docker-compose Build/Run command.</figcaption>

### .env

![](https://cdn-images-1.medium.com/max/1024/1*K2zO9L8rWsCtULuY3D9wrw.png)<figcaption>.env</figcaption>

An example .env file used to pass environment variables (using docker-compose) to the Docker container.

### Appendix

- [Code images with Carbon](https://carbon.now.sh)
- [Docker explained](https://medium.freecodecamp.org/a-beginner-friendly-introduction-to-containers-vms-and-docker-79a9e3e119b)
- [GitHub Issue around could not connect errors](https://github.com/react-community/create-react-native-app/issues/81)
- [Genymotion Emulator](https://www.genymotion.com/)
- [GIF Overlay Creator](https://ezgif.com/overlay)