서비스 개발 기초 강의 내용을 개인적으로 정리했던 글 중 팀원들에게 가장 만족도가 높았던 글을 다시 재구성한 글입니다.
Version이 필요한 이유
버전(Version)는 소프트웨어 제품의 특정 릴리스에 대한 고유한 식별자다.
버저닝(Versioning)은 소프트웨어 제품에 Unique한 버전 이름, 버전 번호를 할당하는 것을 의미한다.
그렇다면 Version은 왜 필요한가?
만약 한 번 릴리스하고 더 이상 개발을 진행하지 않는 프로젝트라면 버저닝이 필요하지 않다.
하지만, 지속적으로 개발, 릴리스하는 경우엔 당연히 버전이 필요할 수밖에 없다. (다른 사람과 협업하는 경우 더더욱!)
아래 예시를 살펴보자.
이건 실제 내가 사용하는 앱의 앱스토어 버전 기록을 가져온 건데, 왼쪽 위의 숫자들이 버전 번호라고 생각하면 된다.
왼쪽 앱의 경우 어떤 기능이 추가됐는지 세세하게 작성된 반면, 오른쪽 앱은 간결하게 작성된 편이다.
사용자에게 위처럼 어떤 버전에서 무엇이 업데이트 됐는지 알려주기 위해서도 우리는 버저닝이 필요하다.
더 중요한 또 다른 이유는..
다른 사람과 함께 일할 때 특정 상태(버전)에 대한 통일된 명칭이 없다면 우리는 원활한 커뮤니케이션을 할 수 없기 때문이다.
예를 들어, 버전이 없는 상태에서 누군가 "뫄뫄씨, 우리 이번 신규 버전에 버그가 심해서 전에 그 릴리스한 버전 있잖아.. 거기로 롤백해야돼"라고 한다면 "전에 그 릴리스한 버전..? 그게 뭔데? 언제 버전?😧"라는 상황이 될 수 밖에 없다.
따라서, 협업하며 계속해서 개발, 릴리스하는 소프트웨어 엔지니어링엔 버전이 필수적이다!!
서론이 길었는데, 이제 Pyenv랑 Poetry로 넘어가서 앞서 강조한 파이썬 버전과 파이썬 프로젝트 버전 관리 방법을 살펴보자.
Pyenv, 파이썬 버전 관리
파이썬을 설치(및 버전 관리)하는 방법은 사실 너무너무너무너무 많다. 일반적인 설치 방법 몇 가지를 보면 다음과 같다.
1) 파이썬 공식 홈페이지에서 파일을 다운받아 설치하기
2) conda로 설치하기
3) Docker로 파이썬 이미지 설치하기
4) 패키지 관리자(brew, apt, winget)로 설치하기
5) pyenv로 설치하기
사실 1~4는 여기저기 많이 소개되는 일반적인 방식들이지만, 우리 팀의 경우 pyenv로 버전 관리를 굉장히 쉽게 했었다!
Why Pyenv?
Pyenv는 파이썬의 여러 버전을 CLI로 쉽게 설치할 수 있는 도구라는 점이 가장 큰 장점이다.
파이썬을 뭐 여러 버전 쓸 일이 있어? 한다면..
실제로, 부캠에서 대회마다 주어지는 Baseline의 requirements.txt와 다른 라이브러리들을 사용할 때 파이썬 버전 충돌이 굉장히 많이 났었다. (당시 겪었던 트러블 슈팅을 정리한 글)
이 외에도, (과거의 나도 마찬가지지만 )파이썬 경험이 적은 사람들은 다른 라이브러리들을 함께 사용할 때 버전 충돌로 애먹은 경험이 분명 있을 거다.
쨌든 일반적으로 많이 사용하는 conda를 사용할 수도 있지만, conda의 경우 파이썬 버전을 빠르게 바꾸기 번거롭고 라이브러리를 설치할 때 생각지도 않았던 다른 라이브러리가 같이 설치돼 용량을 많이 차지하는 등의 문제가 있었다. (실제로 Production 환경에서는 conda가 무거워 잘 사용되지 않는다고 한다.)
따라서, 우리 팀은 좀 더 쉽고 간편하게 여러 파이썬 버전을 관리할 수 있는 툴 중 pyenv를 사용하기로 결정했었다.
그럼 본격적으로 pyenv를 직접 설치하고 실행해 보며, 구체적으로 어떻게 여러 버전을 관리하는 지 알아보자.
Pyenv 설치 및 사용 방법
Linux 기준이기 때문에 MacOS, Windows의 경우 위 공식레포 READEME.md를 참고할 것!
1. 패키지 관리 시스템을 업데이트
sudo apt-get update
2. 설치 중에 지역 입력하라고 뜨면 6(Asia), 69(Seoul) 입력 후 enter
sudo apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev
3. URL을 통해 pyenv 설치에 필요한 데이터 다운로드
curl https://pyenv.run | bash
4. 환경 변수 설정
vi ~/.bashrc
# pyenv 환경 변수 설정
export PATH="${HOME}/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
shell 설정 파일(~/.bashrc)에 다음과 같이 환경변수들을 추가해줘야 한다. ESC -> : -> wq!로 빠져나오기
5. Shell 설정 파일 환경 설정 업데이트
source ~/.bashrc
6. 본인이 설치하고 싶은 버전으로 설치하면 된다!
pyenv install 3.9.16
여기서 ModuleNotFoundError: No module named '_lzma' 에러나면 아래 두 개 다시 설치해 주면 된다.
sudo apt-get install lzma
sudo apt-get install liblzma-dev
7. pyenve로 설치된 파이썬 버전 확인
pyenv versions
8. 현재 shell에 파이썬 버전 활성화
pyenv shell 3.9.16
9. 시스템 전역에 해당 파이썬 버전 설정
pyenv global 3.9.16
여기까지 진행하면 Pyenv는 설치 완료!!
+ 다른 버전을 설치하고 싶다면
위에서 6번과 8번만 하면 된다. 예를 들어, 3.11.0을 설치하고 싶다면
pyenv install 3.11.0
pyenv shell 3.11.0
파이썬 버전 관리 참 쉽죠? 필요에 따라 버전을 설치하고, pyenv shell로 사용할 버전을 활성화 해주기만 하면 된다.
Poetry, 파이썬 프로젝트 버전 관리
Why Poetry?
Pyenv가 파이썬의 버전 관리를 해줬다면, Poetry는 파이썬 프로젝트 버전을 관리해준다.
바로 Poetry 사용 방법으로 넘어가기 앞서, 내가 팀원들에게 Poetry 사용을 제안한 이유에 대해 설명해보고자 한다.
(궁금하지 않다면 밑으로 내려 설치 및 사용 방법을 확인하면 된다. 이 부분은 안 읽어도 사용하는데 전혀 지장 없다.)
팀 프로젝트를 진행하다보면, 당연하게도 다른 팀원과 일을 함께 진행해야 하는 상황이 온다. 이 말은, 내가 현재 작업하고 있는 환경(버전일 수도 있고)과 상대의 환경은 전혀 다른 상황에서 갑자기 새로운 프로젝트를 함께 진행해야 할 수도 있다는 뜻이다.
또한, 다음 이미지처럼 프로젝트별 최소로 요구되는 패키지의 버전이 각각 다르다면 어떨까? (물론 도커를 사용할 수도 있지만..)
위처럼 여러 모델을 실험하거나 여러 프로젝트를 동시에 진행한다면, 의존성 문제가 생겨 하나의 환경에서 작업을 할 수 없다.
왜? 당연하게도, 하나의 환경에서 계속해서 버전을 바꿔가며 하는 방법은 비효율적이니까!
그래서 "각각의 작업별 버전을 갖도록 가상환경을 사용하면서 패키지 의존성 관리도 손쉽게 할 수 있는 방법이 없을까?"
고민한 결과, poetry를 통해 두 문제를 아주 손쉽게 해결할 수 있었다!
Poetry 설치
설치는 단 3줄이면 된다.
curl -sSL https://install.python-poetry.org | python3 -
vi ~/.bashrc 후 아래 환경변수 설정 추가
# poetry 환경 변수 설정(위치가 다를 수도 있음)
export PATH=$PATH:$HOME/.local/bin
source ~/.bashrc
poetry를 입력했을 때 아래와 같이 commands가 잘 뜨면 끝!
Poetry 사용 방법
1) 프로젝트 생성
poetry new 프로젝트명
설정한 프로젝트명 뒤에 알파벳과 숫자들은 무시해도 된다.
- 프로젝트 명의 폴더(그림에서는 dkt), tests 폴더는 그다지 중요하지 않음
- pyproject.toml
- 프로젝트와 패키지의 의존성을 관리하는 가장 중요한 파일
위처럼 name은 처음 생성할 때의 프로젝트명, version은 패키지 버전이며 python 버전도 잘 명시돼 있다.
2) 의존성 관리(+ 프로젝트 관리)
- poetry add 명령어를 사용
- 필요한 패키지 설치(예시)
- poetry add pandas -D
- poetry add numpy -D
- -D(or --dev) 옵션: production환경에서는 필요하지 않고, 테스트나 디버깅 등 개발환경(development dependency)에서만 필요한 패키지를 설치한다.(공식문서)
- 즉, poetry add 명령어의 --dev 옵션은 특정 패키지를 개발 시에만 필요한 의존성(dependency)으로 추가할 때 사용된다. 이렇게 추가된 패키지는 poetry install 명령어를 사용해 프로젝트에 설치할 때는 설치되지 않지만, poetry install --dev 명령어를 사용하여 개발 의존성을 함께 설치할 수 있다.
- poetry show --tree
+ 만약 특정 패키지의 버전을 변경하고 싶다면?
예를 들어, 다음처럼 numpy는 1.25.2 버전으로 설치돼 있는 상황.
pandas 2.1.0 버전은 최소 numpy의 버전이 1.23.2 버전이 필요하다 할 때, numpy의 버전을 1.23.2 버전으로 바꿔보자.
1. pyproject.toml 파일에서 버전을 직접 수정해 준다.
2. poetry add 패키지 == 원하는 버전
poetry add numpy==1.23.2
에러 없이 잘 설치가 됐다면, 다음 이미지처럼 1.23.2로 변경된 버전이 출력되는 걸 확인할 수 있다.
이게 왜 유용한지 사실 이렇게만 보면 와닿지 않을 수 있지만..
다른 사람들과 협업할 때, 여러 팀원이 작업한 환경을 git에서 pull한 후 (pyproject.toml 파일이 있는) 해당 프로젝트 디렉토리에서 poetry install만 해줘도 새로운 가상환경이 자동으로 만들어지며 필요한 모든 패키지를 설치할 수 있다. 즉, 더 이상 성가신 종속성 문제나 대충 적혀있는 requirements.txt로 스트레스받을 일이 사라진다는 이야기!
지금까지 아주 간단한 사용방법만 살펴봤기 때문에, 사실 위 글들로만은 크게 장점이 와닿지 않을 수도 있다.
그럼에도 poetry가 pip 사용 시 발생하는 문제점들(개발, 운영 환경을 구분해 패키지를 설치할 수 없다거나 패키지간 의존성을 볼 수 없는 등)을 해결할 수 있고, "여러 가상환경과 버전 관리를 빠르고 쉽게 하고 싶다"는 우리의 니즈 역시 충족시켜 준다고 생각한다.
물론, 처음 사용할 때는 은근 사소한 이슈들이 있었는데 공식레포나 docs가 굉장히 친절해서 빠르게 해결할 수 있는 정도의 문제들이었다. 그 과정에서 문제가 생길 때마다 팀 노션에 트러블 슈팅을 정리해 뒀고, 대회 중 서버를 다시 할당받아야 할 때나 예상치 못한 버전 이슈가 있을 때 팀원들도 해당 글들을 보고 도움을 많이 받았다고 했다. 또 내용이 좋으니 블로그에도 작성해 보라고 추천해줘서 어쩌다 보니 블로그에 이렇게 글까지 남기게 됐는데.. 누군가에게도 이 글이 도움이 되길 바란다😊
3줄 요약 📑
1. 대회랑 프로젝트를 진행하면서 계속 (파이썬) 패키지 간 버전 문제가 있었다. 가상환경도 필요했다.
2. pyenv랑 poetry를 사용하면 작업별 가상환경 버저닝과 패키지 의존성 관리도 쉽게 할 수 있다는 걸 확인했다.
3. 실제로 팀원들이랑 부캠 동안 사용하면서 빠르고 편하게 협업할 수 있었다.
Rerence
https://towardsdatascience.com/pipenv-vs-conda-for-data-scientists-b9a372faf9d9
https://python-poetry.org/docs/pyproject/
https://github.com/pyenv/pyenv#uninstalling-pyenv
변성윤 마스터님, 서비스 개발 기초 강의(네이버 부스트캠프 AI Tech)