Docker-compose & Django & Postgresql

do yeon kim·2022년 8월 22일
0

Docker-compose & Django & Postgresql

유저의 입력이 들어올 경우 데이터베이스에 유저 정보를 저장하는 API를 구현해보자!!
✅ Python의 Djnago를 이용한 API작성
✅ Postgresql 데이터베이스를 활용한 DB data 저장



docker-compose

Docker-compose란 여러 컨테이너를 일괄적으로 정의하고 실행 하고 관리 할 수 있는 툴이다.

다시 말해, 컨테이너들 간의 관계를 만들거나, 선행적으로 필요로 하는 여러 컨테이너들을 하나로 합쳐서 한번에 관리 할 수 있는 방법이다.



dockerfile 생성

dockerfile
Dockerfile은 Container Image를 만들기 위한 파일이다.

mkdir docker_compose
cd docker_compose
vim dockerfile
# syntax=docker/dockerfile:1
FROM python:3
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
WORKDIR /code
COPY requirements.txt /code/
RUN pip install -r requirements.txt
COPY . /code/

FROM
컨테이너의 기반이 되는 환경을 설정해준다.
이번 API에서는 python을 사용하므로 기반이미지는 python이 된다.

ENV
환경변수를 의미한다.
python에 필요한 환경변수를 설정해준다.
docker.hub.com 홈페이지의 내용을 그대로 가지고 왔다.

WORKDIR
앞으로 작업하는 내용의 작업 디렉토리를 설정한다.

COPY
해당파일이나 데이터를 지정한 디렉토리에 복사하는 과정이다.

RUN
컨테이너 이미지를 만들기 위한 필요 환경을 설치하는 과정이다.



requirements.txt 작성

requirements.txt
dockerfile을 실행시 필요로 하는 requirements.txt작성하는 과정이다.

python에서 사용하는 라이브러리 django와 psycopg2를 설치한다.
(psycopg는 Python 프로그래밍 언어용으로 가장 널리 사용되는 PostgreSQL 데이터베이스 어댑터이다.)

vim requirements.txt

Django>=3.0,<4.0
psycopg2>=2.8


docker-compose.yml 작성

docker-compose.yml
docker-compose를 실행하기 위한 약속된 파일 형태이다.
.yml file에 docker-compose로 실행될 요소들을 작성해준다.

version: "3.9"
   
services:
  db:
    image: postgres
    volumes:
      - ./data/db:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    environment:
      - POSTGRES_NAME=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
    depends_on:
      - db

version
docker-compose의 버전을 의미한다.

services
docker-compose에 속하는 컨테이너들을 의미한다.
위의 코드에서는 db라는 이름의 컨테이너 하나, web이라는 컨테이너 하나 총 두개의 컨테이너가 만들어지는 것이다.



yml파일 상세보기 (1)

►docker-compose.yml파일 (이름이 db인 첫번째 컨테이너)

db:
    image: postgres
    volumes:
      - ./data/db:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres

►일반 docker run 명령어

docker run -d --name db 
-v ./data/db : /var/lib/postgresql/data 
-e POSTGRES_DB=postgres POSTGRES_USER=postgres  POSTGRES_PASSWORD=postgres postgres

volumes는 volume mount하는 것으로 해당 데이터베이스의 /var/lib/postgresql/data 저장되는 데이터를 ./data/db에 영구적으로 저장하기 위해서 작성된 코드이다.



yml파일 상세보기 (2)

►docker-compose.yml파일 (이름이 web인 두번째 컨테이너)


web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    environment:
      - POSTGRES_NAME=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
    depends_on:
      - db

build
해당 디렉토리를 기준으로 dockerfile 컨테이너 이미지로 만드는 과정이다.
만들어진 컨테이너 이미지를 이용해서 web이라는 이름의 컨테이너를 생성하는 것이다.

volumes
해당 컨테이너의 파일들을 /code에 영구적으로 저장한다는 의미이다.(volume mount)

ports
해당 컨테이너가 외부 네트워크를 실행 시 해당하는 포트를 알려준다.
앞의 8000은 docker host의 포트 뒤의 8000은 컨테이너의 포터번호에 해당한다.

environment
환경변수를 의미한다.

depends_on
해당 컨테이너가 첫번째 컨테이너인 db에 의존적이라는 의미이다. 그렇기 때문에 db가 먼저 생성 후 두번째 컨테이너인 web이 생성된다.



►일반 docker run 명령어

docker build -t 이미지이름은 없음 .
docker run --name web -v .:/code -p 8000:8000 
-e POSTGRES_NAME=postgres POSTGRES_USER=postgres POSTGRES_PASSWORD=postgres 이미지이름은 없음

이렇게 따로 작성된 경우라면 command는 dockerfile에 추가 될 것이다.(추측)
환경변수 역시 따로 작성될 수 있을 것이다.(추측)


Django프로젝트 만들기
sudo docker-compose run web django-admin startproject composeexample .

docker-compose의 web 컨테이너를 실행해준다.
그리고 실행하면서 새로운 프로젝트를 만들어 준다.



users 앱 생성

python manage.py startapp users
python manage.py startapp core

데이터 베이스를 연결하기 전에 앱을 만들고, API작성을 하도록 하자.

▻users 모델 작성

from django.db import models
from ipaddress import ip_address

class User(models.Model):
    name        = models.CharField(max_length=20)
    email       = models.CharField(max_length=50, unique=True)
    age         = models.IntegerField()
    ip_address  = models.GenericIPAddressField(null=True)
    created_at  = models.DateTimeField(auto_now_add = True)

▻users views작성

import json

from django.http    import JsonResponse
from django.views   import View

from users.models   import User

class UserView(View):
    def post(self, request):
        try:
            data            = json.loads(request.body)
            name            = data["name"]
            age             = data["age"]
            email           = data["email"]
            x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')


            if x_forwarded_for:
                ip_address = x_forwarded_for.split(',')[-1].strip()
            else:
                ip_address = request.META.get('REMOTE_ADDR')

            user, is_true = User.objects.get_or_create(
                        name = name,  
                        age = age, 
                        email = email,
                        defaults={
                            "ip_address": ip_address
                        })

            if not is_true:
                user.ip = ip_address
                user.save()
            
            return JsonResponse({"result":"success"}, status = 200)
        
        except KeyError:
            return JsonResponse({"result":"key_error"}, status = 400)        


Djnago 와 Postgresql 연결

django 프로젝트 settings.py에서 데이터베이스에 대한 설정을 변경해준다.


# settings.py
   
import os
   
[...]

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': os.environ.get('POSTGRES_NAME'),
        'USER': os.environ.get('POSTGRES_USER'),
        'PASSWORD': os.environ.get('POSTGRES_PASSWORD'),
        'HOST': 'db',
        'PORT': 5432,
    }
}


docker-compose up

docker-compose.yml 파일을 실행시킨다.

docker-compose up 실행

docker-compose up -d 백그라운드로 실행

docker exec -it python컨테이너명 /bin/bash
python manage.py makemigrations
python manage.py migrate

docker exec -it db컨테이너명 /bin/bash
psql -U postgres postgres

데이터 확인



docker-compose down

생성된 docker-compose 삭제




https://docs.docker.com/samples/django/

https://velog.io/@miracle-21/DOCKERDjango-migration-postgreSQL

0개의 댓글