RSS

새 컴퓨터로 Flutter 프로젝트를 안전하게 이전하는 방법

.env부터 Android 키스토어, Firebase, 소셜 로그인, iOS 서명까지 한 번에 옮기는 실전 체크리스트

Flutter 프로젝트를 다른 컴퓨터로 옮길 때 가장 흔한 착각은 “Git 저장소만 clone하면 되겠지”라는 생각입니다. 소스 코드는 돌아오지만 .gitignore에 들어간 환경 파일, Firebase 설정, 앱 서명 키가 빠져 있으면 개발 빌드부터 스토어 업데이트까지 곳곳에서 막힙니다.

이 글은 다음 상황을 기준으로 설명합니다.

  • Flutter 앱을 기존 컴퓨터에서 새 컴퓨터로 이전합니다.
  • Android와 iOS를 함께 지원합니다.
  • dev, stg, prod 같은 flavor별 .env와 Firebase 설정을 사용합니다.
  • 이미 배포한 Android 앱이 있어 기존 서명 체인을 유지해야 합니다.

가장 중요한 원칙부터 말씀드리면 다음과 같습니다.

Git에는 재생성 가능한 소스를, 비밀 관리 도구에는 복구 원본을, 새 컴퓨터에는 필요한 파일만 복원합니다.

1. 먼저 파일을 네 종류로 나눕니다

모든 파일을 통째로 압축해 옮기기보다 복구 방법에 따라 나누면 빠뜨릴 항목이 줄고 비밀 유출 위험도 낮아집니다.

분류 예시 처리 방법
Git으로 복구 lib/, assets/, pubspec.yaml, pubspec.lock, .fvmrc, Gradle Wrapper, Xcode 프로젝트 커밋 후 clone
안전하게 별도 백업 .env.*, release 키스토어, 키 비밀번호, Apple .p12·.p8 암호화 금고/비밀번호 관리자에 보관
콘솔에서 다시 다운로드 google-services.json, GoogleService-Info.plist, provisioning profile Firebase·Apple 콘솔 권한 확보 후 재다운로드 가능
새 컴퓨터에서 재생성 build/, .dart_tool/, .gradle/, Pods/, local.properties, 에뮬레이터 백업하지 않음

여기서 가장 복구하기 어려운 것은 Android release 키스토어입니다. Firebase 설정 파일은 콘솔에서 다시 받을 수 있지만, 자체 관리 중인 앱 서명 개인 키는 같은 값으로 다시 만들 수 없습니다.

2. .env는 설정 파일이지 비밀 금고가 아닙니다

Flutter에서 flutter_dotenv를 사용하면 보통 다음처럼 파일을 asset으로 등록합니다.

flutter:
  assets:
    - .env.dev
    - .env.stg
    - .env.prod

이 방식의 .env는 최종 APK나 IPA 안에 포함됩니다. 난독화를 하더라도 값을 추출할 수 있으므로 다음 값은 넣지 않는 것이 원칙입니다.

  • 서버 관리자 토큰
  • 데이터베이스 비밀번호
  • Firebase 서비스 계정 JSON
  • AWS Secret Access Key
  • 결제·메일·AI API의 서버용 비밀 키
  • 유출되면 제3자가 독립적으로 권한을 행사할 수 있는 OAuth client secret

앱에 들어가도 되는 값은 “사용자에게 안 보이게 하는 값”이 아니라 “노출되어도 서버 측 권한이 생기지 않는 값”이어야 합니다.

  • API base URL
  • flavor 이름
  • 기능 플래그
  • 모바일 SDK 초기화에 필요한 공개 식별자
  • 앱 패키지명과 서명 인증서에 사용 제한을 건 클라이언트용 API 키

SECRET이라는 이름이 붙은 값을 모바일 SDK가 요구하더라도 앱에서는 결국 추출할 수 있다고 가정해야 합니다. 가능한 경우 서버 교환 방식으로 옮기고, 불가능하다면 공급자 콘솔에서 패키지명·서명 지문·redirect URI 제한을 최대한 적용합니다. flutter_dotenv도 민감한 키와 토큰을 Flutter 앱에 저장하지 말라고 명시합니다.

권장 파일 구성

.env.example      # 키 이름과 예시만 Git에 커밋
.env.dev          # 실제 값, Git 제외
.env.stg          # 실제 값, Git 제외
.env.prod         # 실제 값, Git 제외
# .env.example
API_BASE_URL=https://example.invalid
GOOGLE_SERVER_CLIENT_ID=
KAKAO_NATIVE_APP_KEY=
NAVER_CLIENT_ID=

새 컴퓨터에서는 템플릿을 복사한 뒤 승인된 보관소에서 실제 값을 채웁니다.

cp .env.example .env.dev
cp .env.example .env.stg
cp .env.example .env.prod

중요한 점은 .env.example을 최신 상태로 유지하는 것입니다. 값은 비워도 되지만 앱이 읽는 키 이름이 빠지면 새 컴퓨터에서 원인을 찾기 어려운 런타임 오류가 생깁니다.

3. Android에서 반드시 백업할 것

3-1. release 키스토어와 key.properties

기존 앱 업데이트에서 가장 중요한 두 파일입니다.

android/app-release.jks   # 프로젝트에 따라 파일명·위치는 다를 수 있음
android/key.properties

key.properties는 보통 아래 네 값을 연결합니다.

storePassword=<키스토어 비밀번호>
keyPassword=<키 비밀번호>
keyAlias=<키 별칭>
storeFile=<키스토어 파일 경로>

키스토어 파일만 있고 비밀번호나 alias를 모르면 실제 서명을 하지 못합니다. 반대로 key.properties만 백업하면 개인 키가 없으므로 아무 소용이 없습니다. 반드시 한 세트로 복구하되, 다음처럼 보관 위치를 분리하는 편이 안전합니다.

  • .jks: 접근 통제가 있는 암호화 파일 보관소에 2개 이상 복제
  • 비밀번호·alias·복구 설명: 팀 비밀번호 관리자
  • 접근 권한: 최소 인원만 부여하고 퇴사·역할 변경 시 회수
  • CI용 base64 값과 로컬 원본: 서로 독립적으로 관리

GitHub Actions 같은 CI secret은 배포 주입 수단이지 유일한 백업 원본으로 삼아서는 안 됩니다. 원본 .jks와 속성 정보는 별도 금고에서도 복구할 수 있어야 합니다.

기존에 배포된 앱이라면 컴퓨터를 옮긴다는 이유로 새 키스토어를 만들면 안 됩니다. 같은 애플리케이션의 업데이트는 기존 서명 관계를 이어가야 합니다.

3-2. Play App Signing 상태를 먼저 확인합니다

Google Play의 Play App Signing을 사용하는 경우 키가 두 종류일 수 있습니다.

  • App signing key: 사용자의 기기에 설치되는 앱을 Google Play가 최종 서명하는 키
  • Upload key: 개발팀이 AAB를 Play Console에 올릴 때 사용하는 키

Play App Signing을 사용하면 upload key를 잃거나 유출했을 때 Play Console에서 재설정을 요청할 수 있습니다. 반면 Play App Signing을 사용하지 않고 app signing key를 직접 관리하는 앱은 그 키를 잃으면 기존 앱 업데이트가 불가능할 수 있습니다.

따라서 이전 전에 Play Console의 앱 서명 화면에서 다음 항목을 기록합니다.

  • Play App Signing 사용 여부
  • 현재 로컬 키가 app signing key인지 upload key인지
  • app signing certificate의 SHA-1·SHA-256
  • upload certificate의 SHA-1·SHA-256
  • 키 재설정 권한이 있는 Play Console 관리자 계정
  • 2단계 인증 및 복구 코드 보관 위치

3-3. 서명 지문을 기록합니다

비밀번호는 명령줄 인자로 적지 않고 프롬프트에서 입력합니다.

keytool -list -v -keystore android/app-release.jks

최소한 다음 항목을 운영 문서에 값의 위치와 함께 기록합니다.

  • alias
  • SHA-1
  • SHA-256
  • 인증서 유효기간
  • Play Console에 등록된 인증서와 일치하는지

백업 파일이 손상되거나 다른 키로 바뀌는 사고를 잡기 위해 키스토어의 SHA-256 체크섬도 함께 기록해 둡니다. 체크섬은 키 비밀번호나 인증서 지문과는 별개의 "파일 동일성" 확인값입니다.

shasum -a 256 android/app-release.jks

인증서 지문은 Firebase Authentication, Google 로그인, App Links, 일부 소셜 로그인 설정에 사용됩니다. 새 컴퓨터에서도 같은 release 키스토어를 사용하면 release 지문은 바뀌지 않습니다.

3-4. debug 키스토어는 release 키와 다르게 다룹니다

~/.android/debug.keystore는 보통 컴퓨터마다 자동 생성되므로 필수 백업 대상이 아닙니다. 다만 새 컴퓨터에서 새 debug 키가 만들어지면 SHA-1과 SHA-256이 달라져 개발 환경의 Google 로그인이 실패할 수 있습니다.

해결 방법은 다음 두 가지 중 하나입니다.

  1. 새 debug 인증서 지문을 dev Firebase·Google Cloud·소셜 로그인 콘솔에 추가합니다.
  2. 팀이 의도적으로 공용 debug 키를 관리한다면 release 키와 분리해 제한된 보관소에서 배포합니다.

release 키를 debug 편의를 위해 공유하거나 debug 빌드에 사용하는 것은 피해야 합니다.

4. Firebase 설정 파일은 flavor별로 맞춥니다

flavor가 dev, stg, prod라면 Android 설정 파일도 보통 환경별로 나뉩니다.

android/app/src/dev/google-services.json
android/app/src/stg/google-services.json
android/app/src/prod/google-services.json

새 컴퓨터에서 아무 파일이나 복사하면 빌드는 되더라도 개발 앱이 운영 Firebase로 연결되는 사고가 생길 수 있습니다. 각 파일 안의 프로젝트와 Android package name이 해당 flavor의 applicationId와 일치하는지 확인합니다.

Firebase의 모바일 API 키는 프로젝트 식별용이며 그 자체가 데이터 접근 권한을 부여하는 비밀은 아닙니다. 실제 데이터 보호는 Security Rules, IAM, App Check 등이 담당합니다. 그래도 환경 혼선을 막고 저장소 정책을 단순하게 유지하기 위해 설정 파일을 Git에서 제외하고 빌드 시 주입하는 팀도 많습니다.

반드시 구분해야 할 파일도 있습니다.

  • google-services.json: Android 앱에 포함되는 클라이언트 설정
  • GoogleService-Info.plist: iOS 앱에 포함되는 클라이언트 설정
  • Firebase service account JSON: 서버 관리자 권한을 가질 수 있는 비밀 파일, 모바일 앱에 절대 포함하지 않음

설정 파일은 Firebase Console에서 다시 다운로드할 수 있으므로 “유일한 백업본”을 만들기보다 콘솔 접근 권한과 올바른 프로젝트 매핑을 문서화하는 것이 더 중요합니다.

5. 소셜 로그인과 딥링크도 같이 확인합니다

새 컴퓨터 이식 후 앱은 실행되는데 로그인만 실패하는 경우가 많습니다. 다음 매핑을 환경별로 기록해 두면 빠르게 복구할 수 있습니다.

항목 확인할 값
Android package name, release/debug SHA-1·SHA-256, 필요 시 key hash
iOS bundle ID, URL scheme, Associated Domains
Google Android OAuth client, server client ID, 승인된 redirect 설정
Kakao·Naver 등 네이티브 앱 키, 패키지·번들 ID, 키 해시, callback scheme
App Links 도메인의 assetlinks.json과 실제 서명 인증서 지문
Universal Links apple-app-site-association과 Team ID·bundle ID

같은 release 키를 복구했다면 운영용 Android 지문은 유지됩니다. 새 debug 키를 사용하거나 새 flavor를 추가했을 때만 공급자 콘솔 등록이 추가로 필요합니다.

6. 새 컴퓨터에 개발 환경을 설치합니다

SDK 폴더 자체를 복사하기보다 프로젝트가 요구하는 버전을 새로 설치합니다.

공통

  • Git
  • Flutter SDK 또는 FVM
  • IDE와 Flutter·Dart 플러그인
  • 프로젝트에 고정된 Flutter/Dart 버전
  • pubspec.lock에 고정된 패키지

FVM을 사용하고 .fvmrc가 Git에 있다면 해당 버전을 설치한 뒤 프로젝트 명령도 FVM을 통해 실행합니다.

fvm install
fvm flutter doctor -v
fvm flutter pub get

Android

  • Android Studio
  • Android SDK Platform
  • Android SDK Build-Tools
  • Android SDK Command-line Tools
  • Platform-Tools
  • 프로젝트가 요구하는 NDK·CMake
  • 프로젝트/Flutter 버전과 호환되는 JDK

설치 후 라이선스와 도구 체인을 확인합니다.

fvm flutter doctor --android-licenses
fvm flutter doctor -v
fvm flutter devices

JDK는 build.gradle의 source compatibility 숫자만 보고 임의로 선택하면 안 됩니다. Flutter·Gradle·Android Gradle Plugin의 조합과 CI에서 사용하는 버전을 함께 맞추는 것이 안전합니다.

iOS 빌드 환경

  • macOS와 Xcode
  • Xcode Command Line Tools
  • CocoaPods 또는 프로젝트가 정한 의존성 도구
  • Apple Developer 및 App Store Connect 권한
  • 배포 인증서와 private key를 담은 .p12 및 비밀번호
  • provisioning profile
  • App Store Connect API 키 .p8를 사용한다면 Key ID·Issuer ID와 원본 키

자동 서명을 사용하면 일부 인증서와 프로파일은 다시 만들 수 있지만, 계정 권한과 2단계 인증 복구 수단이 먼저 확보되어야 합니다. .p8 개인 키는 발급 후 다시 다운로드할 수 없는 경우가 있으므로 별도로 보관합니다.

7. 백업하지 않아도 되는 파일

다음 파일은 경로나 캐시가 이전 컴퓨터에 종속되므로 새로 만듭니다.

build/
.dart_tool/
.gradle/
android/local.properties
ios/Pods/
ios/.symlinks/
DerivedData/
에뮬레이터·시뮬레이터 데이터
IDE 개인 설정

특히 android/local.properties에는 Android SDK와 Flutter SDK의 로컬 절대 경로가 들어갑니다. 다른 컴퓨터로 그대로 복사하면 오히려 잘못된 경로 때문에 빌드가 깨질 수 있습니다.

8. 실제 이식 순서

기존 컴퓨터에서

  1. git status로 미커밋 소스가 없는지 확인합니다.
  2. .env.example, .fvmrc, pubspec.lock, Gradle Wrapper가 추적 중인지 확인합니다.
  3. .env.dev/.stg/.prod를 승인된 비밀 보관소에 백업합니다.
  4. Android release .jkskey.properties를 백업합니다.
  5. Play App Signing 상태와 인증서 지문을 기록합니다.
  6. flavor별 Firebase 프로젝트·package name·bundle ID 매핑을 기록합니다.
  7. iOS 배포가 필요하면 .p12, 프로파일, .p8와 관련 ID를 백업합니다.
  8. Play Console, Firebase, Apple, 소셜 로그인 콘솔의 관리자 권한과 2FA 복구 수단을 확인합니다.
  9. 가능하면 임시 폴더나 별도 머신에서 복원 리허설을 진행합니다.

새 컴퓨터에서

  1. 저장소를 clone합니다.
  2. 프로젝트가 고정한 Flutter 버전과 Android/iOS 도구 체인을 설치합니다.
  3. flutter doctor -v의 오류를 모두 정리합니다.
  4. .env.example로 환경 파일을 만들고 실제 값을 복원합니다.
  5. flavor별 Firebase 설정 파일을 올바른 경로에 둡니다.
  6. Android release 키스토어와 key.properties를 복원합니다.
  7. storeFile이 새 컴퓨터에서도 유효한 상대경로인지 확인합니다.
  8. 의존성을 받고 정적 분석과 dev 빌드를 실행합니다.
  9. 로그인·푸시·딥링크를 실기기에서 확인합니다.
  10. prod release AAB를 만들고 기존 인증서로 서명되었는지 확인합니다.

예를 들어 flavor 구조의 프로젝트라면 다음 순서로 검증할 수 있습니다.

fvm flutter pub get
fvm flutter analyze
fvm flutter build apk --debug --flavor dev -t lib/main_dev.dart
fvm flutter build appbundle --release --flavor prod -t lib/main_prod.dart

키스토어 경로나 서명 설정을 바꾼 뒤 이상한 캐시 문제가 생겼을 때만 flutter clean 후 다시 빌드합니다.

9. 복원 완료 판정표

검사 완료 기준
도구 체인 flutter doctor -v에 필요한 플랫폼 오류 없음
의존성 flutter pub get 성공, lockfile의 불필요한 변경 없음
환경 파일 모든 flavor 파일 존재, 키 누락 없음, Git 미추적
개발 빌드 dev debug 앱 설치·실행 성공
Firebase flavor별 프로젝트가 의도한 환경과 일치
로그인 release/debug 인증서 구분 후 Google·소셜 로그인 성공
푸시 해당 flavor의 FCM 토큰 발급·수신 성공
딥링크 App Links/Universal Links가 의도한 앱으로 열림
Android release prod AAB 생성 성공, 기존 upload/signing 체인 확인
iOS release Archive 또는 IPA 생성, 서명·프로파일·entitlement 확인
보안 .env, .jks, key.properties, 서비스 계정 등이 Git에 없음

마지막으로 Git 추적 여부를 확인합니다.

git status --short
git ls-files | rg '(^|/)\.env(\.|$)|\.(jks|keystore)$|key\.properties$|google-services\.json$|GoogleService-Info\.plist$'

팀 정책상 모두 비추적 대상이라면 두 번째 명령은 결과가 없어야 합니다. 단, 공개 클라이언트 설정을 의도적으로 추적하는 프로젝트라면 해당 정책에 따라 판단합니다.

듀오랩스가 보는 관점

모바일 앱의 개발 환경을 이전할 때는 단순히 “새 컴퓨터에서 빌드가 되는가”만 확인해서는 부족합니다. 기존 앱의 업데이트 가능성, 환경별 외부 서비스 연결, CI/CD 복구 가능성까지 함께 확인해야 이전이 끝났다고 볼 수 있습니다.

특히 Android 키스토어처럼 다시 만들 수 없는 자산은 개발자 개인의 컴퓨터에만 두지 않고, 권한이 통제된 팀 보관소에서 관리해야 합니다. 환경 파일과 Firebase 설정도 누가 언제 어떤 환경을 복구하더라도 같은 결과를 얻을 수 있도록 경로와 관리 책임을 문서화하는 것이 좋습니다.

마치며

Flutter 프로젝트 이식은 SDK 설치 작업보다 “Git 밖에 있는 자산의 복구”가 본질입니다. .env는 다시 만들 수 있고 Firebase 설정은 다시 받을 수 있지만, Android 서명 키는 앱의 업데이트 가능성과 직결됩니다.

그래서 가장 현실적인 우선순위는 다음 세 가지로 정리할 수 있습니다.

  1. 기존 Android 앱의 release/upload 키와 비밀번호를 먼저 보존합니다.
  2. .env를 비밀 금고로 착각하지 않고 서버 비밀은 앱 밖으로 옮깁니다.
  3. 백업 파일의 존재만 확인하지 않고 새 환경에서 release 빌드까지 복원해 봅니다.

참고 자료