본문 바로가기
TIL

[Docker] 개발중인 Django Postgresql 프로젝트에 Dockerfile 생성 및 docker-compose 적용하기

by qbinee 2022. 8. 25.
Djnago로 구성된 앱  docker 구성하기
온통 Djnago app 만들면서 한 것 밖에 없어서 쓴 글

프로젝트 구성

1. pipenv를 통해 가상환경에서 로컬을 적용.

2. pipfile, pipfile.lock 을 통하여 환경 관리.

3. postgresql 사용 .

폴더 최상단
ㄴ server
ㄴ ㄴ settings
ㄴ ㄴ ㄴ Dockerfile-dev
ㄴ ㄴ ㄴ .env
ㄴ docker-compose
ㄴ Pipfile
ㄴ Pipfile.lock

 


Dockerfile

프로젝트 소스코드 & 소스코드가 돌아가게 하기 위하여 환경 설정
두가지를 내용을 담은 image 생성을 위한 파일
# syntax=docker/dockerfile:1
FROM python:3.8-slim-buster as base

# install pipenv on the container
RUN pip install --upgrade pip
RUN pip install -U pipenv

RUN apt-get update \
    && apt-get -y install libpq-dev gcc \
    && pip install psycopg2

# sets the working directory
ENV PROJECT_DIR /usr/src/django-docker
WORKDIR ${PROJECT_DIR}

# copy these two files from <src> to <dest>
COPY ../../../Pipfile Pipfile.lock ${PROJECT_DIR}/

# install project dependencies
RUN pipenv install --system --deploy

# copy all files and directories from <src> to <dest>
COPY ../../.. ${PROJECT_DIR}/

# RUN SERVER
# expose the port
EXPOSE 8000

# Command to run
CMD ["python", "user/src/django-docker/manage.py", "runserver", "0.0.0.0:8000"]

1. 파이썬 이미지를 가져온다 ( 나는 psycopg2 설정을 다운을 위해 apt를 써야해서 alpine( 최소 단위 이미지 )를 사용하지 않았다 )

FROM python:3.8-slim-buster as base

2. pip 명령어 pipenv 명령어 사용할 수 있게 다운 ( pipfile , pipfile.lock 실행을 위해 )

RUN pip install --upgrade pip
RUN pip install -U pipenv

3. psycopg2 설정

RUN apt-get update \ && apt-get -y install libpq-dev gcc \ && pip install psycopg2

4. 이미지 내부의 기준 폴더 위치 설정

ENV PROJECT_DIR /usr/src/django-docker
WORKDIR ${PROJECT_DIR}

5. pipenv 명령어를 통해 (2번에서 다운받은 ) 설정 파일 시스템에 적용

COPY ../../../Pipfile Pipfile.lock ${PROJECT_DIR}/

- 여기서 copy {내 소스코드 위치}의 pipfile, pipfile.lock을 

( 나는 dockerfile이  프로젝트 최상단에서 2댑스 들어가기 때문에 ../../../ 설정을 해두었다.)

- 이미지속 위치에 복사한다는 의미

6. 컨테이너 실행시 외부에서 받는 포트번호 정의

EXPOSE 8000

7. 컨테이너 내부에서 실행 ( user/scr/django-docker/은 내가 설정한 workdir)

CMD ["python", "user/src/django-docker/manage.py", "runserver", "0.0.0.0:8000"]

 

하면 설정하기 위한 dockerfile 생성 완료


Docker-Compose 설정

Docker-Compose란 쉽게 말해서 여러개의 컨테이너를 같은 네트워크에서 관리할 수 있게 도와주는것이다.

 

내 프로젝트에서는 Django app 컨테이너  / postgres를 담은 컨테이너  두가지를 동시에 구동시켜야 돌아갈 수 있게 설정해 두었다.

도커를 공부했다면 굉장히 많이 봤을 그림인데

나는 appA appB를 동시에 사용하기 위해서 compose를 사용하는것이라고 봐도 무방하다.

 

나의 로컬 환경에는 DB를 설정하는 파일을 .env파일로 관리하고있다.

dockerfile에서 내 소스코드를 모두 복사해서 가져간것이기 때문에 로컬에서 구동 되는 방향과 동일하게 구성해 두어야 한다.

 

docker-compost.yml

version: "3.9"

services:
  db:
    image: postgres:14.2-alpine
    volumes:
      - ./postgres_data:/var/lib/postgresql/data/
    ports:
      - "5432:5432"
    environment:
      - POSTGRES_DB=projectname
      - POSTGRES_PASSWORD=password
      - POSTGRES_USER=username
    networks:
      - backend
  server:
    build:
      context: .
      dockerfile: server/settings/docker_compose/Dockerfile-dev
    restart: always
    volumes:
      - .:/usr/src/django-docker
    ports:
      - "8000:8000"
    links:
      - db
    depends_on:
      - db
    env_file:
      - server/settings/.env
    command: sh -c "python manage.py migrate && python manage.py runserver 0.0.0.0:8000"
    networks:
      - backend


networks:
  backend:
     driver: bridge

 


DB 설정 파해치기

db 라고 이름 지은 부분에 postgres의 공식 이미지를 가져왔다 

여기서 주의해야할 점은 자신의 소스코드속 host 이름과 docker-compose속 "db" 라는 이름이 다르면 다음과 같은 에러를 만나게 된다.

django.db.utils.OperationalError: could not connect to server: Connection refused Is the server running on host "db" (172.28.0.2) and accepting TCP/IP connections on port 5432?

즉 

소스코드속 HOST: db 가 되어야한다.

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "NAME": ENV("DB_NAME"),
        "USER": ENV("USERNAME"),
        "PASSWORD": ENV("PASSWORD"),
        "HOST": ENV("HOSTNAME"),
        "PORT": ENV("PORT"),
    }
}

 만약 자신이 HOST를 "somthing"이라고 해놨다면 

docker-compose 속 service: db : -> service: somthing: 으로 변경해야한다.

 

image

참고할 이미지이름 , 여기서는 공식 postgresql 의 alpine(최소단위)로 설정

 

volumes

내 로컬 위치 : 이미지에서 가져올 위치

volumes:
  - ./postgres_data:/var/lib/postgresql/data/

내 로컬위치에 postgres_data에 이미지속 var/lib/postgresql/data/ 내용을 Mount 한다는 의미다.

만약 도커를 이용하여 서버 구동하고 데이터 베이스에 어떤 값을 넣는다면 해당 값은 해당 컨테이너 속 ~~data에 저장될 것이다.

이를 로컬 Postgres_data를 통하여 확인할 수 있다.

 

ports

(컨테이너)외부에서 보이는 포트번호 : (컨테이너) 내부에서 쓰이는 포트번호

ports:
  - "5432:5432"

environment

이미지 db의 설정

이는 소스코드에서 찾는 db설정과 동일하게 해줘야한다.

environment:
  - POSTGRES_DB=projectoh
  - POSTGRES_PASSWORD=password
  - POSTGRES_USER=chainlightning

network

두 컨테이너 ( django app, postgresql ) 는 같은 네트워크 위에서 동작해야한다.

그러나 service로 묶어버린것으로도 네트워크가 자동으로 반영되긴하지만, 추후에 다른 컨테이너를 묶을때 사용하기 위해 설정해 두었다.

networks:
  - backend

server 설정

이것도 이름 멋대로 해도 된다.

여기에는 아까 만든 dockerfile을 이용한다.

 

이때 생각해야할게 

파이썬 기준으로 python manage.py runserver 를 하면

db랑 커넥션을 맺은 다음에 허가를 내준다.

 

따라서 DB생성 먼저이다.

 

build

context : 어느 위치에서 dockerfile을 실행시킬 것인가

dockerfile: 소스코드속 도커파일 위치

build:
  context: .
  dockerfile: server/settings/docker_compose/Dockerfile-dev

restart

다시 시작하는 경우

restart: always

volumes

로컬 소스코드 위치: 이미지속 소스코드 위치

volumes:
  - .:/usr/src/django-docker

links

연결할 container name

links:
  - db

depends_on

어떤걸 먼저 하고 실행할 것인가 ( 위에서 설명한대로 db 생성 이후에 server 구동을 한다. )

depends_on:
  - db

env_file

env_file:
  - server/settings/.env

서버에서 사용할 env 파일 위치

 

command

dockerfile 속에 있는 CMD 보다 선행되서 실행되는 명령어

command: sh -c "python manage.py migrate && python manage.py runserver 0.0.0.0:8000"

 

network

네트워크 브릿지를 만들것이다. 

networks:
  backend:
     driver: bridge

- 요부부분은 공부가 더 필요해 보인다

 

 


실행하기

docker-compose up

명령어 입력하면

dockerfile 이미지 빌드하고,, db 이미지도 빌드하고 컨테이너로 만들어서 두 컨테이너가 네트워크로 통신한다.

 

하고나면 debug 모드에서 보이는것처럼 서버 구동이 가능하다.

성공화면