엔진엑스-장고(지유니콘) 도커컴포즈로 배포

hyeok2·2023년 8월 5일
0
post-thumbnail
  • 영화 추천 사이트 프로젝트를 진행하면서 배포를 django, nginx 도커 컴포즈로 진행하려고 하였다.
  • nginx가 생소한 나머지 시간을 너무 많이 소모하였다.
  • 도커 이미지만 몇백개 만들었는 것 같다.
  • 구글링해서 나오는 블로그들의 글은 매우 유익하였지만 내 폴더와는 달랐기에 volume을 할당하는 부분에서 이해가 잘 되지 않는 경우가 많았다.

    사용 환경
    GCP VM 인스턴스 e midium인줄 알았는데 micro로 먼저 만들려고 했나보다.

구조

  • 내 작업폴더 트리이다. (대부분의 블로그에서 구조를 이해하기 어려웠다. 트리로 보여줬으면 더좋았겠다 하는 아쉬움..)
  • 작업을 할 폴더(last)에서 git pull로 장고 프로젝트를 가져왔다.
  • pull 한 폴더의 이름을 수정했다. mv <장고프로젝트 폴더> ./src

Dockerfile

  • 도커파일은 장고프로젝트에 대한 도커파일이다.
  • 파이썬 3.8-알파인을 사용하였고
  • WORKDIR /src/app : 사용할 디렉토리는 src/app
  • COPY requirements.txt . : 필요한 모듈을 requirements.txt로 저장했으니 해당 파일을 복사한다.
  • RUN apk update && \ : apk 패키지 관리자를 업데이트를 하고, 필요한 패키지들을 설치
    --no-cache : 캐시를 남기지 않는 옵션을 추가
    (계속 도커 빌드를 하면서 오류가 났던 패키지들을 하나씩 추가하다보니 꽤 길어졌다.)
    		- postgresql-dev: PostgreSQL 데이터베이스를 사용할 때 필요한 개발 라이브러리
    		- gcc: GNU 컴파일러 컬렉션 중 C 컴파일러
    		- python3-dev: Python 3 개발 헤더 파일 및 라이브러리를 포함
    		- musl-dev: musl C 라이브러리의 개발 파일입니다. 
    		            musl은 리눅스에서 표준 C 라이브러리를 대체하는 것으로 Alpine Linux에 사용
    		- pkgconf: 패키지 구성 및 메타데이터 관리를 위한 도구
    		- mariadb-dev: MariaDB 데이터베이스를 사용할 때 필요한 개발 라이브러리
    		- libffi-dev: 외부 함수 인터페이스 라이브러리의 개발 파일. 
    					  C와 같은 저수준 언어에서 파이썬과 같은 고수준 언어 상에서 사용
    		- bash: GNU Bourne-Again Shell로 흔히 알려진 리눅스 쉘
  • pip install --upgrade pip : pip를 최신 버전으로 업그레이드합니다.
  • pip install -r requirements.txt : requirements.txt에 명시된 파이썬 패키지들을 설치
  • COPY ./src /src/app : 내 로컬의 현재 폴더 하위의 src폴더 내용을 도커 안의 src/app에 복사
  • COPY ./src/static /static : static 정적 파일들을 도커안의 static으로 복사 (사실 두개로 나눌 필요가 없어보이긴 한다)
FROM python:3.8-alpine

ENV PYTHONUNBUFFERED 1

WORKDIR /src/app

COPY requirements.txt .

RUN apk update && \
    apk add --no-cache postgresql-dev gcc python3-dev musl-dev pkgconf mariadb-dev libffi-dev bash && \
    pip install --upgrade pip && \
    pip install -r requirements.txt

COPY ./src /src/app
COPY ./src/static /static
~

nginx.conf

  • nginx는 nginx.conf만으로도 도커 파일을 만들 수 있다고 이해했다.
  • config>nginx>nginx.conf
pshyeok@moochu-gunicorn:~/last/config/nginx$ vim nginx.conf
upstream web {
    ip_hash;
    server web:8000;
}

server {
    listen 80;
    server_name ;

    location / {
        proxy_set_header Host $host:$server_port;
        proxy_pass http://web;
        proxy_redirect off;
    }
location /static/ {
    alias /src/static/;   # static 파일 (도커파일에서 옮기게 설정한 경로를 기입한다)
    expires 30d;
    add_header Cache-Control "public";

    types {
        text/css css;
        text/javascript js;
        image/jpeg jpg jpeg;
        image/png png;
        image/gif gif;
        application/octet-stream map;
        }
       }
       
# 없어도 되는 부분
# 사진이 로딩이 되지 않는 문제가 있어서 이걸 추가했지만, 사진의 이름이 달라 발생한 문제였다.
location /media/{
    alias /src/static/images/;  
        add_header Cache-Control "public";

        types {
            image/jpeg jpg jpeg;
            image/png png;
            image/gif gif;
            audio/mpeg mp3;
            video/mp4 mp4;
            application/octet-stream map;
            }
      }
}

docker-compose.yml

  • nginx는 최신버전을 사용
  • nginx의 도커와 내 로컬이 공유할 부분을 volume에 설정.
  • django 프로젝트는 web으로 정리해놓았다.
  • django 프로젝트를 제작할때는 runserver를 하지만 배포시에는 collectstatic으로 한다는 점.
  • config 하위에 wsgi가 있기에 gunicorn을 gunicorn config.wsgi:application으로 한것.
  • networks 설정으로 도커끼리 내부 통신을 할 수 있게 설정.
version: "3"
services:
  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - "80:80/tcp"
    volumes:
      - ./src:/src
      - ./src/static:/src/static  # 수정된 경로 사용
      - ./src/static/images:/src/static/images
      - /home/pshyeok/last/config/nginx/nginx.conf:/etc/nginx/conf.d/myconfig.conf
    depends_on:
      - web
    networks:
      - custom_network
  web:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: web
    command: >
        bash -c "python manage.py collectstatic --noinput
        && python3 manage.py migrate
        && gunicorn config.wsgi:application --bind 0.0.0.0:8000 --log-level=debug --access-logfile=- --log-file=-"
    volumes:
      - ./src/static:/static # 도커 파일에서 설정한 경로로 설정
    ports:
      - "8000:8000"
    networks:
      - custom_network

networks:
  custom_network:
    driver: bridge

도커컴포즈 실행

  • docker-compose up --build 빌드를 하는 설정으로 실행시킨다.
  • 만약 제대로 설정되지 않아 설정파일을 바꿀때는 docker-compose down -> docker-compose build -> docker-compose up 의 순서대로 실행해주었다.

결과물

  • 8000번 포트로 진입하면 css 파일이 로딩이 되지 않아 다 깨지는 것을 볼 수 있다.
  • 그냥 접속을 해보면 제대로 적용되어 보인다.

소감

  • 시간을 정말 많이 썼다.
  • 많이 입력한 내용
    - 도커 파일 생성 이후 내부 구조를 파악하려고 docker exec -it nginx /bin/bash/
    - docker-compose down docker-compose build docker-compose up docker ps -a docker rm <컨테이너id> docker rmi <도커이미지 이름> docker rmi -f $(docker images -f "dangling=true" -q)

사용하지 않는 도커 이미지 제거하기

참고

profile
땅을 파다보면 흙과 물을 보겠지만, 코드를 파다보면 답이 보일것이다.

1개의 댓글

comment-user-thumbnail
2023년 8월 5일

정보에 감사드립니다.

답글 달기
Powered by GraphCDN, the GraphQL CDN