Programming/Docker

docker compose를 이용해서 한 번에 서버 구축하기 (2) Django-gunicorn, nginx

stein 2021. 9. 8. 14:29

 

docker compose를 이용해서 한 번에 서버 구축하기 (1) Nuxt.js(※주의! 본 게시글은 필자의 삽질과정이 모두 기록되어 있습니다. 본 시리즈의 앞 부분은 눈으로 흐름만 읽으시고, 코드는 후반 게시글을 참고하시기 바랍니다.)


Django

참고하고있는 포스트: https://testdriven.io/blog/dockerizing-django-with-postgres-gunicorn-and-nginx/#nginx

 

 

  1. 생각
    1. 어차피 django도 requirement.txt로 설치한다
    2. nuxt가 package.json으로 설치되는 것과 동일
    3. 그러면 어제 node 이미지 위에 설치한 것과 같이, python 이미지위에 requirement.txt만 실행시키면 되지 않을까?
    4. docker-compose 내용
django:
  image: python:3.8.12-slim-buster
  volumes:
  - /home/ubuntu/경로:/home/경로
  ports:
  - 8888:8000
  environment:
  - HOST=0.0.0.0
  command: bash -c '
  cd /home/경로/django/
  && pip install -r requirement.txt
  && cd dapada_django
  && python manage.py runserver 0.0.0.0:8000'
    1. django: image: python:3.8.12-slim-buster volumes:
    2. nuxt 내용과 크게 다른 것이 없다.
    3. 성공

gunicorn

gunicorn이 무엇인가?

gunicorn은 WSGI(Web Server Gateway Interface) 서버이다. python이 웹 서버와 통신하기 위해서는 wsgi 규약을 통해 통신하여야 하고, 그 wsgi를 지키는 서버중 하나가 gunicorn이다. (python은 애초에 웹 작업을 하도록 만들어지지 않았기 때문에 js를 사용할 때 보다, 이것저것 달라붙는게 많은 느낌)

 

  1. 이제 gunicorn을 붙이면 된다. 
  2. gunicorn은 별도로 docker를 만드는게 아니라 django와 붙어다닌다. (별도의 서버가 아니다)
    1. [Django는 wsgi 를 위한 module인 wsgi.py를 제공하며, 내부 구현 변경 없이 gunicorn, uwsgi 등 다양한 WSGI 서버를 자유롭게 선택하여 사용할 수 있습니다.](<http://blog.hwahae.co.kr/all/tech/tech-tech/5567/>)
  3. pip로 gunicorn을 설치하고 다음 명령어를 입력해 정상적으로 작동하는지 확인한다.
    gunicorn --bind 0:8000 config.wsgi:application​
  4. 최종적인 docker-compose.yml
    collectstatic은 내부에 있는 정적파일을 모으는 명령어이다. 관련 내용은 검색해보길. (--noinput은 답변을 yes로 처리한다)
    command: bash -c '
    cd /home/경로/django/
    && pip install -r requirement.txt
    && cd 경로
    && python manage.py collectstatic --noinput
    && gunicorn --bind 0.0.0.0:8000 경로.wsgi:application'​

 

 

tip

  1. env에 대해서 고민
    1. node에서 process.env가 실제로 정확히 무엇인가!
      1. process.env는 os의 환경변수를 뜻하는 것이었다. (node에 종속적인게 아니었음)
      2. process.env는 javascript 객체이다(즉 javascript가 os에서 가져오는 형태인듯)
      3. linux kernel에서 env를 입력하면 환경변수들을 확인할 수 있다.
        1. 생성: $ env NAME=VALUE
        2. 삭제: $ env -u NAME
      4. 사용 방법(process.env.이름 으로 바로 접근/수정 가능)
        $ node
        Welcome to Node.js v14.15.0.
        Type ".help" for more information.
        > process.env.API_KEY = "abc"
        'abc'
        > process.env.API_KEY
        'abc'
        > process.env.API_KEY = "def"
        'def'
        > process.env.API_KEY
        'def'
        '1234'
        > delete process.env.API_KEY
        true
        > process.env.API_KEY
        undefined​
      5. https://wayhome25.github.io/django/2017/07/11/django-settings-secret-key/
    2. 그럼 python에서는 어떻게 접근하는데?
      1. os.environ['이름'] 으로 접근가능하다
        # settings.pyimportos
        # 환경변수 INSTA_SECRET_KEY 의 값을 참조한다.
        SECRET_KEY = os.environ["INSTA_SECRET_KEY"]​
      2. https://www.daleseo.com/js-node-process-env/
  2. docker-compose에서 port와 expose의 차이점
    1. https://stackoverflow.com/questions/40801772/what-is-the-difference-between-docker-compose-ports-vs-expose
    2. expose는 현재 버전에서는 더이상 operational 하지 않다고한다. informative 용도로 기술.
  3. nginx upstream이란? 1. 2. nginx uptream중 keepalive에 관한 설명 https://brunch.co.kr/@alden/11
  4. docker-compose에서 build 옵션이 있을 시, 내부 파일이 변경되면 새로 docker-compose build 명령을 주어서 rebuild 해야한다.
  5. docker network라는 것이 존재한다. 내부 호스트들은 bridge라는 driver를 사용해서 통신한다. https://www.daleseo.com/docker-networks/
  6. nginx가 proxy pass를 할 때 upstream server는 [서비스 이름:포트]로 지정하면 된다. 단 이때 포트는 docker port옵션으로 연결한 외부 포트가 아닌, 내부 포트를 적어주어야 한다. (사실상, port 옵션을 쓸 이유가 없어짐). expose로 내부 포트를 적어주긴 하나, 적지 않아도 동작한다.