10

I'm trying to dockerize an Expo React Native app so anyone of my team partners could download the repo and then make a docker-compose up and without effort have the same expo server running in their computers.
As far I make it possible to build the container and it is showing the same info it show up when I run it locally on my computer.

enter image description here

The problem arises when trying to start the metro bundler, url http://localhost:19002 is inaccessible. That doesn't happen with the port 19001, which is working perfectly.Besides, I tryed scanning the QR code with my iPhone device but it doesn't work neither, because is not finding the docker ip I guess.

I cannot figure out what I am doing wrong, and there is not so much information about dockerize expo in the web.

These are my dockerfile and docker-compose.yml

FROM node:latest

RUN mkdir -p /usr/src/app

WORKDIR /usr/src/app

COPY package*.json /usr/src/app/
COPY app.json /usr/src/app/

RUN npm install -g expo-cli

EXPOSE 19000
EXPOSE 19001
EXPOSE 19002

CMD npm i -f && npm start
version: '3.7' # Specify docker-compose version

# Define the services/containers to be run
services:
   expo: # Name of the frontend service
      container_name: expo-prestadores
      build: ./ # Specify the directory of the Dockerfile
      ports:
         - 19000:19000 # Specify port-forwarding
         - 19001:19001
         - 19002:19002
      volumes: # Mount host path in the container
         - ./:/usr/src/app
         - /usr/src/app/node_modules

rodricass
  • 155
  • 1
  • 5

3 Answers3

10

Makes sense. Expo DevTools tells you it is running on localhost in your container.

This means that in your container the Expo DevTools are only available to localhost. Which in turn is only available from within the container itself. No port exposure will help you there. You need to set your port binding in a way that allows outside access. e.g. via the IP of the container in order to allow an expose statement to work.

In short, add the EXPO_DEVTOOLS_LISTEN_ADDRESS=0.0.0.0 environment variable like this

version: '3.7' # Specify docker-compose version
services:
   expo: # Name of the frontend service
      container_name: expo-prestadores
      build: ./ # Specify the directory of the Dockerfile
      ports:
         - 19000:19000 # Specify port-forwarding
         - 19001:19001
         - 19002:19002
      volumes: # Mount host path in the container
         - ./:/usr/src/app
         - /usr/src/app/node_modules
      environment:
         - EXPO_DEVTOOLS_LISTEN_ADDRESS=0.0.0.0 

to your docker-compose.yml and you should be fine.

ckaserer
  • 4,827
  • 3
  • 18
  • 33
  • 1
    Thanks ckaserer, this works but only halfway. The logo of Expo developer tools is showing up in the tab on the browser, but only a black background screen is visible. Besides, I don't know why if in the terminal says Metro bundler will be running on port 19001, then when I search for it, it opens the React Native Debugger tab. I could connect the expo docker with my mobile phone now because I added REACT_NATIVE_PACKAGER_HOSTNAME variable to enviroment in my docker-compose.yml, but it is impossible for me to open the app in a simulator without using the Metro Bundler interface. – rodricass Jan 08 '20 at 13:29
  • Thanks for the reply. I don't have any idea how to fix the browser issue you just mentioned in the comment above, maybe somebody else is up to the task – ckaserer Jan 08 '20 at 13:38
6

To fix the black background screen in the browser as mentioned in previous responses, you must add the REACT_NATIVE_PACKAGER_HOSTNAME environment variable and set it to your computer's local IP address. Then instead of navigating to localhost:19002 or 0.0.0.0:19002 for the Expo Developer Tools, navigate to <<HOST LOCAL IP>>:19002 (replacing with your respective IP, of course), and you should see the DevTools working. The QR code on this page should load your app on ExpoGo at the address <<HOST LOCAL IP>>:19000.

Your docker-compose.yml should now look like this:

version: '3.7' # Specify docker-compose version
services:
   expo: # Name of the frontend service
      container_name: expo-prestadores
      build: ./ # Specify the directory of the Dockerfile
      ports:
         - 19000:19000 # Specify port-forwarding
         - 19001:19001
         - 19002:19002
      volumes: # Mount host path in the container
         - ./:/usr/src/app
         - /usr/src/app/node_modules
      environment:
         - EXPO_DEVTOOLS_LISTEN_ADDRESS=0.0.0.0 
         - REACT_NATIVE_PACKAGER_HOSTNAME=<<HOST LOCAL IP>>>

CJSantee
  • 71
  • 1
  • 5
  • Using the local IP was a savior for me. This expo react native and docker also made me paranoid. Thanks @CJSantee ! – JavaQuest Dec 24 '21 at 01:18
  • @CJSantee do you know how could I send API requests from the expo app running in one container to another container that has the backend. I am trying to configure nginx but I am stuck. – hd3adcode Jun 20 '22 at 00:12
  • Yep local IP saved me as well. The EXPO Go didn't load the app but I resolved that issue by using tunnel connection. Thanks – KMC Jul 06 '22 at 01:49
2

I might be a little too late for this but I've come up with a workaround here, once you've implemented the solution given by @ckaserer you can log on to http://0.0.0.0:19002 and select Tunnel instead of LAN in the connection section just as shown below and run your application on Expo Go App and it'd be fine enter image description here