FVM으로 Flutter 버전 관리하기: 프로젝트별 SDK 고정부터 CI까지
Flutter 프로젝트가 하나뿐일 때는 시스템에 설치된 SDK 하나로도 충분해 보입니다. 하지만 유지보수 중인 앱, 신규 앱, 검증용 브랜치가 서로 다른 Flutter 버전을 요구하기 시작하면 전역 SDK를 계속 바꾸는 방식은 금방 불편해집니다.
FVM(Flutter Version Management)은 여러 Flutter SDK를 캐시에 보관하고 프로젝트마다 사용할 버전을 선택해 주는 도구입니다. 개발자, IDE, CI가 같은 버전을 바라보게 만들면 “내 환경에서는 되는데 빌드 서버에서는 실패하는” 문제를 줄일 수 있습니다.
왜 이 주제가 중요한가
Flutter SDK가 달라지면 Dart 버전, 빌드 도구의 동작, 생성되는 네이티브 프로젝트 파일, 패키지 호환 범위가 함께 달라질 수 있습니다. 전역 Flutter를 업그레이드한 뒤 기존 프로젝트까지 갑자기 영향을 받는 이유입니다.
FVM은 프로젝트에 버전 선택 정보를 남기고 실제 SDK는 공용 캐시에 보관합니다. 프로젝트마다 SDK 전체를 복사하지 않으면서도 서로 다른 버전을 사용할 수 있어, 여러 앱을 관리하거나 단계적으로 업그레이드할 때 특히 유용합니다.
핵심 개념
FVM 프로젝트 설정은 크게 두 부분으로 나뉩니다.
- .fvmrc: 프로젝트가 사용할 Flutter 버전과 FVM 옵션을 기록하는 설정 파일입니다. 팀이 같은 버전을 사용하도록 Git에 포함합니다.
- .fvm/: 선택한 SDK를 가리키는 심볼릭 링크와 내부 정보가 들어갑니다. FVM 3 이상에서는 디렉터리 전체를 Git에서 제외하는 구성이 권장됩니다.
프로젝트 루트에서 fvm use를 실행하면 필요한 SDK가 캐시에 없을 경우 내려받고, .fvmrc와 .fvm/flutter_sdk 연결을 구성합니다. 기본 설정에서는 SDK 변경 후 flutter pub get도 실행합니다.
FVM은 Flutter SDK 버전을 관리하는 도구입니다. Dart·Flutter 패키지 잠금은 pubspec.lock, Android JDK와 Gradle, iOS의 Xcode와 CocoaPods 같은 다른 도구 버전은 각자의 방식으로 별도 관리해야 합니다.
설치하기
FVM 공식 문서는 시스템의 기본 Flutter SDK는 Flutter 공식 설치 방법으로 준비하고, 프로젝트별 SDK 버전을 FVM으로 관리하는 방식을 권장합니다. FVM 자체는 환경에 맞는 방법으로 설치할 수 있습니다.
macOS와 Linux에서 공식 설치 스크립트를 사용하는 방법은 다음과 같습니다.
curl -fsSL https://fvm.app/install.sh | bashmacOS에서 Homebrew를 사용한다면 다음 명령도 가능합니다.
brew install fvmWindows는 공식 설치 문서에서 제공하는 Chocolatey 또는 독립 실행형 패키지 방법을 선택할 수 있습니다. 설치가 끝나면 새 터미널을 열고 다음 명령으로 상태를 확인합니다.
fvm --version
fvm doctor보안 정책상 원격 설치 스크립트를 바로 실행할 수 없는 환경이라면 공식 GitHub 릴리스의 독립 실행형 패키지를 검토하는 편이 적합합니다.
실제 적용 포인트
1. 프로젝트에 Flutter 버전 고정하기
먼저 설치 가능한 릴리스를 확인하고 프로젝트 루트에서 버전을 선택합니다.
fvm releases
fvm use <exact-version>현재 stable 채널의 최신 릴리스를 그 시점의 구체적인 버전으로 고정하려면 다음 명령을 사용할 수 있습니다.
fvm use stable --pin설정 후에는 FVM을 통해 실제 버전을 확인합니다.
fvm flutter --version
fvm flutter doctor출시 중인 앱과 CI에서는 stable 같은 움직이는 채널 이름보다 정확한 버전이 기록된 .fvmrc를 기준으로 작업하는 편이 재현성이 좋습니다.
2. Flutter와 Dart 명령 실행하기
터미널과 자동화 스크립트에서는 프로젝트 SDK가 확실히 선택되도록 FVM 프록시 명령을 사용합니다.
fvm flutter pub get
fvm flutter analyze
fvm flutter test
fvm flutter run
fvm dart run build_runner buildFVM은 현재 디렉터리의 .fvmrc, 상위 디렉터리의 .fvmrc, FVM 전역 버전, 시스템 PATH의 Flutter 순서로 SDK를 찾습니다. 모노레포 루트에 .fvmrc를 두면 하위 프로젝트가 같은 버전을 물려받도록 구성할 수 있습니다.
3. Git에 포함할 파일 구분하기
팀이 반드시 공유해야 하는 파일은 .fvmrc입니다. 반면 SDK 연결과 로컬 내부 정보가 들어 있는 .fvm/은 제외합니다.
.fvm/FVM은 updateGitIgnore 옵션이 활성화된 기본 설정에서 이 규칙을 자동으로 추가합니다. 오래된 글에서 .fvm/fvm_config.json을 커밋하라는 안내를 볼 수 있지만, 현재 문서에서는 이 파일을 레거시 호환용으로 설명합니다. 신규 구성은 .fvmrc를 기준으로 잡는 것이 명확합니다.
README에도 다음 두 가지를 짧게 남겨두면 새 팀원이 빠르게 환경을 맞출 수 있습니다.
- FVM 설치 방법
- 저장소를 받은 뒤 실행할 fvm install 명령
4. IDE 연결하기
VS Code는 프로젝트 루트의 .vscode 디렉터리 또는 VS Code 터미널 환경을 감지하면 FVM SDK를 사용하도록 설정을 자동 갱신할 수 있습니다. 버전을 바꾼 뒤 편집기가 이전 SDK를 계속 표시하면 창을 다시 불러오고 Flutter SDK 경로를 확인합니다.
Android Studio와 IntelliJ에서는 Flutter SDK 경로를 프로젝트의 .fvm/flutter_sdk로 지정합니다. 일부 IDE 버전은 심볼릭 링크를 실제 캐시 경로로 변환해 저장하므로 FVM 버전을 바꾼 뒤 SDK 경로를 다시 선택하거나 캐시를 새로 고쳐야 할 수 있습니다.
5. CI/CD에서도 같은 버전 사용하기
CI는 개발자 환경과 같은 .fvmrc를 읽어 SDK를 설치해야 합니다. 기본 흐름은 다음과 같습니다.
dart pub global activate fvm
fvm install
fvm flutter pub get
fvm flutter analyze
fvm flutter test
fvm flutter build appbundle --release실제 파이프라인에서는 FVM 실행 파일 경로와 SDK 캐시를 CI 환경에 맞게 구성합니다. 캐시 키에는 .fvmrc의 변경을 반영해 버전이 바뀌었을 때 잘못된 SDK를 재사용하지 않도록 합니다.
자주 쓰는 명령
| 목적 | 명령 |
|---|---|
| 설치된 SDK 목록 | fvm list |
| 설치 가능한 릴리스 | fvm releases |
| 프로젝트 버전 선택 | fvm use |
| .fvmrc 기준 SDK 설치 | fvm install |
| 프로젝트 SDK로 Flutter 실행 | fvm flutter |
| 프로젝트 SDK로 Dart 실행 | fvm dart |
| 특정 SDK로 일회성 테스트 | fvm spawn test |
| 환경 진단 | fvm doctor |
| 사용하지 않는 SDK 제거 | fvm remove |
fvm destroy는 전체 FVM 캐시와 설치된 SDK를 제거하는 되돌릴 수 없는 작업입니다. 일반적인 용량 정리에는 fvm list로 확인한 뒤 fvm remove로 필요한 버전만 지우는 편이 안전합니다.
안전한 Flutter 업그레이드 절차
SDK 업그레이드는 다음처럼 별도 변경으로 다루는 것이 좋습니다.
- 업그레이드 전용 브랜치를 만듭니다.
- fvm use로 목표 버전을 선택합니다.
- .fvmrc 변경 내용을 확인합니다.
- fvm flutter pub get을 실행하고 의존성 변화를 검토합니다.
- analyze, test, 실제 배포 빌드를 모두 실행합니다.
- Android와 iOS 네이티브 빌드도 각각 확인한 뒤 버전 변경을 커밋합니다.
새 버전을 잠깐 검증할 때는 프로젝트 설정을 바로 바꾸지 않고 fvm spawn으로 테스트할 수도 있습니다.
fvm spawn <candidate-version> test주의할 점
- 셸의 flutter 명령은 여전히 시스템 전역 SDK를 가리킬 수 있습니다. 스크립트와 CI에서는 fvm flutter를 사용해 모호함을 없애는 편이 좋습니다.
- .fvmrc를 Git에서 제외하면 팀원과 CI가 같은 버전을 재현할 수 없습니다.
- .fvm/을 커밋하면 큰 SDK 파일이나 환경별 심볼릭 링크가 저장소에 섞일 수 있습니다.
- Android Studio가 버전 변경을 반영하지 않으면 .fvm/flutter_sdk를 다시 선택하고 Gradle 동기화 또는 캐시 재시작을 진행합니다.
- 여러 SDK는 디스크 공간을 사용합니다. 사용하지 않는 버전은 목록을 확인한 뒤 선택적으로 제거합니다.
- 릴리스 버전에 fvm flutter upgrade를 실행하기보다 fvm use로 새 버전을 명시적으로 선택하고 검증합니다.
듀오랩스가 보는 관점
버전 매니저의 핵심 가치는 명령을 편하게 만드는 데만 있지 않습니다. 프로젝트가 어떤 SDK로 빌드되어야 하는지를 코드와 함께 기록하는 것이 더 중요합니다.
.fvmrc를 개발 환경의 계약으로 삼고 로컬, IDE, CI가 모두 같은 파일을 읽도록 구성하면 SDK 변경이 의도적인 리뷰 대상이 됩니다. 여기에 pubspec.lock과 네이티브 도구 버전 관리까지 함께 맞추면 Flutter 빌드의 재현성을 한 단계 더 높일 수 있습니다.
공식 문서
함께 읽기
- Flutter 앱 배포, `flutter build` 한 줄이면 끝인 줄 알았습니다Flutter 앱의 빌드 명령은 간단합니다. Android는 flutter build appbundle, iOS는 flutter build ipa로 결과물을 만들 수 있습니다. 그러나 팀이 반복해서 사용할 수 있는 배포 체계를 만들려면 그 뒤에 있는 서명, 권한, 스토어 API, 심사와 출시 절차까지 함께 설계해야 합니…
- Expo로 개발할 때 자주 쓰는 실행 명령어 모음Expo 앱을 개발하다 보면 명령어보다 “지금 다시 빌드해야 하나?”가 더 헷갈립니다. 화면 코드만 바꿨는데 Gradle 빌드를 다시 돌리기도 하고, 반대로 스플래시 이미지를 바꾼 뒤 Metro만 재시작해서 왜 그대로인지 한참 보기도 합니다.
- 새 컴퓨터로 Flutter 프로젝트를 안전하게 이전하는 방법Flutter 프로젝트를 다른 컴퓨터로 옮길 때 가장 흔한 착각은 “Git 저장소만 clone하면 되겠지”라는 생각입니다. 소스 코드는 돌아오지만 .gitignore에 들어간 환경 파일, Firebase 설정, 앱 서명 키가 빠져 있으면 개발 빌드부터 스토어 업데이트까지 곳곳에서 막힙니다.
- Flutter와 React Native, 장단점보다 먼저 봐야 할 기술 선택 기준앱 개발 상담에서 자주 나오는 질문이 있습니다. "Flutter와 React Native 중 무엇이 더 좋은가요?"
- EAS 배포와 앱 이관: 새 컴퓨터에서 빌드는 왜 쉬울까?모바일 앱의 운영 환경을 정리하다 보면 Android Keystore, iOS 인증서, Provisioning Profile 같은 낯선 자격 증명을 만나게 된다. 이런 파일을 보고 있으면 새로운 컴퓨터에서 앱을 다시 빌드하는 일이 상당히 복잡할 것처럼 느껴진다.