etc

Heroku에 django 프로젝트 배포

동건 2016. 5. 22. 17:36

클라우드 서비스는 개발자 뿐만 아니라 일반인에게도 친숙한 개념이 될 정도로 널리 퍼져있다. 대중적으로는 드랍박스 등의 저장소 서비스로 클라우드를 인식하고 있을 가능성이 높은데, 이 드랍박스를 뒤에서 받쳐주는 클라우드 서버를 아마존이 제공하고 있다는 사실은 알고 있는가. 아마존의 AWS를 필두로 마이크로소프트의 Azure 등의 유명한 대기업 외에도 cloudera, cloudway, 우리나라의 kt ucloud 등 클라우드 서비스를 제공하고 있는 업체는 넘나 많다. 그런데 이러한 서비스들을 살펴보면 결국엔 돈을 내야한다는 결론에 다다른다. 기업 레벨에서 사용을 해야한다면 과금은 당연한 이치이겠지만 개인이 시범/실험적으로 사용을 하고 싶을 때는 당장 돈을 내야하지 않더라도 과금의 존재 자체가 클라우드 서비스에의 접근을 정신적으로 막기도 한다. (적어도 나에게는)

여기서는 확실하게 무료로 이용할 수 있는 + django 프로젝트를 손쉽게 올릴 수 있는 클라우드 서비스를 소개하고, 그 과정을 정리한다. 내가 아는 것으로는 heroku.com, pythonanywhere.com 정도를 들 수 있는데, 이 포스트에서는 heroku만 소개한다.

heroku에서는 아마존 EC2처럼 할당받은 서버를 내 컴퓨터 쓰듯이 직접 제어할 수는 없다. heroku에서 제공하는 CLI (CommandLine Interface)를 통해, 그리고 git을 이용해서 django 프로젝트 (django 외에도 python 및 다양한 언어를 지원한다) 를 업로드하고 제어한다. 여기서는 유닉스 시스템 (리눅스 또는 맥os)을 사용한다고 가정하고 과정을 정리한다. heroku에서 제공하는 튜토리얼 문서(첫 번째, 두 번째)를 번역하는 수준이지만 그 과정에서 겪은 시행착오를 기록하려 한다.

우선 git이 없다면 설치.

$ sudo apt-get install git

Python 가상환경을 쓰고 있지 않다면 또 설치

$ pip install virtualenv

그리고 heroku와 내 컴퓨터가 대화할 수 있게 하는 heroku 툴벨트를 설치해야한다.

$ wget -O- https://toolbelt.heroku.com/install-ubuntu.sh | sh

위 주소는 heroku 툴벨트 다운로드 페이지에 접속했을 때, 사용자 컴퓨터 환경에 따라 다르게 나오는 부분이다. 나는 우분투를 사용하고 있으므로 위 주소가 제공됐으니, 툴벨트 페이지에 꼭 들어가서 자신의 환경에 맞도록 설치해야 한다. wget 다음에 나오는 글자는 대문자 O임을 유의하자.

heroku에 올리고 싶은 django 프로젝트는 이미 어딘가에 완성돼있다고 가정하고, 이 프로젝트를 heroku에 올리기 위한 작업들이 몇 가지 있다. 하지만 이를 정리하기에 앞서 - 이러한 것들을 신경쓰고 싶지 않다거나, 이 과정에서의 시행착오를 겪고 싶지 않다면 heroku django starter template을 받아서 이 템플릿 위에서 기존 프로젝트를 옮기길 추천한다. 실제로 이 방법이 성공을 향한 지름길이 될 것이라고 나는 생각한다. 그럼 이제 heroku가 요구하는 몇 가지를 정리하겠다.

1. requirements.txt가 필요하다

이 텍스트 파일은 우리의 django 프로젝트가 사용하는 Python 패키지들을 기록한 리스트이다. 이미 알고 있을 가능성이 높겠지만, Python 가상환경을 이용해 설치한 패키지들을 다음 명령어로 간단히 저장할 수 있다.

pip freeze > requirements.txt

그리고 heroku가 필수로 요구하는 requirements.txt의 내용은 다음과 같다.

dj-database-url==0.4.0
Django==1.9.2
gunicorn==19.4.5
psycopg2==2.6.1
whitenoise==2.0.6

이를 통해서 heroku는 우리의 django 프로젝트를 gunicorn2를 사용해서 배포할 것이고, 데이터베이스는 postgresql을 사용할 것임을 알 수 있다. dj-database-url은 heroku 쪽의postgre에 연결하기 위한 패키지이다. whitenoise는 정적 파일을 제공하기 위한 패키지이다. 물론 django도 필요하겠지.

2. Procfile이 필요하다

이 파일은 우리가 heroku에 올린 django 프로젝트를 실행하기 위한 명령을 적어 놓는 곳이다. 위의 환경설정을 기반으로 Procfile은 다음 한 줄을 갖고 있으면 된다.

web: gunicorn your_wsgi.wsgi --log-file -

heroku에 배포하기 위해서는 이거면 충분하다. 하지만 윈도우 컴퓨터에서 heroku local(내 컴퓨터에서 heroku 환경 아래서 실행)을 실행하기 위해서는 Procfile.windows 파일을 새로 만들어 다음 명령을 입력해 놓는다.

web: python manage.py runserver 0.0.0.0:5000

추후 설명하겠지만, 윈도우 컴퓨터에서 heroku local을 설명하기 위해서는 다음 명령어를 입력하면 된다.

> heroku local -f Procfile.windows

그럼 어떤 일이 벌어지는 지는 예상 가능할 것이다.

3. settings.py를 고쳐야한다

settings.py의 DB 관련 부분, 정적 파일 관련 부분을 heroku가 다룰 수 있는 환경과 맞춰주어야 한다.

3-1. DB 관련 환경 설정

heroku django starter template의 settings.py에서 DB와 관련된 부분만 뽑아서 보여주겠다.

DATABASES = {
    'default' = {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

import dj_database_url

db_from_env = dj_database_url.config(conn_max_age=500)
DATABASES['default'].update(db_from_env)

기본 DB 세팅은 sqlite3로 되어있지만 이를 requirements.txt에 등록했었던 dj_database_url을 통해서 heroku에서 사용하는 postgre로 설정을 바꿔주는 것이다.

3-2. 정적 파일 관련 환경 설정

PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))

STATIC_ROOT = os.path.join(PROJECT_ROOT, 'staticfiles')
STATIC_URL = '/static/'

STATICFILES_DIR = [
    os.path.join(PROJECT_ROOT, 'static'),
]

STATICFILES_STORAGE = 'whitenoise.django.GzipManifestStaticFilesStorage'

heroku에서 정적 파일은 django와는 독립적으로 gunicorn과 whitenoise를 통해서 제공할 것이기 때문에 django 프로젝트 폴더가 아닌, settings.py와 wsgi 파일이 있는 폴더에서 정적 파일 폴더를 다룬다. 따라서 위의 환경 설정을 마친 뒤, static 폴더를 그 위치로 옮겨 놓아야 한다.

참고로 whitenoise는 css파일이 가리키는 링크 파일이 제대로 연결되어 있지 않다면 바로 에러를 내기 때문에 heroku에 push를 할 수가 없다. 따라서 없는 파일을 포함하지 않도록 정적파일을 꼭 갈무리하길 바란다.


heroku에 django 프로젝트를 올리기 전에 기본적으로 설치해야 할 것들과 django 프로젝트에서 손봐야 할 것들을 살펴봤다. 이제 이를 heroku에 올려보자.

당신의 django 프로젝트가 git과 무관하다면 git을 실행하고 커밋하자.

$ git init
$ git add .
$ git commit -m "initial commit for heroku"

그리고 heroku 툴벨트를 설치했으니 heroku를 시작하자. 다음 명령어는 자신의 heroku 계정에 새로운 웹앱을 추가하고, 현재 git 프로젝트에 이 웹앱을 가리키는 새로운 지점을 추가한다.

$ heroku create

그러면 이 git 프로젝트는 새로운 remote 저장소인 heroku가 추가되고 다음 명령을 통해 heroku create를 통해 만든 웹앱에 내 django 프로젝트를 집어넣는다.

$ git push heroku master

이를 실행하면 내가 push하려고 하는 프로젝트를 heroku가 python 앱임을 감지하고, 이와 연결돼있는 내 계정의 웹앱을 찾아내며, requirements.txt에 등록된 Python 패키지들을 설치한다. 그리고 collectstatic을 실행하여 정적파일을 복사하여... 기타 등등 열심히 일을 하고 문제없이 나의 앱이 heroku에 배포가 되었다. -- 첫 시도엔 대부분 잘 넘어가지 못할 것이다. 이 경우에는 starter template을 바로 heroku에 배포한 뒤 (내가 손을 안되면 무조건 성공) 스텝바이스텝으로 조금씩 고쳐보면서 나아가길 권한다.

이 앱을 로컬 컴퓨터에서 실행하려면

$ heroku local (맥 또는 리눅스라면)

$ heroku local -f Procfile.windows (윈도우 컴퓨터라면)

heroku에 잘 배포된 나의 웹페이지를 보고싶다면

$ heroku open

당신의 웹브라우저에 명령에 맞는 페이지가 뜰 것이다.

참고로 사용자가 직접 파일을 업로드해서 media파일을 쓰려면 과금이 필요하게 되므로 (이렇게 되는 이유는 추후에 추가) 정적 파일만으로 충분한 웹 프로젝트를 배포하기에 적당하다.

시간이 된다면 pythonanywhere.com에서 django 프로젝트를 올리는 것도 정리할 예정이다.

반응형