Meet Kinksters’ mobile app is built with Expo, an opinionated set of defaults for React Native, paired with a simplified build pipeline for iOS and Android binaries. It’s great.
My preference, whenever I can, is to run software under development in a Docker container. This helps isolate dependencies, provides better dev-to-prod parity, and keeps my laptop a little “cleaner.”
Running Expo in Docker is easy enough:
version: '3' services: expo: image: node:14 working_dir: /build volumes: - ./app:/build user: $USER_ID command: node_modules/.bin/expo start environment: REACT_NATIVE_PACKAGER_HOSTNAME: docker-bridge.local EXPO_DEVTOOLS_LISTEN_ADDRESS: 0.0.0.0 ports: - 172.17.0.1:19002:19002 - "0.0.0.0:19000:19000"
This setup works “fine” if you’re using Expo Go on a physical device on the same LAN. But
what about emulation? Clicking the
Run on Android device/emulator button inside of the Expo Developer Tools UI
expo run:android both attempt to call
adb, which isn’t present inside the container.
There are a few tutorials around the web that cover installing
adb along with
node, but this seemed excessive. A
static analysis of the code behind
expo run:android led me to understand Expo simply starts a virtual device (emulator), installs Expo Go and then
points the app at Metro Bundler. So, why not just do that ourselves?
I followed the Expo documentation on installing Android Studio and the Android SDK, and creating an emulator. Ignore the part about saving the path to the SDK or adding it to your shell.
You’ll notice I set
REACT_NATIVE_PACKAGER_HOSTNAME to an arbitrary, non-publicly-routable hostname, but not
localhost. I’m running Linux, so I know with confidence that the Docker
bridge interface address is
172.17.0.1. I added this to my laptop’s
172.24.0.1 docker-bridge docker-bridge.local
Since the emulator defers to my laptop for performing DNS lookups, this now allows my emulated Android device to connect to Expo. Now, I just need Expo Go installed. You could “just” use the IP, but I find this more semantic.
Download the APK from the Expo Go downloads page, start the virtual device and run
adb install [path-to-apk.apk].
Expo Go looks for an
exp:// URL on the device clipboard to add a new project, but I couldn’t quite figure out how to
paste arbitrary text to the clipboard. Instead, I used the emulator testing UI to send the device an SMS containing
the URL. Copy the message contents and you’re done!
Expo Go will now hot-reload your application.