[django] EC2에서 gunicorn 연동 + S3(static, media)

최동혁·2023년 3월 6일
0

클라우드

목록 보기
11/18

Gunicorn이란?

  • Python WSGI(Web Server Gateway Interface)로 WEB Server(Nginx)로부터 서버사이드 요청을 받으면 WSGI(Gunicorn)를 통해 서버 어플리케이션(Django)으로 전달하는 역할을 함
  • Django의 [ runserver ] 명령어는 단일 쓰레드로 작동하여 테스트용도로 적당하나, Request 요청이 많아질 경우 현저히 처리 능력이 떨어지므로 Production 환경에는 사용할 수 없음
  • WSGI는 멀티 쓰레드를 만들 수 있도록하여 Request 요청이 많아지더라도 효율적으로 처리하므로 Production 환경에 사용

가상환경 준비

  • AWS의 EC2로 준비 Ubuntu 20.04 프리 티어

사전 설치 파일

gunicorn 설치

  • pip install gunicorn
  • gunicorn myproject.wsgi:application
    • 해당 명령어로 gunicorn을 실행해본다.
    • 에러 없이 실행되면 된거다.
  • vi /etc/systemd/system/gunicorn.service
[Unit]
Description=gunicorn daemon
After=network.target

[Service]
User=root
Group=root
WorkingDirectory=/root/greenyday/backend

ExecStart=/root/greenyday/backend/venv/bin/gunicorn --workers 3 --bind 0.0.0.0:8000 backend.wsgi:application

[Install]
WantedBy=multi-user.target
  • User와 Group은 root 사용자로 지정
  • 현재 배포할 프로젝트의 폴더 위치를 WorkingDirectory로 잡아준다.(manage.py가 있는 경로)
  • 가상환경에 gunicorn을 설치했기 때문에 ExecStart 경로로 가상환경안의 gunicorn을 입력
  • workers 뒤에 숫자는 스레드의 갯수를 의미한다.
    • 통상 서버의 코어 * 2를 입력해준다.

gunicorn 실행

  • systemctl start gunicorn
  • systemctl status gunicorn 명령어로 gunicorn service가 제대로 돌아가는지 확인

static, media 폴더

  • Gunicorn은 WSGI(Web Server Gateway Interface) 애플리케이션 서버로, HTTP 요청을 Django 애플리케이션으로 전달하고 그 결과를 다시 HTTP 응답으로 반환하는 역할을 한다.

  • 하지만 Gunicorn은 Django의 정적 파일(Static files)과 미디어 파일(Media files)을 자동으로 처리하지 않는다.

    • 나는 react랑 연동해서 was로 drf 사용할거니깐 static 폴더 필요없는데?
    • 그래도 장고에서 제공해주는 admin 페이지가 많이 유용한데 css(static) 없이 들어가면 UI가 보기 불편하다..
    • media 폴더는 사진 업로드 같은 것들이다.
  • Django의 정적 파일은 CSS, JavaScript, 이미지 등의 파일로, 애플리케이션에서 사용하는 파일이다.

  • 이 파일들은 애플리케이션 코드와는 별도로 관리되어야 한다.

  • 보통 이러한 파일들은 웹 서버(apache, nginx 등)에서 직접 제공하거나, Django에서 제공하는 collectstatic 명령을 사용하여 별도의 디렉토리에 모아놓고 웹 서버에서 이를 서빙한다.

  • 반면, 미디어 파일은 애플리케이션에서 업로드되는 이미지, 동영상 등의 파일이다.

  • 이 파일들은 Django의 MEDIA_ROOT 설정에 지정된 디렉토리에 저장된다.

  • 웹 서버는 이러한 미디어 파일을 직접 서빙하거나, Django에서 제공하는 MEDIA_URL 설정에 따라 서빙한다.

따라서, Gunicorn을 사용하더라도 Django의 정적 파일과 미디어 파일은 웹 서버에서 처리되어야 하며, 애플리케이션 서버는 그저 HTTP 요청을 받아서 Django 애플리케이션으로 전달하는 역할을 한다.

  • 나는 Web Server로 AWS의 S3 버킷에 빌드 파일을 올려서 배포할 것이기 때문에, media 파일과 static 파일도 S3에서 함께 보관할 것이다.

AWS IAM 사용자 생성

AWS S3 버킷 생성

권한 설정

  • 권한 클릭

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowPublicRead",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::greenyday/*"
        }
    ]
}
  • 위의 코드와 같이 세팅해준다.

django 내부 설정

django_storages 설치

  • pip install django_storages
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # AWS S3
    'storages',
]
  • settings.py에 app 추가

boto3

  • django_storages 패키지는 boto3 라는 패키지를 사용하여 S3와 통신하도록 구성되어있다.
  • boto3 는 S3를 조작할 수 있는 API에 맞는 요청을 Python으로 작성해놓은 패키지이다.
  • boto3 를 사용하면 requests 패키지를 사용해서 직접 요청을 보내도록 코딩을 할 필요 없이 미리 정의된 메서드를 사용해서 간편히 API를 다룰 수 있다.
  • boto3 는 단순한 파일 저장, 삭제 등과 같은 기능 이외에도 버킷 생성, 권한 설정 등과 같은 S3 편의 기능도 제어할 수 있도록 작성되어 있다. django_storages 는 이 boto3를 사용하여 S3에 파일을 저장하는 저장 시스템 클래스인 것이다.

설치

  • pip install boto3

s3라는 새로운 앱 생성

  • python manage.py startapp s3
  • 그 후, 새로운 앱을 만들었으니 settings.py의 새로운 앱에 추가

settings.py

    # AWS Setting
    AWS_REGION = 'ap-northeast-2'
    AWS_STORAGE_BUCKET_NAME = 'BUCKET_NAME'
    AWS_QUERYSTRING_AUTH = False
    AWS_S3_HOST = 's3.%s.amazonaws.com' % AWS_REGION
    AWS_ACCESS_KEY_ID = 'ACCESS_KEY_ID'
    AWS_SECRET_ACCESS_KEY = 'SECRET_ACCESS_KEY'
    AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME

    # Static Setting
    STATIC_DIR = os.path.join(BASE_DIR, 'static')
    STATICFILES_DIRS = [
    	STATIC_DIR,
    ]
    STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles/')
    STATIC_URL = "https://%s/" % AWS_S3_CUSTOM_DOMAIN
    STATICFILES_STORAGE = 'backend.storages.StaticStorage'

    #Media Setting
    MEDIA_URL = "https://%s/" % AWS_S3_CUSTOM_DOMAIN
    DEFAULT_FILE_STORAGE = 'backend.storages.MediaStorage'

storages.py

  • settings.py가 있는 폴더 안에 storages.py 파일을 만들자
from django.conf import settings
from storages.backends.s3boto3 import S3Boto3Storage


class MediaStorage(S3Boto3Storage):
    location = settings.MEDIAFILES_LOCATION


class StaticStorage(S3Boto3Storage):
    location = settings.STATICFILES_LOCATION
  • 위의 코드를 입력하고 저장

S3에 static 파일 모으기

  • manage.py가 있는 곳에 static 폴더 생성
  • python manage.py migrate
  • python manage.py collectstatic
    • 해당 명령어를 입력하면 진짜 원하냐고 물어볼것이다. yes를 입력하자.

결과

  • media폴더와 static 폴더로 나뉘어서 저장되어 있는 것을 볼 수 있다.

  • admin 페이지에 들어가면 위의 그림처럼 css 파일이 잘 적용된 것을 확인할 수 있다.
  • 사진 파일을 업로드 하면 media 폴더 아래에 저장되는 것도 확인할 수 있다.
profile
항상 성장하는 개발자 최동혁입니다.

0개의 댓글