Google App Engine Django Google Cloud SQL (MySQL) 튜토리얼 - macromancer/DjangoTutorial GitHub Wiki

0. Django Project 준비

0.1. Python 준비

0.1.1. Anaconda 설치

  • Anaconda Download 에서 설치 파일 다운로드 후 실행
    • python2나 python3이나 아무거나 깔면 됨 (어차피 나중에 가상환경 만들 때는 python2 사용)
  • 설치 막바지에 PATH에 추가하겠냐고 물으면 yes를 선택하자.
  • 터미널을 재시작하고 python -V 명령을 실행했을 때 Python x.x.xx :: Continuum Analytics, Inc. 이렇게 출력되면 성공

0.1.2. 가상환경 설정

  • python2에 django package가 설치된 가상환경(이름을 django2로 하자)을 생성한다.
    $ conda create -n django2 django
    • conda env list 명령으로 사용가능한 가상환경을 조회할 수 있다.
  • source activate django2 명령으로 django2 가상환경을 활성화 한다.
    • 0.1.1 에서처럼 python -V 명령으로 python이 2.x 버전으로 실행되는지 확인한다.
    $ source activate django2
    (django2)$ python -V      
    Python 2.7.11 :: Continuum Analytics, Inc.
    
  • python -c "import django" 명령을 실행했을 때 에러가 없으면 성공

0.1.3. django tutorial project 생성

  • django tutorial을 참고해서 Part 2까지 만들어보자. 만약 시간이 없다면 예제 프로젝트를 사용한다.

    $ cd ~  
    $ mkdir Projects  
    $ cd Projects  
    $ git clone https://github.com/macromancer/DjangoTutorial.git DjangoTutorial
    $ cd DjangoTutorial
    $ git checkout Part2   # Part2까지 작성된 Release checkout  
    
  • mysite 폴더로 이동하자. 여기 ~/Projects/DjangoTutorial/mysite가 이후 실습에서의 기준 위치다.

    $ cd mysite
    $ pwd
    /home/<user>/Projects/DjangoTutorial/mysite
    
  • Django에서 기본으로 제공하는 sqlite가 예제 프로젝트에 포함되어 있지만, Google App Engine 에서는 sqlite를 지원하지 않는다. mysite/setting.py 에서 DATABASES 항목을 주석 처리하자.

    $ vim mysite/setting.py
    
    #DATABASES = {
    #    'default': {
    #        'ENGINE': 'django.db.backends.sqlite3',
    #        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    #    }
    #}
  • 예제를 로컬에서 실행하자.

    $ python manage.py runserver
    
  • Chrome을 띄우고 http://localhost:8000/polls 로 접속하자. "Hello, world. You're at the polls index." 라는 문구가 뜨면 성공이다. http://localhost:8000/admin 으로 접속하면 로그인 창이 뜬다. (DB 설정을 주석처리했기 떄문에 로그인은 안된다.)

1. Google App Engine Project 생성

1.1. Google App Engine Free Trial 신청

Google 계정에 로그인하고, Google Cloud Platform Console에 접속해보자. 이전에 Free Trial을 신청한 적이 없다면, 60일동안 $300의 Credit을 제공하는 Free Trial 신청 안내가 상단에 떠 있을 것이다. 만약 이전에 신청한 Free Tier가 만료되었다면, 새 Google 계정을 만들어 접속하면 신청 가능하다. 단, 해외 결제가 가능한 신용카드가 있어야 신청가능하다.

1.2. Google App Engine에 Deploy 하기

Running Django on App Engine standard environmentPython Django Skeleton for Google App Engine을 참고하자.

1.2.1. Google Cloud Platform에 프로젝트 생성하기

Google Cloud Platform Console에서 "프로젝트 만들기"를 클릭한다. 프로젝트 이름을 정할 수 있는데, 이 프로젝트 이름에 따라 <프로젝트 ID>가 자동으로 생성된다. <프로젝트 ID>를 적어두자. 설정, 배포, 접속 등등에 이 <프로젝트 ID> 가 필요하다.

1.2.2. Google Cloud SDK 설치

Google Cloud SDK Documentation를 참고하자.

  • python -V 명령으로 2.x 버전인지 확인한다.

  • 자신의 OS에 맞는 파일을 적당한 다운받아 압축을 풀어준다.

    $ cd ~
    $ tar -xvzf ~/Downloads/<파일명>.tar.gz
    
  • 아래와 같이 스크립트를 실행하면, gcloud 관련 명령 자동완성 기능 등이 추가된다.

    $ ~/google-cloud-sdk/install.sh
    
  • gcloud init 명령으로 SDK를 초기화하자.

    $ ~/google-cloud-sdk/bin/gcloud init
    

1.2.3. Google App Engine SDK for Python 설치

Python과 PHP의 경우 App Engine SDK가 앞서 설치한 Google Cloud SDK에 포함되어서 따로 설치할 필요가 없어졌다.

1.2.4. Django 프로젝트에 파일 추가하기

A. app.yaml

cloud로 배포할 때 필요한 정보들이 적히는 핵심 설정파일

$ cd ~/Projects/DjangoTutorial/mysite
$ vim app.yaml

runtime: python27
api_version: 1
threadsafe: yes

handlers:
- url: /static
  static_dir: static/
- url: .*
  script: mysite.wsgi.application

B. appengine_config.py

appengine이 lib 폴더를 참조하도록 설정하는 파일

$ vim appengine_config.py
# [START vendor]
from google.appengine.ext import vendor
vendor.add('lib')
# [END vendor]

C. requirements-vender.txt

cloud에서 실행될 때 필요한 패키지 목록

$ vim requirements-vender.txt

Django==1.10

1.2.5. Django를 lib 폴더에 설치

$ pip install -r requirements-vendor.txt -t lib

1.2.6. mysite/setting.pySTATIC_ROOT 설정 추가

$ vim mysite/setting.py
...
STATIC_URL = '/static/'
STATIC_ROOT='static'

1.2.6. static file들을 static 폴더로 모으기

$ python manage.py collectstatic

1.2.6. gcloud init 명령으로 이 예제 앱을 어느 계정에 연결할 지, 어느 프로젝트에 올릴지 등을 설정한다.

  • $ gcloud init
  • [2] Create a new configuration
  • configuration name 설정
  • google cloud 계정 선택
  • cloud project 선택

1.2.7. gcloud app deploy 명령으로 Google Cloud 에 올려보자.

  • $ gcloud app deploy
  • Chrome 에서 https://<프로젝트ID>.appspot.com/polls 로 접속해보자. "Hello, world. You're at the polls index." 문구가 출력되면 성공! 그리고 https://<프로젝트ID>.appspot.com/admin 으로 접속했을 때 로컬에서 실행했을 때처럼 깔끔하게 로그인 창이 뜨면 성공!!

2. Google Cloud SQL 인스턴스 생성 및 연결

2.1. MySQL client 설치

1세대는 mysql 5.5, 5.6 버전을 지원하고, 2세대는 5.6, 5.7 버전을 지원한다. 사용할 SQL 인스턴스 세대에 알맞은 버전의 클라이언트를 설치하자.

2.1.1 Ubuntu

  • apt-get 명령으로 설치하면 된다.

    $ mysql -V                                      # 현재 깔려있는 버전 확인
    $ sudo apt-get update
    $ sudo apt-get upgrade
    $ sudo apt-get install mysql-client-core-5.X    # 설치
    $ mysql -V                                      # 설치된 버전 확인
    

2.1.2 Mac OS

페이지를 참고하자.

2.2. MySQL Python 설치

  • Anaconda로 MySQL Python 패키지를 설치한다.

    $ conda install -c alefnula mysql-python 
    
    • MySQL sever나 client 가 설치되어있지 않으면 에러가 발생한다.
    • python -c "import MySQLdb" 명령을 실행했을 때 에러가 없으면 성공
    • 만약에 라이브러리 관련 에러(Library not loaded: libmysqlclient.18.dylib)가 발생하면 여기 답변을 보고 심볼릭 링크를 만들어 준다.

2.3. Google Cloud SQL 인스턴스 생성 및 설정

cloud console의 SQL 페이지에서 인스턴스를 생성할 수 있다. 1세대와 2세대가 있는데, 2세대는 MySQL 새 버전을 지원하고 가격이 저렴한 반면에, 응답속도가 늦고 대부분 설정을 콘솔 페이지가 아닌 mysql-client로 접속해서 설정해야 한다. GAE+Django 문서에는 1세대만 사용할 수 있다고 나와있지만, 2세대로도 연결 가능하다.

2.3.1 Google Cloud SQL 1세대

2.3.2 Google Cloud SQL 2세대

A. Cloud SQL 인스턴스 생성

  • 좌측 상단 모서리의 "제품 및 서비스" >> "SQL" >> "인스턴스 생성" >> "2세대 선택"
  • 인스턴스 ID: mysql-2nd
  • 데이터베이스 버전: MySQL 5.6, 5.7 둘 다 별 문제 없음
  • 장애 조치용 복제본: 선택
  • "+ 네트워크 추가"
    • 네트워크: 0.0.0.0/0
    • "완료"
  • "생성"

B. MySQL 설정

  • "제품 및 서비스" >> "SQL" >> "mysql-2nd"
  • "개요" 탭에서 "IPv4 주소"를 메모해두자. (이하 <IP주소>)
  • "개요" 탭에서 "인스턴스 연결 이름"을 메모해두자. (이하 <인스턴스 연결 이름>)
  • "액세스 제어" >> "사용자" >> "루트 비밀번호 변경" >> 새 비밀번호 입력 후 "확인" (이하 <db root 비번>)
  • mysql client로 Cloud SQL 인스턴스에 접속
    $ mysql -h <IP주소> -u root -p  
    Enter password: <db root 비번>
    
  • 데이터베이스와 사용자 생성 - 참고1, 참고2
    mysql> SHOW DATABASES;           # DB List 확인
    mysql> CREATE DATABASE polls;    # polls DB 생성
    mysql> SHOW DATABASES;           # 제대로 생성되었는지 확인
    mysql> GRANT ALL PRIVILEGES ON polls.*          # 로컬 접속 사용자 pythonapp을 생성하고 
        -> TO pythonapp@localhost                   # 데이터베이스 polls의 권한을 부여한다.
        -> IDENTIFIED BY '<사용자 pythonapp의 비번>';
    mysql> GRANT ALL PRIVILEGES ON polls.*          # 원격 접속 사용자 pythonapp을 생성하고 
        -> TO pythonapp@'%'                         # 데이터베이스 polls의 권한을 부여한다.
        -> IDENTIFIED BY '<사용자 pythonapp의 비번>';
    mysql> use mysql;                   # mysql db 사용
    mysql> select user, host from user; # 사용자 확인
    mysql> exit                         # 나가기
    
    $ mysql -h <IP주소> -u pythonapp -p  # 새 사용자 로그인 테스트
    

2.4. Django 설정 및 배포

2.4.1. Django MySQL 설정

mysite/setting.py를 열고 아까 주석처리한 db 설정 아래에 다음과 같이 추가한다.

$ vim mysite/setting.py
import os
if os.getenv('SERVER_SOFTWARE', '').startswith('Google App Engine'):
    # Running on production App Engine, so use a Google Cloud SQL database.
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'HOST': '/cloudsql/<인스턴스 연결 이름>',
            'NAME': 'polls',                       # database name
            'USER': 'pythonapp',                   # mysql user
            'PASSWORD': '<사용자 pythonapp의 비번>',  # mysql user password
        }
    }
else:
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'HOST': '<IP주소>',
            'PORT': '3306',
            'NAME': 'polls',                       # database name
            'USER': 'pythonapp',                   # mysql user
            'PASSWORD': '<사용자 pythonapp의 비번>',  # mysql user password
        }
    }

2.4.2. Django migrate 및 로컬에서 실행

먼저 migrate 명령을 실행해 polls 데이터베이스에 테이블을 생성하고, createsuperuser 명령으로 admin 사용자를 만들어보자.

$ python manage.py migrate           # DB 테이블 생성 (User, Group 등)
$ python manage.py createsuperuser   # admin 사용자 생성

Cloud SQL 인스턴스로 접속해서 admin 사용자가 생성된 것을 확인해보자.

$ mysql -h <IP주소> -u pythonapp -p

mysql> SHOW DATABASES;
mysql> USE polls;
mysql> SHOW TABLES;
mysql> select id, username, date_joined from auth_user; 
mysql> exit

Django 서버를 실행하고 http://localhost:8000/admin으로 접속해 로그인해보자.

$ python manage.py runserver

2.4.3. Google App Engine에 배포하기

app.yaml에 아래 내용을 추가하자.

$ vim app.yaml

libraries:
- name: MySQLdb
  version: 1.2.5

Google App Engine으로 배포하고, 사이트로 접속해보자.

$ gcloud app deploy
$ gcloud app browse

https://<프로젝트 ID>.appspot.com/admin/ 으로 들어가서 로그인했을 때 아래와 같이 뜨면 성공이다. 성공스샷

⚠️ **GitHub.com Fallback** ⚠️