TLDR: Expo cannot run in Docker. iOS Simulator needs direct access to Metro bundler on the host. This is fine because Expo only uses public EXPO_PUBLIC_* vars. Real secrets live in the API container. For EAS Build, inject secrets with infisical run -- eas build.
Why Expo must run on the host
The iOS Simulator is a native macOS process. It needs direct access to Metro bundler. Expo Go on a physical device needs the dev server over your local network. Neither works when Metro is inside a container.
Why this is safe
Expo’s EXPO_PUBLIC_* variables are public by definition. They get bundled into the JavaScript and shipped to the client. They are not secrets.
# Expo on host, only public varscd apps/mobileEXPO_PUBLIC_API_URL=http://localhost:3333 npx expo startReal secrets (Stripe server keys, push notification tokens) live in the API container. The mobile app calls the API. It never sees secrets directly.
EAS Build
Inject build-time secrets only during the build command:
infisical run --env=staging -- eas build --platform ios --profile preview.claudeignore for Expo
apps/mobile/.expo/apps/mobile/ios/apps/mobile/android/*.mobileprovision*.p12*.keystoreGoogleService-Info.plistgoogle-services.json