기본정리
나보다 잘 정리한 사람도 많고...그냥 이해한대로 최대한 정리해봤다.
# 배포 아키텍처
- WSGI(Web Server Gateway Interface) : Application Server를 호출하여 동적인 요청을 처리할 수 있는 서버
- python은 Gunicorn을 사용한다. Django의 runserver와 같은 역할!
- NGINX : Client에게 받은 정적인 요청을 Gunicorn으로 전달하여 처리하는 Web Server.
- 즉, 이 프로젝트에서 NGINX는 정적인 요청은 알아서 처리하여 사용자에게 return하고, 동적인 요청을 처리하기 위해 Application Server를 불러올 수 있는 Gunicorn을 통해 처리한다.
# Docker
- OS에 관계없이 내가 만든 프로젝트가 같은 환경에서, 동일하게 실행할 수 있도록 도와주는 가상 컨테이너 기술
- 가상 컨테이너란 소프트웨어 구동 환경을 뜻하는데, 즉 나의 application과 관련된 라이브러리들을 함께 묶어 패키지로 만든다.
- 가상컨테이너는 Dockerfile을 통해 명시한다. Dockerfile을 실행함으로써 실행에 필요한 설정값, 파일(라이브러리)들을 가지고 있는 Image를 정의한다.
- Image==나의 application 환경 정도로 이해했다.
- 파일을 분석해보자.
#Dockerfile
FROM python:3.8.3-alpine
ENV PYTHONUNBUFFERED 1
RUN mkdir /app
WORKDIR /app
RUN apk add --no-cache mariadb-connector-c-dev
RUN apk update && apk add python3 python3-dev mariadb-dev build-base && pip3 install mysqlclient && apk del python3-dev mariadb-dev build-base
COPY requirements.txt /app/requirements.txt
RUN pip install -r requirements.txt
COPY . /app/
- FROM python:3.8.3-alpine : Docker의 기반이 될 이미지다
- https://hub.docker.com/ <- 여기에서 여러 이미지를 찾을 수 있는데, alpine가벼워서 많이 쓰는 듯
- ENV PYTHONUNBUFFERED 1 : 환경변수(모드). 이미지와의 충돌을 막고 출력 로그 버퍼링을 없애고...뭐 그렇다고 한다.
- RUN mkdir /app : 현재 경로(mkdir)에 빈 디렉토리(app) 생성
- WORKDIR /app : default directory 변경
- RUN apk ~~ : 자세한 설명은 없지만...데이터베이스(mysql) 사용을 위한 환경을 만들고, 설치하고 실행하기
- COPY requirements.txt~~ : 이전에 pip freeze > requirements.txt로 필요한 라이브러리를 모아둔 파일을 app 디렉토리로 복사한다.
- RUN pip install ~~ : 필요한 라이브러리들 가상환경에 설치
- COPY . /app/ : 내가 짠 코드들을 app에 복사하고 실행하기
- 여러 명령어들...처음 보는 것들도 있다.
- 참고로 모두 가상 컨테이너를 만들고 거기에서 실행하는 것이므로, 오류가 나면 아래 명령어와 해결법을 참고하여 꼭 Dockerfile에 적어주자!!!
괜히 내 프로그램에다가 설치하고 왜 해결이 안되지~~이러지말자
명령어 | 용도 |
FROM | base 이미지 설정 |
WORKDIR | 작업 디렉토리 설정 |
RUN | 이미지 빌드 시 실행할 커멘드 |
ENTRYPOINT | 이미지 실행 시 항상 실행되어야 하는 커멘드 |
CMD | 이미지 실행 시 디폴트 커멘드 또는 파라미터 설정 |
EXPOSE | 컨테이너가 리스닝할 포트 및 프로토콜 설정 |
COPY/ADD | 이미지의 파일 시스템으로 파일 또는 디렉터리 복사 |
ENV | 환경변수 설정 |
ARG | 빌드 시 넘어올 수 있는 인자 설정 |
# docker-compose.yml
- Dockerfile에서 만든 이미지들을 쉽게 실행하기 위한 도구이다.
- 이미지를 여러개 띄워서 네트워크를 만들거나, 컨테이너 밖의 호스트와 연결하는 등의 여러 제어를 담당한다.
version: '3'
services:
db:
container_name: db
image: mysql:5.7
restart: always
environment:
MYSQL_ROOT_HOST: '%'
MYSQL_ROOT_PASSWORD: mysql
expose:
- 3306
ports:
- "3307:3306"
env_file:
- .env
volumes:
- dbdata:/var/lib/mysql
web:
container_name: web
build: .
command: sh -c "python manage.py migrate && python manage.py runserver 0.0.0.0:8000"
environment:
MYSQL_ROOT_PASSWORD: mysql
DATABASE_NAME: mysql
DATABASE_USER: 'root'
DATABASE_PASSWORD: mysql
DATABASE_PORT: 3306
DATABASE_HOST: db
DJANGO_SETTINGS_MODULE: django_rest_framework_17th.settings.dev
restart: always
ports:
- "8000:8000"
volumes:
- .:/app
depends_on:
- db
volumes:
app:
dbdata:
- Docker-compose의 version : 3
- service : 다음줄부터 서비스를 설정한다(port, volumes 등)
- 나는 db와 web 컨테이너를 설정해주었다. (container_name으로 이름 따로 설정 가능)
- web
- build : . -> project root안에 있는 모든 것들을 build함.
- volumes : 프로젝트가 업데이트되면 docker를 재실행할 필요없이 자동으로 container에 업데이트 된다.(로컬과 매핑)
- command : docker cotainer안에서 실행할 command (sh == shell, -c == command)
- ports : -> port번호
- db
- 뭐...적혀진대로 이해하면 된다.
- 다만 프로젝트가 업데이트되면 db는 다른 경로로 업데이트 됨
# docker-compose.prod.yml
- 이전에 작성한 yml파일은 로컬에서 실행하기 위한 파일이다.
- 이 파일은 실제 배포를 위한 파일로, 나중에 github action을 통해 실행해줄 것이다.
- 데이터 해킹 방지를 위해 db컨테이너가 없고, 대신 배포를 위한 nginx 컨테이너가 존재한다.
- nginx도 마찬가지로 nginx Dockerfile이 존재하고, 또 Dockerfile에서 COPY하기 위한 nginx의 환경설정(config)파일도 프로젝트 내에 작성해주었다.
- 추가로 비용이 큰 static과 media 파일은 따로 정의
version: '3'
services:
web:
container_name: web
build:
context: ./
dockerfile: Dockerfile
command: gunicorn django_rest_framework_17th.wsgi:application --bind 0.0.0.0:8000
environment:
DJANGO_SETTINGS_MODULE: django_rest_framework_17th.settings.prod
env_file:
- .env
expose:
- 8000
volumes:
- static:/home/app/web/static
- media:/home/app/web/media
entrypoint:
- sh
- config/docker/entrypoint.prod.sh
nginx:
container_name: nginx
build: ./config/nginx
volumes:
- static:/home/app/web/static
- media:/home/app/web/media
ports:
- "80:80"
depends_on:
- web
volumes:
static:
media:
- entrypoint : collectstatic을 수행하기 위해 넣어준 파일
- static파일을 한 곳에 모아 처리하기 위함.
- 필요하면 python manage.py migrate을 넣어줄 수도 있다.
- 나는 직접 EC2에 연결하고, docker-compose 명령어를 통해 migrate를 실행했었는데...정리면서 보니까 이렇게 하는 방법도 있었구나...😂 담에는 이걸로 해봐야지...
#!/bin/sh
python manage.py collectstatic --no-input
exec "$@"
# 로컬에서 실행
- docker-compose -f docker-compose.yml up --build를 통해 실행해준다.
- 여러 명령어가 있다.
- -d 옵션으로 terminal을 닫아도 계속 실행되게 할수도 있다.(down -v로 닫아줌)
- 여러 명령어들은...필요하면 공부하자.
- 잘 실행된다!!
- 이제 로컬에서 docker가 잘돌아가는 것을 확인했으니, 실제 서버에 배포해보자~~

# 참고
- Docker-compose 파일 정리 https://nirsa.tistory.com/79
[Docker CE] docker-compose 문법 간단 정리 (1) (image, build, command, entrypoint, links)
docker-compose는 여러개의 컨테이너 설정 내용을 하나의 파일에 모아서 사용하는 YAML 파일 입니다. 이 docker-compose는 컨테이너의 서비스(services:), 네트워크(networks:), 볼륨(volumes:)을 정의 합니다. docker
nirsa.tistory.com
'django > 정리' 카테고리의 다른 글
AWS 배포(4) - SSH 연결 및 docker 관리 (1) | 2023.05.24 |
---|---|
AWS 배포(3) - https, 도메인 (0) | 2023.05.24 |
AWS 배포(2) - EC2, RDS, github action (0) | 2023.05.24 |
CEOS Readme 정리 - 4주차:DRF2 : Simple JWT & Permission (0) | 2023.05.08 |
[Django] choice와 mutiplechoice (0) | 2023.03.22 |