Django Serverless deploy | zappa

Jihun Kim·2021년 11월 9일
2

프로젝트

목록 보기
3/3
post-thumbnail

Serverless란?

  • 관리할 서버가 없다는 뜻으로, 서버 인프라를 구축/ 운영/ 관리하지 않고도 코드 배포만으로 백엔드 애플리케이션을 구축할 수 있는 아키텍쳐
  • 서버리스로 배포시 서버 구축이나 운영에 대한 고민 없이 서비스 자체에만 집중할 수 있다.

lambda를 이용하자.

서버를 관리하지 않고도 코드를 실행할 수 있게 해주는 컴퓨팅 서비스

  • lambda를 잘 다룰 수 있다면 다양한 리소스와 적절히 조합해서 다양한 백엔드 서비스를 쉽게 구현할 수 있다.
  • 람다는 코드로 이루어진 '함수'를 실행한다고 보면 된다.
    👉 이 때 실행되는 함수를 '람다 함수'라고 말한다.
  • 람다 함수는 특정 이벤트가 발생 했을 때 실행된다.
    👉 가령, API Gateway가 호출 되었을 때 람다를 실행하여 코드를 실행할 수 있다.

즉, 특정 이벤트에 람다 함수를 연결하여 우리가 원하는 시점에만 애플리케이션 코드를 실행하도록 할 수 있다.


Lambda를 사용하는 기업은 어떤 곳이 있을까?

  • 직방
  • 당근마켓

EC2와 비교해서 좋은 점은?

  • EC2를 사용하게 되면 서버를 켜두는 비용만으로 최소 월 몇 만원씩 나오게 되는데 람다는 코드가 호출되고 실행되는 시간 단위로 비용이 청구되기 때문에 훨씬 저렴함!
  • 트래픽이 적고 간단한 서비스 사용에 매우 좋음

Lambda 특징

lambda 사용시 주의
월별 컴퓨팅 요금은 GB-초당 0.0000166667 USD이고 프리 티어에서 400,000GB-초를 제공합니다.



Zappa 배포

AWS 세팅

아래의 유튜브 영상 보고 따라했다.
코딩PM
👉 aws 계정 cli에서 설정하는 것까지 알려줘서 좋음!

aws cli 설치방법


zappa 사용을 위한 IAM policy
'기존 정책에 직접 생성' -> '정책 생성'에 추가하면 됨
S3(static files 저장)와 lambda에 대한 모든 권한이 필요하다.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:AttachRolePolicy",
                "iam:GetRole",
                "iam:CreateRole",
                "iam:PassRole",
                "iam:PutRolePolicy"
            ],
            "Resource": [
                "arn:aws:iam::[본인의 iam account 번호]:role/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "lambda:CreateFunction",
                "lambda:ListVersionsByFunction",
                "lambda:DeleteFunctionConcurrency",
                "logs:DescribeLogStreams",
                "events:PutRule",
                "lambda:GetFunctionConfiguration",
                "cloudformation:DescribeStackResource",
                "apigateway:DELETE",
                "apigateway:UpdateRestApiPolicy",
                "events:ListRuleNamesByTarget",
                "apigateway:PATCH",
                "events:ListRules",
                "cloudformation:UpdateStack",
                "lambda:DeleteFunction",
                "events:RemoveTargets",
                "logs:FilterLogEvents",
                "apigateway:GET",
                "lambda:GetAlias",
                "events:ListTargetsByRule",
                "cloudformation:ListStackResources",
                "events:DescribeRule",
                "logs:DeleteLogGroup",
                "apigateway:PUT",
                "lambda:InvokeFunction",
                "lambda:GetFunction",
                "lambda:UpdateFunctionConfiguration",
                "cloudformation:DescribeStacks",
                "lambda:UpdateFunctionCode",
                "events:DeleteRule",
                "events:PutTargets",
                "lambda:AddPermission",
                "cloudformation:CreateStack",
                "cloudformation:DeleteStack",
                "apigateway:POST",
                "lambda:RemovePermission",
                "lambda:GetPolicy"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucketMultipartUploads",
                "s3:CreateBucket",
                "s3:ListBucket"
            ],
            "Resource": "arn:aws:s3:::*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:AbortMultipartUpload",
                "s3:DeleteObject",
                "s3:ListMultipartUploadParts"
            ],
            "Resource": "arn:aws:s3:::*"
        }
    ]
}

zappa 실행

sqlite 사용

sqlite3 을 사용해 저장하려고 하는데, 아래와 같은 오류가 발생한다.

sqlite3: attempt to write a readonly database

디비 파일의 권한 이슈가 문제여서

아래의 방법이 해결책이라고 해서 그대로 해봤는데, 불가능한 해결 방법이었다.

$ sudo chmod 775 /var/www/mysite
$ sudo chmod 664 /var/www/mysite/sqlite.db

sqlite 말고 RDS 사용하기

나는 프리 티어 사용할 수 있는 계정이 없어서 Sqlite로 사용하고 싶었는데 방법이 없다.... 일단 사용 방법은 아래와 같다.

일단 모듈을 다운 받는다.

$ pip install mysqlclient

아래와 같이 데이터베이스 설정을 settings.py에서 변경한다.

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'pollsdb', # dbname
        'USER': 'polls_admin', # master username
        'PASSWORD': 'pollsadmin', # master password
        'HOST': 'pollsapi-cluster.cluster-chcxxxxx.us-east-2.rds.amazonaws.com', # Endpoint
        'PORT': '3306',
    }
}

데이터베이스를 세팅하기 위해 명령어를 실행할 수 있는 디렉토리와 파일을 생성한다.

$ python manage.py startapp core
$ cd core
$ mkdir management
$ cd management
$ touch __init__.py
$ mkdir commands
$ cd commands
$ touch __init__.py
$ touch create_db.py

루트 디렉토리/core/management/commands/create_db.py

import sys
import logging
import MySQLdb

from django.core.management.base import BaseCommand, CommandError
from django.conf import settings

rds_host = 'pollsapi-cluster.cluster-chc62yjp918f.us-east-2.rds.amazonaws.com'
db_name = 'pollsdb'
user_name = 'polls_admin'
password = 'pollsadmin'
port = 3306

logger = logging.getLogger()
logger.setLevel(logging.INFO)


class Command(BaseCommand):
    help = 'Creates the initial database'

    def handle(self, *args, **options):
        print('Starting db creation')
        try:
            db = MySQLdb.connect(host=rds_host, user=user_name,
                                 password=password, db="mysql", connect_timeout=5)
            c = db.cursor()
            print("connected to db server")
            c.execute("""CREATE DATABASE pollsdb;""")
            c.execute(
                """GRANT ALL PRIVILEGES ON db_name.* TO 'polls_admin' IDENTIFIED BY 'pollsadmin';""")
            c.close()
            print("closed db connection")
        except:
            logger.error(
                "ERROR: Unexpected error: Could not connect to MySql instance.")
            sys.exit()

zappa 업데이트 후

$ zappa update dev

데이터베이스를 생성한다.

$ zappa manage dev create_db

마이그레이션 한다.

$ zappa manage dev migrate

어드민 유저를 생성해 본다.

$ zappa invoke --raw dev "from django.contrib.auth.models import User; User.objects.create_superuser('admin', 'anmol@agiliq.com', 'somerandompassword')"

DB 설정 잘 나와 있는 사이트


url 접근시 css 적용이 안되어 있는 문제
django-s3-storage 모듈을 이용하면 된다.

pip install django-s3-storage

그리고 settings.py에 설정을 추가해 준다.
S3_BUCKET_NAME은 내가 zappa에 설정한 bucket_name이기 때문에 자신의 것으로 바꾸면 된다.

STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")
# S3 storage
S3_BUCKET_NAME = "developer-zappa-static"
STATICFILES_STORAGE = "django_s3_storage.storage.StaticS3Storage"
AWS_S3_BUCKET_NAME_STATIC = S3_BUCKET_NAME
# serve the static files directly from the specified s3 bucket
AWS_S3_CUSTOM_DOMAIN = "%s.s3.amazonaws.com" % S3_BUCKET_NAME
STATIC_URL = "https://%s/" % AWS_S3_CUSTOM_DOMAIN


💡 참고자료

zappa 사용 관련 참고 블로그
zappa 블로그1
zappa 블로그2
zappa 블로그3
Oauth도 이용한 블로그

profile
쿄쿄

0개의 댓글