본문 바로가기
IT/Deploy

Django 프로젝트 Docker를 사용하여 배포하기

by Cyber_ 2024. 4. 16.

목차

    Docker가 없는 배포

    처음 Django 웹 애플리케이션을 배포할 때 Docker없이 EC2에 아래의 패키지와 파일을 생성하여 관리해야 했었다.

    • /home/usr/projects/django: 프로젝트 소스코드
    • /home/usr/venvs/django: 프로젝트 가상환경
    • /home/usr/venvs/django.env: 가상환경 실행 명령어
    • /home/usr/venvs/django.sh: 가상환경 실행 및 gunicorn 실행 자동화
    • /etc/nginx/sites-enabled: nginx 파일

    보통 로컬에서 개발과 테스트를 마치고 서버환경에서 개발에 사용된 도구(Django, nginx 등)에 대한 버전을 맞추어 설치해 주고 설정파일들을 작성해주어야 합니다.

    이 과정을 Docker가 대신한다면 위 모든 과정은 필요 없다.
    서버에서 docker로 이미지를 가져오기만 하면 된다.

    이번 포스팅에선 로컬에서 도커 이미지를 생성하고 서버에서 도커 이미지를 가져오는 기초적인 과정과 소스코드와 Nginx에 대한 이미지를 각각 띄워 docker-compose로 관리하는 내용을 기재하겠습니다.

    로컬에서 도커 사용하기

    1) 설치

    • Docker나 Dockerhub에서 회원가입한다.
    • 로컬에서 Docker Desktop을 설치한다.
    • 아래의 명령어를 입력해 사용된는 라이브러리의 리스트를 생성한다.
    pip freeze > requirements.txt

    2) DockerFile을 생성한다.

    pyko: 프로젝트 루트폴더이다.

    • DockerFile
    # 기본 이미지 설정
    FROM python:3.10.12
    
    ENV PYTHONDONTWRITEBYTECODE 1
    ENV PYTHONUNBUFFRED 1
    
    RUN apt-get update
    
    # 작업 디렉토리 설정
    WORKDIR /pyko
    
    RUN pip install --upgrade pip
    COPY ./requirements.txt  /pyko/
    RUN pip install --no-cache-dir -r requirements.txt
    
    COPY . /pyko/
    RUN mkdir -p /pyko/logs
    
    
    EXPOSE 8000
    
    # Gunicorn으로 실행
    CMD ["gunicorn", "--bind", "0.0.0.0:8000", "config.wsgi:application"]

    3) 도커 로그인

    docker login
    

    4) 도커 이미지 생성

    docker build `옵션` `도커에가입한 계정`/`프로젝트명`:`버전` `경로`
    docker build -t amdin/projects:0.1.0

    5) 생셩된 이미지 확인

    docker images

    6) 이미지 실행시키기

    docker run --name '컨테이너명' -d -p '호스트 포트':'
    컨테이너 포트'
    docker run --name projects01 -d -p admin/projects:0.1.0

    7) 실행중인 이미지 확인

    docker ps -a

    8) 도커허브에 푸시하기

    docker push '이미지명'

    서버(EC2 등)에서 도커로 배포하기

    1) 서버에서 docker 설치

    sudo apt update
    sudo apt install apt-transport-https ca-certificates curl software-properties-common 
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - 
    sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable" 
    sudo apt update 
    apt-cache policy docker-ce
    sudo apt install docker-ce

    2) 도커 로그인

    sudo docker login

    3) 도커 이미지 가져오기

    sudo docker pull admin/projects:0.1.0

    4) 도커 이미지 실행시키기

    sudo docker run --name '컨테이너명' -d -p 8000:8000 admin/projects:0.1.0

    다음 잘 작동하는지 확인

    sudo docekr ps -a 

    이제 IPAddress:8000에 접속하면 실행된 것을 확인할 수 있다. 하지만 nginx를 사용하지 않아 정적 파일을 서빙하지 못한다. nginx에대한 DockerFile을 하나 더 생성하고 docker-compose를 작성하여 두개의 이미지를 한번에 관리할 수 있도록 하겠습니다.

    nginx 이미지를 따로 생성하는 이유는 ?
    Nginx를 사용하여 정적파일만 서빙하는 것이아니다. 트래픽을 분산시키거나 성능을 최적화 시키는활동이 추가적으로 발생하기 때문에 프로젝트의 규모가 커질 경우 자원을 관리하는데 있어서 개발자는 프로젝트에 집중하고 시스템 관리자나 DevOps팀은 Nginx 설정과 성능 최적화 등에 집중할 수 있기 때문입니다.

    docker-compose 작성하기

    1) docker-compose란?

    docker-compose는 Docker에서 다중 컨테이너 애플리케이션을 정의하고 실행하기 위한 도구입니다. 단일 'docker'명령어를 사용하여 여러 컨테이너를 실행하는 것보다 여러 추가 이점을 제공합니다.

    • 서버에서 설치
    # 설치
    sudo curl -L https://github.com/docker/compose/releases/download/1.25.0-rc2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
    # 권한 설정
    $ sudo chmod +x /usr/local/bin/docker-compose
    # 버전확인
    $ docker-compose --version
     docker-compose version 1.25.0-rc2, build 661ac20e

    선택의 갈림길입니다.
    1. 서버에서 docker-compose를 설치: 그렇다면 서버의 소스코드가 존재하고 소스코드를 참조할 docker-compose.yml이 있어야합니다.
    2. 로컬에서 이미지 띄우기: 로컬에서 docker-compose를 설치하여 이미지를 Push하고 서버에서 두가지 이미지를 Pull하기
    !! 이번 포스팅에선 1번 방법으로 진행하였습니다.

    2) Nginx 패키지 생성


    위의 패키지 구조를 살펴보면 nginx.conf와 DockerFile을 추가로 생성 하였습니다.

    • DockerFile
    FROM nginx:1.18.0
    
    COPY nginx.conf /etc/nginx/nginx.conf
    
    EXPOSE 80
    
    CMD ["nginx", "-g", "daemon off;"]
    • nginx.conf
    user nginx;
    worker_processes auto;
    pid /var/run/nginx.pid; 
    
    events {
        worker_connections  768;
    }
    
    http {
        sendfile on;
        tcp_nopush on;
        types_hash_max_size 2048;
    
        include       /etc/nginx/mime.types;
        default_type  application/octet-stream;
    
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
        ssl_prefer_server_ciphers on;
    
    
        access_log  /var/log/nginx/access.log  main;
        error_log /var/log/nginx/error.log;
    
        gzip on;
    
    
        server{
            listen 80;
            server_name 13.125.16.6; # 이곳에는 아이피주소가 아닌 도메인이 와도 됩니다.
    
            location / {
                include proxy_params;
                proxy_pass http://13.125.16.6:8000/;
            }
    
            location /static/ 
                alias /pyko/static/; # 위의 포스팅 내용중 WORKDIR를 /pyko로 설정해주었기 때문에 경로가 이렇게 된 것입니다.
            }
    
            location /media/ {
                alias /pyko/media/;
            }
        }
    }

    3) docker-compose.yml생성

    version: '3.8'
    
    services:
      pyko:
        build: ./pyko
        restart: always
        command: gunicorn config.wsgi:application --bind 0.0.0.0:8000
        volumes:
          - ./pyko:/pyko
          - ./pyko/logs:/pyko/logs
        ports:
          - "8000:8000"
        expose:
          - "8000"
        environment:
          - DJANGO_SETTINGS_MODULE=config.settings.prod
    
      nginx:
        build: ./nginx
        restart: always
        image: nginx:1.18.0
        volumes:
          - ./pyko/static:/pyko/static
          - ./pyko/media:/pyko/media
        ports:
          - "80:80"
        depends_on:
          - pyko

    4) 서버에 가져오기

    • 위에서 언급한 것 과 같이 1번방법으로 진행하였습니다.
    • 프로젝트 진입
    cd ~/projects/django
    • 소스코드 가져오기
    git pull
    • 이미지 빌드하기
    sudo docker-compose build
    • 이미지 런하기
    # -d는 백엔드에서 실행한다는 뜻입니다.
    sudo docker-compose up -d 
    • 이미지 실행중인지확인
    sudo docker-compose ps
    • 이미지 내리기
    sudo docker-compose down

    !! 만약 제대로 실행이 되지않는다면

    sudo docker-compose logs

    를 통해 로그를 확인할 수 있고

    sudo docker-compsoe logs '이미지이름'

    을 입력하여 특정 이미지에 대한 로그를 확인할 수 있습니다.

    Reference