Key words
배포, Heroku, WSGI, 대시보드, Metabase
1. Heroku
- 어제는 Flask를 통해 웹 어플리케이션을 만드는 걸 배웠다. 하지만 어제 한 것만으로는 내가 만든 어플리케이션을 다른 사람이 쓸 수 있도록 공유할 수는 없다.
(물론 설정해서 줄 수는 있긴 한걸로 보았지만 진정한 의미의 배포라고 할 수는 없다.)
- Heroku는 이렇게 만든 웹 어플리케이션을 배포할 수 있도록 도와주는 클라우드 서비스이다.
- Heroku는
requirements.txt, Procfile, 그리고 내가 작성한 코드만 push 해주면 Heroku에서 알아서 코드를 해석하고, 공유할 수 있는 도메인까지 넘겨준다. 되게 편한거지~
- 참고로 Heroku 홈페이지 가면
add-ons라는 페이지가 있는데, 여기서 여러 DB를 연결할 수도 있다고 한다. 아직 직접 해보지는 못 했다.
배포에 쓸 수 있는게 Heroku 말고는 없어? 있다!!
아래 내용을 참고하자. 오늘 웜업 영상에서 봤던 거다.
AWS EC2 vs Heroku 뭘 써야할까? 선택하는 기준은? (출처)
Heroku = Platform as a Service / AWS EC2 = Infrastructure as a Service 로 생각하면 된다.
Heroku: 작성한 코드만 push하면 히로쿠에서 알아서 해석하고 도메인 이름도 주고 다 해준다. 그런 의미에서 플랫폼이라고 하는 거다.
AWS EC2: 인프라를 위한 비용을 지불하는 것인데, 여기서 인프라란 서버를 말한다. 즉, 그 안에 뭘 설치하고 등등 다 내가 알아서 해야한다는 얘기다.
- 위 정의만 보면 내 상황에 따라 배포에 둘 중 어떤 걸 선택해야할지 선택의 기준이 빡~ 감이 온다!
- 여기서 내 상황이란? 3가지다. 비용, 시간, 컨트롤!!
- 컨트롤: 히로쿠는 코드만 푸시하면 다 알아서 해주는 편의성이 있는 반면, 내가 파이썬 몇 버전을 쓸지, 포트는 어떻게 할지 등의 디테일에 대한 선택권이 제한된다. 반면, AWS EC2는 인프라만 제공하기 때문에 내가 그것들을 선택할 수 있다.
- 시간: 위와 연결되는 부분인데, 만약 내가 이것저것 공부하고 설치하고 할 시간이 없다면? 히로쿠를 선택하면 된다.
- 비용: 히로쿠가 더 비싸다! 왜 그런지 직관적으로 알 수 있다. 그리고 히로쿠는 AWS EC2 위에서 작동하기 때문에 결코 AWS EC2보다 저렴할 수가 없다고 한다.
- 아마존에서는 히로쿠와의 직접적인 경쟁상대인
AWS EB를 출시했는데, 히로쿠보다 저렴하고 비교적 빠르기 때문에 히로쿠 대신 AWS EB를 선택할 수도 있다고 한다. 다만, 아직은 히로쿠가 더 빠르고 사용하기 쉽다고 한다.
- 결론적으론 내가 가용한 리소스에 따라 적절한 클라우드 배포 서비스를 선택하면 되고, 정답은 없다고 기억하고 넘어가면 될 것 같다.
Heroku CLI - 기본적인 것만 몇 개!
참고로 install 해줘야 한다~
$ heroku login: 입력하면 히로쿠 사이트로 연결되며 로그인을 하면 CLI을 사용할 수 있도록 인증이 된다.
$ heroku apps: 계정 내에 등록된 앱들의 목록을 볼 수 있다. 5개까진가? 이후부터는 유료로 넘어간다고 한다.
$ heroku create app_name: 로컬에서 개발했던 앱을 등록하기 위해 히로쿠에 앱을 만들 수 있다.
- 참고로 기존 히로쿠 서버에 없는 이름만 사용할 수 있다.
- 깃 레포에서 생성하면 git remote에 heroku 주소를 자동으로 추가해주는데, 만약 자동으로 추가가 안된 경우 수동으로 해줘야 한다고 한다. (근데 오늘 실습할 때는 자동으로 되긴 했다.)
$ git push heroku main: 작업한 코드가 변경되면 git add와 commit을 해주고 히로쿠로 푸시를 해줘야 반영이 된다.
- 아무튼 여기까지는
Heroku가 무엇이고 어떨 때 쓰는지만 알고 넘어가면 되고, Heroku를 통한 배포 과정은 아래 실습 부분에 자세히 적어두겠다.
2. WSGI
어떤 과정으로 우리가 배포한 어플리케이션이 왔다갔다 하는지도 공부했다.
Web Server Gateway Interface의 약자로 '위스키'라고 부르곤 한다고 한다.
- 위스키는 서버/게이트웨이를 어플리케이션/프레임워크와 연결해주는 다리 역할을 하는데, 예를 들어 내가 어제 만든 Flask 프로젝트를 서버로 연결해 외부에서 접속할 수 있도록 도와주는 역할을 한다.
- 그림으로 설명을 들었을 때 난 더 이해하기 쉬웠다!
(그림 너무 못 그리네;)
- 위 그림이 나타내는 게
서버의 3계층(3-tier Architecture)라고 한다고 함.
- WAS는 끊임없이 변하는 내용이 있는 경우 db에서 꺼내 반영해주는 역할을 한다. 예를 들어, 어제 Jinja 변수 넘겨주는 걸 해봤었는데 그런 역할로 이해하면 될 것 같다.
오늘 Heroku로 배포할 때 사용한 WSGI server는 gunicorn이었다.
- 기본적으로 HTTP 요청이 들어오면 flask와 같은 어플리케이션을 이용해 처리를 하는 역할을 하며, 작동하는 방식은
pre-fork worker 모델이라고 한다.
파이썬에서 어떤 애플리케이션이나 프레임워크가 주어지게 되면 사전에 '포킹'을 한 뒤에 worker 를 통해 작업을 실행합니다. 라고 하는데.. 정확히 무슨 말인지는 잘 모르겠다.
- 여하간 서버를 띄울 때 worker의 수를 정해서 하나의 어플리케이션을 몇 개 띄우게 되는지 미리 정할 수 있다고 한다.
- 참고로 gunicorn은 파이썬에 종속되어 있으며, 웹 서버라고 하기는 힘들고 그런 역할을 제한된 범위 내에서 할 수 있다고 한다. (gunicorn = Python WSGI HTTP Server)
- 사용하는 과정은 아래 실습 부분에 남겨두겠다~
참고: gunicorn documents
- 음.. Power BI, Google DataStudio 같은 BI툴이다. 딱히 더 적어둘 건 없다. 오늘은 어떻게 사용하는지 위주로 설명을 들었다.
- 아 대시보드에서 만든 차트 웹 어플리케이션에 임베딩하는 것 봤는데 신기했다!!
- 참고로 이번 섹션 프로젝트 때 Metabase를 쓴다고 하니 실습만 미리 해두면 될 것 같다.
4. Heroku 배포 실습
(오늘은 제출해야할 과제는 없었다.)
어제 작업했던 flask 어플리케이션 폴더를 복제해서 Heroku를 통해 배포하는 걸 해보았는데, 아예 프로젝트 폴더 만드는 것부터 완전 새롭게 해보고 싶어서 다시 과정을 하나하나 밟아보았고, 그걸 기록해둔다. 나중에 와서 보면 바로 할 수 있게~!
[flask 프로젝트 폴더 생성 및 가상환경 세팅]
- 우선 flask 프로젝트 폴더를 만들었다.
herokutest/my_app
- my_app 폴더 내에
_init__.py 파일 생성.
- conda 가상환경 세팅 및 실행
$ conda create -n herokutest
- 설치
$ pip install flask, $ pip install gunicorn
$ pip freeze로 설치 잘 되었는지 확인했다. (원래 이런 용도는 아니지만 여하튼..)
__init__.py에 기본 내용 기입.
from flask import Flask, render_template
def create_app():
app = Flask(__name__)
@app.route('/')
def index():
return "Hello World!"
return app
if __name__ == "__main__":
app = creat_app()
app.run(debug=True)
- 아, 참고로 이번엔 어제와 다르게 어플리케이션 팩토리 형태로 만들었다. 이렇게 하는 걸 추천한다고 함.
- flask run test.
$ FLASK_APP=my_app flask run => 확인 완료
[Heroku 앱 생성하기]
- (이미 heroku 설치 및
$ heroku login을 통해 인증을 해둔 상태라 해당 과정은 생략함)
- heroku 앱 생성하기
$ heroku create app_name (앱 실제 이름은 적지 않겠다)
- 정상적으로 생성되면, 결과로 웹에서 접속할 수 있는 도메인 주소와 git 주소를 반환해준다
- 참고로 이 git 주소는 뒤에서 쓸 데가 있는데, 만약 까먹었다면
heroku apps:info --app app_name을 통해 확인할 수 있다. (경우에 따라 heroku apps:info만 해도 나올 수 있음)
- 전달된 도메인 주소를 웹에서 실행하면 다음과 같은 화면이 뜬다.

이제 뭘 해야 한다? 그치~ 내가 작업한 코드를 히로쿠에 푸시해줘야 한다. 그래야 저 사이트에서 내가 작성한 웹 어플리케이션이 보인다~
근데 그 전에 할게 있지!
[requirements.txt, Profile 생성하기]
- 참고로 위 두 파일은
my_app 폴더와 동일한 디렉토리에 위치해야 한다.
requirements.txt 생성하기: $ pip freeze > requirements.txt

requirements.txt 파일 들어가서 gunicorn 잘 들어가 있는지 확인했고(없으면 직접 넣어야 함), Pytest 관련 지금 쓸데없는 건 리스트에서 제거해주었다. 이상 없다!
Procfile 생성: $ touch Procfile
Procfile 들어가서 내용 기입
web: gunicorn --workers=1 'my_app:create_app()'
- 참고로 worker는 1로 했는데, 숫자 높여야할 필요가 뭔지 아직은 잘 모르겠음.
[Heroku에 배포하기]
- git 작업 먼저 해줄거임.
- 현재 디렉토리를 깃 폴더로 만들기:
$ git init
- 잘 되면
Initialized empty Git repository in {경로} 메시지 확인 가능함.
- 깃 리모트 지정:
$ git remote add heroku {아까 확인한 git url}
- 이제 add, commit, push 해주면 됨.
$ git add ., $ git commit -m 'my first commit', $ git push heroku master
- (참고로 push할 때 master 안되면 main으로 해보면 됨)
- 그리고 아까 받은 도메인 새로고침 해보면!

이러면 배포가 된거다. 배포가 되었다는 건, 도메인을 다른 사람이 들어와도 똑같은 화면이 보인다는 거다.
- 만약 코드 수정하거나 하면
git add, commit push 하면서 수정사항 히로쿠에 반영해주면 됨.
끝~~ 쫄지마 쫄지마!
- Metabase는 원래 내일 실습해보려고 했는데, heroku 실습하고 생각보다 에너지가 많이 남아있어서 해본다.
- metabase에서 만든 대시보드를 웹 어플리케이션에 임베딩하는 것까지 해볼 예정이다.
1. Metabase 설치하기(docker이용)
- 설치 안내 페이지
- 따라해 준다.

- (docker 명령어 실행하기 전에 docker 앱 켜서 running 후에 해야 하는 거 잊지 말자ㅎ)
- 참고로 container run할 때 명령어에
-d는 백그라운드에서 돌아가도록 하는 거라 빼고 돌렸다.
- 설치가 완료되었다면, 위 안내 메시지처럼
localhost:3000에 접속하면 내 metabase를 사용할 수 있다.
(맨 처음에 그냥 metabase 사이트 들어가서 회원가입하다가 돈 내라고 하는거 보고 깜짝 놀랐네)
2. metabase에 db 연결하기
- metabase에 접속하면 언어 선택 등을 하고
Add your data 화면이 나온다.
- db는 이전에 썼던
chinook.db를 써볼거다. 그래서 sqlite를 선택을 하면 아래와 같은 화면이 나온다.
- 자, 이제
Filename을 채우기 전에, 실행 중인 metabase docker에다가 chinook.db를 넘겨줄거다.
- 도커 컨테이너 어디에 넘겨줄지 확인해보기 위해 컨테이너 안으로 들어가서
ls를 한 번 봐보자. 터미널에서 docker 컨테이너 안으로 들어가려면 다음 명령어 쓰면 된다. $ docker exec -it metabase /bin/bash
- 나는 세션 영상과 똑같이
/app에 db 파일을 넘겨주기로 했다.
chinook.db가 들어있는 디렉토리로 변경을 해준다음에 docker cp 명령 수행!
$ docker cp ./chinook.db metabase:/app
- 잘 들어간 것까지 확인했다.

- 그리고 다시 metabase 사이트로 돌아와서,
Filename 쓰는 곳에 /app/chinook.db를 입력하면 끝!
[간단히 대시보드 만들어보기]
- 이건 사이트 GUI라 뭐 딱히 적어둘 건 없고, SQL Query를 통해 대강 대시보드를 만들었다. (이미지는 첨부해두지 않겠다)
[내 웹 어플리케이션에 대시보드 임베딩하기!]
오늘 내가 metabase를 하게 만든 이유! 원인! 한번 가보자~!
(참고 - 임베딩 안내문서)
- 시작하기 전에 flask 프로젝트의 my_app 폴더 내에
templates 폴더를 새로 만들고 그 안에 index.html 파일을 만들어주었다. 그리고 아까__init__.py에 만들었던 index route에 render_template('index.html') 해줌.
- 대시보드 임베딩 URL을 해당 html 파일에 넣어줄거다. (임베딩 테스트만 하려고 할 때는 굳이 이렇게까지 할 필요는 없고 그냥 바로 return값만 수정해줘도 될 듯. 암튼 나중에 하게될 상황 그대로 하려고 이번엔 이렇게 했다.)
- 그 이후에는 안내문서에 따라 하기만 하면 된다.

(웹에 나오는 화면이다)
[Trouble Shooting]
- 이렇게 herokuapp 도메인에 들어가서 대시보드 임베딩된 것까지는 보았다. 근데 문제는 내 도메인 링크를 다른 사람(정확히는 다른 IP)에게 전달하면, metabase dashboard 임베딩한게 그 사람에게는 접근 불가로 나온다는 것이다!!
- 이 문제의 원인은, 이 글에 의하면, 내가 local에서 docker를 통해 metabase를 구동하고 있기 때문인 것 같다.
- 이 글의 답변에서도 마찬가지 얘기를 하고 있다. (이 글이 더 자세하고 친절히 설명하고 있다. 이 글을 봐라!!)
- 그냥 메타베이스 홈페이지 구글링해서 직접 들어가서 가입하면 돈 내고 구독할 수 있고, 그러면 메타베이스를 지금처럼 로컬 주소가 아니라, public URL로도 접속할 수 있게 된다. (즉, 외부에서도 내가 쓰는 메타베이스 접근이 가능하다는 뜻이다. 지금은 안되는 상태지.)(실제로 가입화면 들어가서 결제정보 입력하니 metabaseapp.com 도메인 설정할 수 있도록 나오더라)
- 위 두 번째 참고 글에 의하면, 메타베이스에도 외부 인터넷에서 접근할 수 있는 상태가 되어야 내가 공유하고 싶은 대시보드 임베딩 url도 외부 IP에서도 접근 가능하도록 되어있는 것 같다.
- 결론은!!! 외부에까지 공유하려면 돈 내고 유료 버전(정확히는 클라우드 버전)을 써야 한다~~
- admin setting에서 site url 바꿔보기도 하는 등 이런 저런 방법을 다 시도해봤지만 안됐다. 유료 서비스 안 쓰고 다른 방법이 뭔가가 있기는 한 것 같지만(프록시 설정이나 서버 오픈 등), 추천하지는 않거나 어려워서 굳이 내가 지금 해봐야하나 싶기도 하고(어차피 회사가서 필요한 상황이면 그냥 유료버전 쓸텐데), 섹션3 프로젝트 발표할 때는 어차피 로컬에서 돌리고 촬영하니까 큰 상관은 없을 것 같아서 넘어간다.
Feeling
- 오늘 원래 히로쿠만 실습해보려고 했는데 삘 받아서 메타베이스까지 해보게 되었다. 이상하게 낮보다 자정에 가까운 지금이 더 안 피곤하다ㅋㅋㅋ 재밌었나보다.
- 다음 주 프로젝트 걱정이 자꾸 앞서긴 했지만,, 그래도 잘 했어! 재밌었어!