# Django 기반 웹 어플리케이션 컨테이너환경 구축

안규원·2024년 9월 6일
0

Infra

목록 보기
20/23

3-tier


어플리케이션 아키텍처: 애플리케이션을 설계/구축하는데 사용하는 패턴과 기술

Web/Business/Data tier

Sample


단순한 Django WAS서버 구동

$ git clone https://github.com/go4real/Django-Poll-App.git

$ sudo apt install -y python3-pip

# 가상환경 진입후 실행
$ pip3 install -r requirements.txt

$ pip3 install setuptools

# db 스키마 구성
$ python3 manage.py migrate

# 관리자계정 생성(fast/fast)
$ python3 manage.py createsuperuser

# Dummy data 생성
$ pip3 install faker

# python환경 진입
$ python3 manage.py shell
>>> import seeder
>>> seeder.seed_all(30)
>>> exit()

# 로컬서버 구동/ 원격 접속하기위해 0.0.0.0:8000
# settings.py 파일에 IP주소 추가
$ python3 manage.py runserver 0.0.0.0:8000

DB서버 구성


db 볼륨 생성

https://docs.docker.com/engine/install/linux-postinstall/

# manage docker as a non-root user
$ sudo groupadd docker
$ sudo usermod -aG docker $USER
$ newgrp docker

# 볼륨 생성
$ docker volume create poll-db-volume
poll-db-volume

# 볼륨 확인
$ docker volume ls
DRIVER    VOLUME NAME
local     poll-db-volume

# mountpoint 확인
$ docker volume inspect poll-db-volume
[
    {
        "CreatedAt": "2024-09-06T00:39:12Z",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/poll-db-volume/_data",
        "Name": "poll-db-volume",
        "Options": null,
        "Scope": "local"
    }
]

# run postgreSQL db container
$ docker run -p 5432:5432 --rm --name poll_db \
-v poll-db-volume:/var/lib/postgresql/data \
-e POSTGRES_PASSWORD=1234qwer \
-e POSTGRES_USER=fast \
-e POSTGRES_DB=poll \
-d postgres

# docker ps
CONTAINER ID   IMAGE      COMMAND                  CREATED              STATUS              PORTS                                       NAMES
4bfe4590a9ed   postgres   "docker-entrypoint.s…"   About a minute ago   Up About a minute   0.0.0.0:5432->5432/tcp, :::5432->5432/tcp   poll_db

# postgreSQL client 설치
$ sudo apt install -y postgresql-client

# 접속
$ psql -h 127.0.0.1 -U fast -d poll

# Django 프로젝트가 postgre 컨테이너를 보도록 settings.py 수정
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'poll',
        'USER': 'fast',
        'PASSWORD': '1234qwer',
        'HOST': '127.0.0.1',
        'PORT': '5432',
    }
}

# postgreSQL client 설치하기 위해 requirements.txt 수정
psycopg2==2.9.3
$ pip3 install -r requirements.txt

# native하게 OS 종속성 필요한 패키지 설치
$ sudo apt install -y libpq-dev python3-dev

# db 스키마 생성
$ python3 manage.py migrate

# admin 재생성
$ python3 manage.py createsuperuser

# dummy data 생성
$ python3 manage.py shell
>>> import seeder
>>> seeder.seed_all(30)
>>> exit()

# 로컬서버 구동
$ python3 manage.py runserver

# pSQL 데이터 확인
$ psql -h 127.0.0.1 -U fast -d poll

# 테이블 목록 확인
$ \dt
$ select * from polls_poll;
# 터미널 접속 종료
$ \q

App서버 구성


Dockerfile 작성

FROM python:3.8-slim-buster

ENV PYTHONUNBUFFERED 1
ENV PYTHONDONTWRITEBYTECODE 1

RUN apt-get update \
  && apt-get install -y gcc libpq-dev python-dev \
  && rm -rf /var/lib/apt/lists/*

WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install -r requirements.txt
COPY . .

EXPOSE 8000
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

이미지 빌드

$ docker build --tag poll_app .

# db서버는 별도로 작동하므로 rm옵션
$ docker run --rm --name poll_container poll_app

# 연결 실패. 컨테이너끼리 바라볼 수 없음
"""
django.db.utils.OperationalError: could not connect to server: Connection refused
        Is the server running on host "127.0.0.1" and accepting
        TCP/IP connections on port 5432?
"""

# IP주소 확인
$ ip addr

# 하나 가져와서 settings.py 호스트정보 수정
DATABASES = {
"""
        'HOST': '{local IP}',
"""
}

# docker image 재빌드
$ docker build --tag poll_app .

# 이미지 재실행
$ docker run --rm --name poll_container poll_app

# 컨테이너 구동되었으나 접속 실패

# 포트 확인
$ sudo ss -tulpn

# 호스트의 8000번 포트가 not expose
$ docker ps
$ docker run -p 8000:8000 --rm --name poll_container poll_app

# 접속 확인

Web서버 구성


app서버에 gunicorn 적용

# requirement.txt
gunicorn==20.1.0

# Dockerfile
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "3", "pollme.wsgi:application"]

# 재빌드
$ docker build --tag poll_app .

# 구동
$ docker run -p 8000:8000 --rm --name poll_container poll_app

# detach 모드로 구동
$ docker run -d -p 8000:8000 --rm --name poll_container poll_app

web서버에 nginx 적용

$ mkdir nginx/config && cd nginx

# private ip 지정
$ vim config/nginx.conf
location / {
	proxy_pass         http://{local private IP}:8000;  
	proxy_set_header   Host $host;
}

# web server Dockerfile
$ vi Dockerfile

# 빌드
$ docker build --tag poll_web -f nginx/Dockerfile .

$ docker run --rm -p 80:80 --name poll_container poll_web

docker-compose


하나의 YAML파일로 서비스 구성

https://docs.docker.com/compose/install/

# docker compose 설치
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
$ sudo curl \
    -L https://raw.githubusercontent.com/docker/compose/1.29.2/contrib/completion/bash/docker-compose \
    -o /etc/bash_completion.d/docker-compose
$ source ~/.bashrc

# 확인
$ docker-compose --version
docker-compose version 1.29.2, build 5becea4c

# settings.py 환경변수 설정
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': os.environ.get('POSTGRES_DB'),
        'USER': os.environ.get('POSTGRES_USER'),
        'PASSWORD': os.environ.get('POSTGRES_PASSWORD'),
        'HOST': os.environ.get('POSTGRES_HOST'),
        'PORT': '5432',
    }
}

# 빌드
docker build --tag poll_app .

# docker-compose.yml 작성
$ vi docker-compose.yml

# 구동
$ docker-compose up

# private ip 지정을 다시 app으로
$ vim config/nginx.conf
location / {
	proxy_pass         http://app:8000; 
	proxy_set_header   Host $host;
}

# nginx 이미지 재빌드
$ docker build --tag poll_web -f nginx/Dockerfile .

# 기존 컨테이너 정리 후 재기동
$ docker-compose down
$ docker-compose up

# 확인
$ docker-compose ps

debugging환경 구성


remote host/App Server에 디버깅 개발환경 구축

  • 스케일 업 위해 ec2 t2.micro -> t2.small 인스턴스 유형 변경

이 과정에서 드디어 탄력적 IP 할당. 그냥 돈을 내는게 낫다.

  • docker/python plugin 설치(VS Code)
# 디버그 docker compose 작성
$ vi docker-compose.debug.yml

# .vscode 하위에 launch.json 파일 작성

# 실행
$ docker-compose -f docker-compose.debug.yml up -d --build

# debug 탭 클릭후 실행

# views.py 파일에서 breakpoint 설정

0개의 댓글