Mobile App Setup
This is the canonical setup guide. mobile-app/README.org and mobile-app/sapot-mobile-app/README.md point here for full instructions and cover only content not duplicated here (WSL/Android troubleshooting, command quick-reference).
Prerequisites
- Node >= 18 (
package.json'sengines), pnpm (this project's declared package manager, pinned viapackage.json'spackageManagerfield topnpm@9.15.9; Corepack will fetch the exact version automatically if enabled) - Nix (used to pin the dev toolchain via flakes)
- Android SDK (for device/emulator builds) — see the WSL2/Android Studio tips in
mobile-app/README.orgif you're on WSL - EAS CLI (
pnpm add -g eas-cli) for cloud builds
Install Nix and the dev shell
# Linux / WSL:
sh <(curl --proto '=https' --tlsv1.2 -L https://nixos.org/nix/install) --daemon
# restart your shell, then if `nix` isn't found:
source /etc/profile.d/nix.sh
# from mobile-app/ :
bash configure_nix.sh # configures Nix to process flakes
nix develop -L # enters the pinned dev shell
cd sapot-mobile-app
pnpm install
cp .env.example .env
Configure the dev server host
Point the app at your server's LAN IP (the machine running the Docker setup) in
the .env you copied above:
# mobile-app/sapot-mobile-app/.env
EXPO_PUBLIC_DEV_HOST=192.168.1.x
config/runtime.ts builds every URL from this one value: https://<host> for the API,
wss://<host> for WebSocket, https://<host>/tiles for map tiles. There is no
EXPO_PUBLIC_API_URL; the base URL is not separately configurable. At runtime the app's Server Mode
settings dialog can override the host without an env change, and that override wins over
EXPO_PUBLIC_DEV_HOST.
See environment-config.md for the full mobile app env var list.
The app always talks HTTPS, including in development (config/runtime.ts's getApiUrl/getWsUrl return https:///wss:// for every build variant, dev included). docker-setup.md's Nginx TLS terminator handles this for you automatically. Running the server bare-metal instead (server-setup.md)? See Configure TLS trust for local development below before starting it, or the app will fail to connect.
Configure TLS trust for local development
The mobile app pins the server's CA certificate via Android's network-security-config (app.config.ts's withServerCa/withNetworkSecurityConfig, using mobile-app/sapot-mobile-app/server_ca.pem), so your local FastAPI dev server needs to terminate TLS with a certificate the app will trust. The dev build's network-security-config trusts two anchors, so pick whichever is least friction:
- System/user CA store — install your own CA on the emulator/device as a user-trusted certificate, then issue a server leaf from it. Trusted automatically in dev builds (
<certificates src="system"/>/<certificates src="user"/>). - Bundled default CA (
mobile-app/sapot-mobile-app/server_ca.pem) — issue a leaf signed by this CA for your dev server. Sameopensslsteps as "Issue a new server leaf from the CA" in runbooks.md, but point the SAN at your dev machine's LAN IP instead of the prod server's.
Point your dev FastAPI server at the resulting cert/key (e.g. uvicorn --ssl-certfile server.crt --ssl-keyfile server.key).
Run
pnpm dev # Expo dev server (APP_VARIANT=development)
# or, for a native Android build:
pnpm run prebuild # expo prebuild -p android --clean, then scripts/setup-android-signing.js
pnpm run android # expo run:android --app-id com.devamt.sapotmobileapp.dev
Then open the app's getting-started screen, tap Server Mode, tap the cog icon on that card, and enter your laptop's LAN IP address (must match EXPO_PUBLIC_DEV_HOST and be on the same WiFi network as the server). The other option, LAN Mode, skips the server entirely and asks only for a name. See quickstart.md.
Optional: GPS map tiles
The Docker stack already runs a tileserver service behind Nginx at
https://<host>/tiles/, which is exactly where config/runtime.ts's getTileServerUrl() looks, so
if you are running that stack, the map works with no extra setup beyond supplying the data. The
.mbtiles file itself is gitignored: download it (see mobile-app/sapot-mobile-app/README.md for
the current link) into tileserver/ and name it osm-batangas.mbtiles, because that exact filename is what
docker-compose.yml passes to tileserver-gl, then restart the service.
Running the tileserver standalone instead? Use deploy-tiling-server.sh from tileserver/.
Verify
pnpm run typecheck,pnpm run lint,pnpm test— see the mobile app testing documentation.
Next
- The mobile app onboarding documentation for a deeper architectural walkthrough.