Using EAS Build for Expo React Native Projects within Docker Compose

This blog explores the integration of EAS Build and Docker Compose for Expo React Native projects, providing a step-by-step guide to streamline your mobile development workflow.

Blog cover image
2101050's avatar
2101050
9 views

Using EAS Build for Expo React Native Projects within Docker Compose

1. Introduction & Context

In the fast-evolving landscape of mobile development, ensuring that your build pipeline is robust, repeatable, and scalable is essential. Expo, an open-source framework built on React Native, streamlines the development of cross-platform apps, and EAS Build (Expo Application Services Build) provides a modern, cloud-powered system for building and distributing those apps.

However, complex dependencies (Node, Java, Android SDKs, Expo CLI, EAS CLI) can lead to “works on my machine” issues and slow onboarding. Containerization—using Docker and particularly Docker Compose—has become the go-to solution for environmental parity across local development and CI/CD. This blog takes a deep dive into integrating EAS Build and Docker Compose, drawing on official documentation and leading open-source examples for actionable guidance.

You’ll learn how to:

  • Prepare and configure your project for EAS in containers
  • Write Dockerfiles and Compose files for versatile local/automation workflows
  • Trigger builds, manage credentials, and persist artifacts
  • Adopt best practices and solve common problems
  • Leverage real-world setups for rapid adoption

2. Fundamentals: EAS Build and CI/CD with Expo

EAS Build is Expo’s recommended tool for building iOS/Android binaries, replacing deprecated local tools. Key steps for container or CI/CD operation include:

  • Initialize EAS:

    Text
    1npx eas-cli build:configure
    2

    Generates required eas.json, ensures projectId and credentials.

  • Define Build Profiles: (in eas.json)

    Json
    1{ 2 "build": { 3 "production": { "android": { "buildType": "apk" } } 4 } 5} 6
  • Authenticate Non-Interactively: Export an Expo access token (from Expo Account Settings):

    Text
    1export EXPO_TOKEN=your-token
    2

    Use this in Docker or CI/CD.

  • Trigger a Build:

    Bash
    1npx eas-cli build --platform android --non-interactive --profile production 2

    For iOS, builds run on Expo's cloud even if launched from Linux containers.

References:


3. Docker and Docker Compose: Essentials

To ensure reproducibility and scalability, encapsulate your build environment.

Example Dockerfile

Dockerfile
1FROM node:18-bullseye 2 3RUN apt-get update && apt-get install -y openjdk-11-jdk wget unzip python3 make g++ git 4RUN mkdir /sdk && wget https://dl.google.com/android/repository/commandlinetools-linux-9477386_latest.zip -O sdk.zip && \ 5 unzip sdk.zip -d /sdk && rm sdk.zip 6 7ENV ANDROID_HOME=/sdk 8ENV PATH=$PATH:/sdk/cmdline-tools/latest/bin:/sdk/platform-tools:/sdk/emulator 9 10WORKDIR /app 11COPY package*.json ./ 12RUN npm install 13COPY . . 14RUN npm install -g expo-cli eas-cli 15 16CMD ["bash"] 17

docker-compose.yml

Yaml
1version: "3.8" 2 3services: 4 expo-eas: 5 build: . 6 volumes: 7 - ./:/app 8 - node_modules:/app/node_modules 9 - expo_cache:/app/.expo 10 environment: 11 - EXPO_TOKEN=${EXPO_TOKEN} 12 - EAS_NO_VCS=1 13 tty: true 14 command: bash 15 16volumes: 17 node_modules: 18 expo_cache: 19

All expo-related ports can be exposed as needed for local dev.


4. Step-by-Step: Building, Running, and Automating EAS with Docker Compose

  1. Set up .env with secrets (never commit!):

    Text
    1EXPO_TOKEN=your-token
    2
  2. Boot the service/interactively test:

    Text
    1docker compose up --build
    2docker compose run --rm expo-eas bash
    3
  3. Trigger EAS Builds: Inside the container:

    Text
    1npx eas-cli build --platform android --non-interactive
    2npx eas-cli build --platform ios --non-interactive
    3
  4. Automate with npm scripts: Add to package.json:

    Json
    1"scripts": { 2 "eas:build:android": "docker compose run --rm expo-eas npx eas-cli build --platform android --non-interactive" 3} 4
  5. CI/CD Workflow Example (GitHub Actions):

    Yaml
    1jobs: 2 build: 3 runs-on: ubuntu-latest 4 steps: 5 - uses: actions/checkout@v3 6 - run: docker compose up --build 7 env: 8 EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }} 9
  6. Persist Artifacts: Use named volumes or bind-mount artifact folders for access after build.

  7. Multi-Service Compose: Add APIs or DB services in the same compose file for integrated end-to-end workflows.


5. Troubleshooting, Best Practices, and Real-World Tips

Common Issues & Solutions:

  • Node modules permissions: Use named volumes, fix with chown if needed.
  • Credential/Token errors: Always export EXPO_TOKEN/environment var, never use interactive login in containers.
  • Android SDK issues: Pin tool versions, explicitly set ANDROID_HOME/PATH.
  • Artifact loss: Mount output directories as volumes to host.
  • iOS builds: Always run via EAS cloud; never locally on Linux.

Best Practices:

  • Always pin tool versions in Dockerfile.
  • Never bake tokens/secrets into images.
  • Run all EAS CLI invocations in non-interactive mode.
  • Keep a .dockerignore file to reduce build context and avoid leaking sensitive info.

References:


6. Case Studies: Community Setups and Extended Workflows

TomTom2028/eas-build-docker

  • Focuses on repeatable Android EAS builds, pinning system dependencies, robust use of Compose volumes.
  • CI and local runs are virtually identical, using EXPO_TOKEN for automated authentication.

expo-starter/expo-self-host-with-docker

  • Shows a dual-stack (frontend + API) Compose environment.
  • Uses volume mounting for hot-reloading, exposes all required ports for device/simulator sync.
  • Example config presented above.

Extended Patterns:

  • Multi-stage Compose for unit/integration testing, device farms, artifact storage, and publishing.
  • Use of .env for secret injection; central README instructions for onboarding.

7. Conclusion and Further Resources

To summarize:

  • Containerize with purpose-built Dockerfiles/Compose for Expo/EAS projects.
  • Use environment variables for non-interactive, secure, repeatable builds.
  • Leverage official documentation and exemplary GitHub projects for reference and troubleshooting.
  • Consistently use named volumes, careful credential management, and CI/CD parity for robust builds.

Further Reading

Recommended Articles

Discover more articles you might find interesting

Implementing LangGraph REST API with FastAPI
Technical Insights

Implementing LangGraph REST API with FastAPI

This guide provides a comprehensive implementation plan for building a LangGraph REST API using FastAPI, covering environment setup, agent definitions, endpoint creation, testing, and deployment.

2101050
Jun 18
153
Read More
DeepSite v2 Practical Guide
Technical Insights

DeepSite v2 Practical Guide

A comprehensive guide to DeepSite v2, covering its features, installation, and advanced workflows.

2101050
Jun 21
112
Read More
Fastify OpenTelemetry: Logging, Metrics, and Tracing in Practice
Technical Insights

Fastify OpenTelemetry: Logging, Metrics, and Tracing in Practice

Learn how to implement logging, metrics, and tracing in Fastify using OpenTelemetry.

2101050
Jul 11
106
Read More
Creating Diverse Logo Designs with Flux Model and ComfyUI
Technical Insights

Creating Diverse Logo Designs with Flux Model and ComfyUI

Learn to leverage the Flux model and ComfyUI for unique logo designs through effective prompts and examples.

2101050
Jan 10
93
Read More
Formatting Dates in TypeScript to UTC
Technical Insights

Formatting Dates in TypeScript to UTC

A guide on how to format dates in TypeScript to the specific format YYYY-MM-DDTHH:mm:ss+00:00.

2101050
Dec 19
83
Read More
Implementing a Custom Chat Model with LangChain
Technical Insights

Implementing a Custom Chat Model with LangChain

This guide provides a comprehensive blueprint for creating a custom chat model by subclassing LangChain's BaseChatModel, including configuration, method overrides, and error handling.

2101050
Jun 17
78
Read More