0%

Frontend

EAS Update(OTA)의 환경 변수 함정

전성진··수정됨 2026.07.21

EAS Update(OTA)의 환경 변수 함정

ota.webp

1. 문제 상황

앱 스토어에 배포된 앱에서 다음과 같은 이상 현상이 발생했다.

  • 앱을 처음 실행하면 → 상용 API 정상 연결

  • 앱을 백그라운드에 뒀다가 다시 열면 → 개발 API로 연결됨

처음에는 앱 재시작 로직, 세션 처리, 캐시 문제로 의심했다.
하지만 실제 원인은 전혀 다른 곳에 있었다.


2. 원인: eas buildeas update는 환경 변수를 다르게 처리한다

Expo 프로젝트에서는 보통 eas.json에 환경 변수를 다음과 같이 설정한다.

{
  "build": {
    "production": {
      "channel": "production",
      "env": {
        "EXPO_PUBLIC_API_BASE_URL": "https://api.example.com",
        "EXPO_PUBLIC_IS_MOCK": "false"
      }
    }
  }
}

eas build --profile production으로 빌드할 때는 위 env 블록이 네이티브 바이너리에 번들링된다.

즉, 앱 스토어에 올라가는 최초 빌드에는 정상적으로 상용 API 주소가 포함된다.

문제는 OTA 업데이트에서 발생한다.

npx eas update --branch production --message "수정 내용"

eas updateeas.jsonenv 블록을 읽지 않는다.
대신 명령을 실행하는 시점의 로컬 환경 변수.env 파일들을 읽어서 JS 번들을 빌드한다.

명령환경 변수 소스eas build --profile productioneas.jsonenv 블록eas update --branch production로컬 환경 변수 및 .env 파일

결과적으로 eas buildeas update는 같은 production 대상이라도 환경 변수 주입 방식이 다르다.


3. 두 번째 함정: .env.local의 우선순위

Expo / Node.js 기반 환경에서 .env 파일은 일반적으로 다음 우선순위로 로드된다.

  1. .env.local

  2. .env.[NODE_ENV]

    • 예: .env.production, .env.development

  3. .env

즉, .env.local이 가장 높은 우선순위를 가진다.

로컬 개발 편의를 위해 .env.local에 다음과 같이 개발 API를 넣어두는 경우가 많다.

EXPO_PUBLIC_IS_MOCK=false
EXPO_PUBLIC_API_BASE_URL=https://dev-api.example.com

이 상태에서 eas update --branch production을 실행하면,
.env.local이 가장 먼저 적용되기 때문에 production 브랜치에 배포되는 OTA JS 번들에 개발 API URL이 그대로 포함될 수 있다.

즉, 앱 스토어 빌드는 상용 API를 바라보고 있어도,
OTA 업데이트로 내려간 JS 번들은 개발 API를 바라보는 상황이 발생한다.


4. 세 번째 함정: .env.developmenteas update 시 자동 적용되지 않는다

다음과 같이 생각할 수 있다.

.env.development에 개발 API를 넣었으니,
eas update --branch preview를 실행하면 자동으로 개발 API가 적용되지 않을까?

하지만 그렇지 않다.

eas update는 기본적으로 NODE_ENV=production 환경에서 실행된다.
따라서 .env.developmentNODE_ENV=development일 때만 로드된다.

실행 명령NODE_ENV로드되는 .env 파일npx expo startdevelopment.env.development, .env.localeas buildproduction.env.production, .env.localeas updateproduction.env.production, .env.local

결론적으로 eas update는 브랜치가 previewproduction이든 기본적으로 NODE_ENV=production으로 실행된다.
따라서 .env.development가 자동으로 적용될 것이라고 기대하면 안 된다.


5. 버그가 백그라운드 전환 시 나타난 이유

현상은 다음 순서로 발생했다.

  1. 앱 최초 설치

    • eas build로 생성된 네이티브 바이너리 실행

    • eas.json의 production env 적용

    • 상용 API 정상 연결

  2. 앱 백그라운드 대기 중

    • Expo Updates가 새 OTA 번들을 자동 다운로드

  3. 앱 포어그라운드 복귀 또는 다음 실행

    • 다운로드된 OTA 번들이 적용됨

    • 이 OTA 번들에는 .env.local의 개발 API URL이 포함되어 있음

    • 결과적으로 개발 API로 연결됨

즉, 첫 실행은 정상인데 앱을 다시 열었을 때 문제가 발생한 이유는,
최초 실행 시점에는 네이티브 빌드에 포함된 상용 API가 사용되고,
이후 OTA 업데이트가 적용되면서 개발 API가 포함된 JS 번들로 교체되었기 때문이다.


6. 해결 방법

6-1. 즉각 해결: 올바른 환경 변수로 OTA 재배포

production OTA를 다시 배포할 때 환경 변수를 명시적으로 주입한다.

EXPO_PUBLIC_API_BASE_URL=https://api.example.com \
EXPO_PUBLIC_IS_MOCK=false \
npx eas update --branch production --message "fix: 환경 변수 수정"

이렇게 하면 로컬 .env.local에 잘못된 값이 있더라도,
명령 실행 시점에 명시한 환경 변수가 우선 적용된다.


6-2. 근본 해결: .env.local에서 API URL 제거

.env.local은 개인 로컬 설정용으로만 사용하는 것이 안전하다.

예를 들어 로컬 IP, 개인 테스트 플래그, 임시 옵션 정도만 넣고,
공용 API URL은 넣지 않는 편이 좋다.

# .env.local

EXPO_PUBLIC_IS_MOCK=false

# API URL은 .env.local에 넣지 않는다.
# EXPO_PUBLIC_API_BASE_URL=https://dev-api.example.com

개발 서버 실행 시에는 .env.development의 값이 자동으로 적용되므로,
.env.local에 API URL을 중복 선언할 필요가 없다.


7. 권장 환경 파일 구성

.env.development

EXPO_PUBLIC_API_BASE_URL=https://dev-api.example.com
EXPO_PUBLIC_IS_MOCK=false

.env.production

EXPO_PUBLIC_API_BASE_URL=https://api.example.com
EXPO_PUBLIC_IS_MOCK=false

.env.local

# 개인 로컬 설정만 작성
# 공용 API URL 작성 금지

8. 정리

구분환경 변수 소스주의사항eas buildeas.jsonenv 블록profile / channel 기반 분리 가능eas update로컬 환경 변수 및 .env 파일.env.local이 우선 적용될 수 있음eas updateNODE_ENVproduction.env.development는 자동 적용되지 않음


9. OTA 업데이트 전 체크리스트

OTA 업데이트를 배포하기 전에는 반드시 아래 항목을 확인한다.

  • .env.local에 API URL이 하드코딩되어 있지 않은지 확인

  • production OTA 배포 시 상용 API URL이 적용되는지 확인

  • preview OTA 배포 시 의도한 API URL이 적용되는지 확인

  • eas update 실행 전에 현재 로컬 환경 변수를 확인

  • 필요하면 환경 변수를 명시적으로 주입하여 실행

  • 배포 후 실제 앱에서 API Base URL 로그 또는 네트워크 요청 확인


10. 핵심 결론

eas buildeas update는 같은 production 환경처럼 보여도 환경 변수 처리 방식이 다르다.

eas build  → eas.json의 env 블록 사용
eas update → 로컬 환경 변수 및 .env 파일 사용

특히 .env.local은 우선순위가 높기 때문에,
로컬 개발용 API URL이 들어있으면 production OTA 번들을 오염시킬 수 있다.

따라서 OTA 업데이트를 사용하는 프로젝트에서는
.env.local에 공용 API URL을 넣지 않고,
production 업데이트 시 환경 변수를 명시적으로 주입하는 방식이 가장 안전하다.

읽기 도구

8분 읽기

이 글이 도움이 되었나요?

다음으로 읽기