어플리케이션 아키텍처: 애플리케이션을 설계/구축하는데 사용하는 패턴과 기술
Web/Business/Data tier
단순한 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 볼륨 생성
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
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
# 접속 확인
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
하나의 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
remote host/App Server에 디버깅 개발환경 구축
이 과정에서 드디어 탄력적 IP 할당. 그냥 돈을 내는게 낫다.
# 디버그 docker compose 작성
$ vi docker-compose.debug.yml
# .vscode 하위에 launch.json 파일 작성
# 실행
$ docker-compose -f docker-compose.debug.yml up -d --build
# debug 탭 클릭후 실행
# views.py 파일에서 breakpoint 설정