Search

[django, drf] django(drf) 개발/배포 환경 별로 환경변수 분리하기 (dotenv, docker-compose 사용)

타입
개발
태그
django
drf
docker
docker-compose
상태
Published
생성일
2023/02/02 04:55
최종 편집 일시
2023/07/18 01:46
2 more properties

개요

django(drf) 에서 환경별로 환경변수를 다르게 할 필요가 있었다.
하지막 막상 구글링을 해보니 단일환경에서 .env 파일 하나만 쓰는 글들만 많이 있었고, 그게 아니면 settings.py 만 분리하는 글들이 대부분이였다.
환경 별로 .env 를 나누고, 각 환경마다 django settings 파일까지 분리하는 글은 아직은 찾지 못했다.
약간의 삽질을 통해서 원하는 개발/배포 환경분리 세팅을 완료하였다.
내가 구축하려고 하는 환경분리는 아래와 같다
프로젝트의 환경은 세 개의 환경으로 나뉘어져 있다.
백엔드(drf)
DB(postgreSQL)
local 환경
로컬
로컬
dev 환경
docker(로컬)
로컬
prod 환경
docker(EC2)
AWS RDS
지금 같은 상황에서 dev 환경은 로컬에서 docker 로만 백엔드를 띄울뿐이여서 사실 local 환경이랑 크게 다를 바가 없다.
dev환경에서 개발용 백엔드 서버와 개발용 DB서버 를 구축하는 것이 베스트였겠으나 우선은 저렇게 세팅을 했다

.env 파일 작성

python 에서 .env 파일을 읽기 위해 python-dotenv 패키지를 설치한다.
패키지를 설치했다면 .env 파일을 작성해주면 된다.
환경변수의 종류가 하나만 필요하다면 파일명을 그냥 .env 로만 작성해주는 것이 편하다.
파일명이 .env 이면 python-dotenv 에서 파일을 불러올 때 파일명을 명시안해줘도 알아서 인식을 하기 때문이다.
하지만 지금은 dev, local, prod 로 환경이 나뉘어져 있으므로 .env.local, .env.dev, .env.prod 로 파일명을 설정했다.
.env 파일은 key=value 형식으로 작성한다.
예시)
NAME=DB_test HOST=localhost PORT=5432 ...
Plain Text
복사

docker 설정

dev 환경과 prod 환경에서만 docker, docker-compose 를 사용한다.
dockerfile
dockerfile 은 dev, prod 환경 공통으로 사용한다.
FROM python:3.9-slim # python 출력 내용을 버퍼에 넣지 않고 바로 출력 => 로그 바로바로 보임 ENV PYTHONUNBUFFERED 1 COPY ./requirements.txt /tmp/requirements.txt COPY ./ /app WORKDIR /app EXPOSE 8000 RUN python -m venv /py && \ /py/bin/pip install --upgrade pip && \ /py/bin/pip install -r /tmp/requirements.txt && \ rm -rf /tmp && \ mkdir logs ENV PATH="/py/bin:$PATH"
Docker
복사
docker-compose.dev.yml
dev 환경에서 사용할 docker-compose 파일
version: '3.9' services: app: build: context: . # dockerfile 이 있는 경로 ports: - '8000:8000' volumes: - ./:/app command: > sh -c "python manage.py makemigrations && python manage.py migrate && python manage.py runserver --insecure 0.0.0.0:8000 --settings=config.settings.dev" env_file: - .env.dev environment: - ENV=dev
YAML
복사
  env_file 로 .env.dev 파일을 설정한다.
  environment 변수로 ENV=dev 를 설정한다.
docker-compose.prod.yml
prod 환경에서 사용할 docker-compose 파일
version: '3.9' services: app: build: context: . # dockerfile 이 있는 경로 ports: - '8000:8000' volumes: - ./:/app command: > sh -c "python manage.py makemigrations && python manage.py migrate && python manage.py runserver --insecure 0.0.0.0:8000 --settings=config.settings.prod" env_file: - .env.prod environment: - ENV=prod
YAML
복사
  env_file 로 .env.prod 파일을 설정한다.
  environment 변수로 ENV=prod 를 설정한다.

settings.py 분리

settings.py 에 관한 상세한 설명은 아래 글에 잘 나와있다.
settings 폴더 밑에 공통파일인 base.py 가 있고 dev.py, local.py, prod.pybase.py 를 상속받는다.

base.py

config/settings/base.py
import os from dotenv import load_dotenv # 생략 .. ENV = os.getenv("ENV", "local") if ENV == "local": load_dotenv(verbose=True, dotenv_path=f"{BASE_DIR}/.env.local") # local 환경에서만 .env 파일 직접 매핑시켜줌 # dev, prod 환경의 .env 파일은 docker-compose 가 주입해준다.
Python
복사
dev 환경과 prod 환경에서는 docker-compose 를 사용하므로 compose yaml 파일에서 설정한 .env 파일이 주입되는데, local 환경은 docker 를 사용하지 않으므로 직접 설정해줘야 한다.
또한 local 환경인지 파악하기 위해서 ENV 환경변수의 값이 local 인지 확인을 할건데, 이는 뒤에 나오는 쉘 스크립트에서 export 문으로 설정해줄 것이다.

local.py, dev.py, prod.py

from .base import * # 환경별로 세팅 값 추가할 사항 있으면 추가하기
Python
복사

(선택) shell script 생성

매번 직접 커맨드를 치기 귀찮으므로 shell script 를 만들어준다.
물론 터미널에 직접 커맨드를 쳐도 무방하다.

runserver.local.sh

export ENV=local python manage.py makemigrations python manage.py migrate python manage.py runserver --insecure 0.0.0.0:8000 --settings=config.settings.local
Shell
복사
  export ENV=local : 환경변수 설정
  runserver 를 돌리기 전에 DB migration 을 한다.
  --settings=config.settings.local : setting 파일 매핑

runserver.dev.sh

docker-compose -f docker-compose.dev.yml build docker-compose -f docker-compose.dev.yml
Shell
복사

runserver.prod.sh

docker-compose -f docker-compose.prod.yml build docker-compose -f docker-compose.prod.yml up
Shell
복사

실행

local 환경 : sh runserver.local.sh
dev 환경 : sh runserver.dev.sh
prod 환경 : sh runserver.prod.sh

TODO

prod 환경에서 runserver 대신 nginx 와 gunicorn 을 적용하고 DEBUG=False 로 바꾸기