프로젝트로 만든 flask앱을 azure vm을 사용해서 배포했었는데, 무료 크레딧을 다 썼다. 그래서 이번에는 heroku로 배포해보았다.
✔ 이 글에 나오는 내용
heroku에서 계정 만들기 -> 로그인 후 Dashboard
-> Create new app
app dashboard 페이지에서 Deploy
로 가면 상세한 설명이 나와있어서 그대로 따라하면 된다. 여기서는 heroku cli를 사용해서 앱을 배포하는 법을 설명하려고 한다.
heroku cli는 여기서 다운받아 설치하면 된다.
나는 우분투 환경에서 작업하고 있어서 다음의 명령어를 통해 설치했다.
$ curl https://cli-assets.heroku.com/install-ubuntu.sh | sh
heroku --version
으로 설치 여부를 확인해보면 된다.
현재 프로젝트의 repository가 git repository가 아니면 git init
부터 해준다.
그런 다음, remote repository로 heroku app을 추가한다.
$ heroku git:remote -a <heroku app name>
로그인이 안되어 있으면 로그인하라는 브라우저 창이 뜨는데, 로그인하면 창이 종료되고 다시 돌아가서 작업하면 된다.
추가가 잘 되었으면 git remote
에 heroku가 뜬다.
그 다음 git repository에 올리는 것처럼 커밋하고 heroku repository에 올리면 된다.
$ git add .
$ git commit -m "heroku로 배포하기"
$ git push heroku master
그런데 이때 주의할 점이 있다. heroku에 배포하는 방식이 git repository에 커밋을 반영하는 방식이랑 동일한 것에서 알 수 있듯, heroku app은 git에 올라가 있는 파일만 볼 수 있다. 즉, .gitignore에 있는 파일은 볼 수 없다. 그래서 Secret key 같은 환경변수들은 따로 app 페이지로 가서 추가해줘야 한다.
app dashboard 페이지에서 Settings
-> Config Vars
-> Reveal Config Vars
클릭 후 추가하면 된다.
환경변수를 .env 파일에서 관리하고 있었으면 이 단계는 건너 뛰어도 되는데, 나는 config.py 파일로 만들어서 import해오는 방식으로 관리하고 있었어가지고 앱이 환경변수를 읽을 수 있게 경로를 수정하고 .env 파일을 다시 만드는 작업을 했다.
그냥 .env 파일을 만들고 os.environ.get("SECRET_KEY")
와 같은 방식으로 읽어오면 될 것 같았는데, 이렇게 하니까 못 읽어와서 왜 인지 찾아보니 flask run
을 실행했을 때 FLASK_APP을 지정해주지 않아서 그런 것 같았다(아닐 수도 있다. 확실치 않음).
찾아보니 번거롭게 따로 설정할 필요없이 환경변수를 .env파일로부터 읽어오는 방법이 있었다.
python-dotenv
를 설치한다. from dotenv import load_dotenv
load_dotenv()
os.getenv("SECRET_KEY")
의 형식으로 사용하면 된다. clearDB는 heroku에서 제공하는 DB 서비스인 것 같다. MySQL 원격 서버를 찾다가 발견했는데, 5MB까지 무료로 사용할 수 있다. heroku app이랑 연결하기도 쉬워서 얘를 사용해보기로 했다.
여기로 가서 Install ClearDB MySQL
을 클릭하고, 연결할 앱을 선택하면 된다. 그리고 앱 대시보드로 가보면 DB가 Installed add-ons
로 표시되어 나타난다.
DB host 주소나 user, password를 알려면 Configure add-ons
를 통해서도 가능하지만, 쉽게 알아내는 명령어가 있다.
터미널에서 heroku configure --app <app_name>
을 입력하면 등록된 환경변수 목록이 뜨는데, 이 중 CLEARDB_DATABASE_URL
을 통해 DB 정보를 알아내면 된다.
주의할 점은, DB URL 맨 끝에 ?reconnect=true
가 붙어있는데, 얘를 지워줘야 한다. 얘는 rails 앱 사용시 필요한 애고, 파이썬 앱을 사용할 때는 삭제하라고 하고 있다. 붙여서 앱을 실행시켜봤더니 동작을 안했다.
(공식 문서 참고)
DB까지 연결한 상태로 앱 대시보드 페이지로 가서 오른쪽 상단의 open app
을 눌러 앱을 열어보았는데, 열리지 않았다. 그래서 터미널로 가서 heroku logs --tail
로 에러 로그를 확인해보았다. 확인해보니 실행 중인 프로세스가 없다고 떴다. 생각해보니 앱을 실행시키지 않았다.
어떻게 실행시킬지 찾아보다가, heroku app을 실행시킬 명령어는 Profile에 정의해놔야 한다는 것을 알게 되었다. 공식 문서를 보면 Procfile은 "Heroku apps include a Procfile that specifies the commands that are executed by the app on startup."이라고 나와있는데, 즉 실행시킬 명령어나 프로세스 타입 등을 써놓는 파일이다.
(공식 문서 참고)
문서의 예시에 나와있는 것처럼 gunicorn을 설치하고 Procfile을 만들어주었다.
pip install gunicorn
으로 gunicorn 설치하기 <process type>: <command>
의 형식으로 내용 추가하기web: gunicorn wsgi:app
그런 다음 다시 push하고 앱 페이지에 접속해보니 앱이 잘 뜨는 것을 확인할 수 있었다.
여기까지 했는데 앱이 뜨지 않으면, heroku restart
로 재시작해보거나, DB가 migrate되었는지 확인해봐야 한다. DB migration은 heroku와는 별개로 직접 해줘야 한다.
참고) migration 관련 명령어
flask db init
: migration folder가 없을 경우 DB 초기화하기
flask db migrate
: migrate하기
flask db upgrade
: db 구조가 변경된 걸 반영하기
단, 모델이 추가되거나 테이블의 컬럼이 추가되는 것 이외에 컬럼의 속성이 바뀐 경우는 migrate/upgrade로 적용되지 않는다. 따라서 테이블을 삭제하고 다시 만들어야 한다.
google oauth 로그인 기능을 달았었는데, 얘는 redirect url을 추가하는 작업을 해줘야 정상적으로 동작할 수 있어서 관련 설정을 해줬다.
Credentials
로 가서 OAuth 2.0 Client IDs
의 앱 클릭 Authorized redirect URIs
에 redirect url 추가하기 추가하고 google로 로그인해보니 잘 되는 것을 확인할 수 있었다. 끝!
근데 개발을 막 시작할 때 만든 앱이라 자잘하고 큰 오류들이 너무 많다 ㅋㅋㅋ 조만간 오류를 수정하고 업데이트를 해야겠다.