프로젝트 세팅
1단계
파이참 프로젝트 생성 및 Poetry 초기화
# 파이썬 기본 도구를 사용하여 컴퓨터 전체에서 쓸 수 있도록 최신 버전의 Poetry를 설치합니다.
pip install poetry
# 현재 작업 중인 폴더를 Poetry가 관리하는 프로젝트로 만들기 위해 초기화 명령어를 실행합니다.
# 사용자가 일일이 엔터를 치지 않도록 기본값으로 자동 설정하는 옵션을 덧붙입니다.
poetry init --no-interaction
- Poetry를 초기화하면 프로젝트 폴더 안에 pyproject.toml이라는 명세서 파일이 생성됨
- 과거에는 단순한 텍스트 파일에 도구 이름을 나열했다면
- 이제는 이 명세서 파일 하나로 프로젝트의 이름, 파이썬 버전, 필요한 도구들의 버전을
코드 해석
poetry init --no-interaction
- 새로운 파이썬 프로젝트를 초기화할 때 사용자에게 프로젝트 이름, 버전, 작성자, 의존성 등을 묻는
- 대화형 프롬프트(Interactive prompt)를 모두 건너뛰고
- 시스템의 기본값을 사용하여 pyproject.toml 파일을 즉시 자동 생성하는 기능
poetry init 동작
- 명령어를 입력하면 다음과 같이 사용자의 입력을 기다림
- Package name
[현재_폴더명]:
- Version
[0.1.0]:
- Description
[]:
- Author
[사용자명 <이메일>]:
- (이후 의존성 패키지를 대화형으로 추가할 것인지 지속적으로 물어봄)
--no-interaction 사용 시 동작
- 이 옵션을 추가하면 위의 모든 질문 과정을 생략
- 프로젝트 이름: 현재 명령어를 실행한 디렉터리(폴더)의 이름을 기본값으로 사용
- 버전: 기본값인 0.1.0으로 자동 설정
- 작성자
- 시스템에 설정된 Git 전역 설정(git config user.name, user.email) 정보를 가져와 자동으로 기입함
- 의존성: 아무런 패키지도 추가하지 않고 빈 상태로 생성
2단계
Django 및 품질 검사 도구 설치
poetry add django
poetry add --group dev black
poetry add --group dev ruff
poetry add --group dev mypy
- 개발을 할 때만 필요한 도구(Black, Ruff 등)와 실제 서버를 돌릴 때 필요한 도구(Django)를 분리하여 설치
- 이렇게 하면 나중에 실제 서버에 배포할 때 불필요하게 무거운 개발 도구들을 뺄 수 있어 효율적
- 또한 설치 과정에서
poetry.lock 파일이 생성되는데
- 이는 현재 설치된 모든 도구의 정확한 버전(소수점 끝자리까지)을 자물쇠처럼 잠가두어
- 다른 컴퓨터에서도 완벽히 똑같은 환경을 에러 없이 재현하게 해주는 아주 중요한 파일
코드 해석
- 애플리케이션을 실제 서버에 배포(Production)할 때는
- 웹 프레임워크(예: FastAPI, Django)나 데이터베이스 드라이버 같은
- 메인 의존성(Main dependencies)만 필요함
- 이를 분리하지 않으면 배포 환경이 무거워지고 불필요한 보안 취약점에 노출될 수 있음
--group dev
- 개발(Development) 과정에서만 필요한 'dev' 그룹 의존성으로 분류하여 추가하겠다는 기능
pyproject.toml 파일의 변화
[tool.poetry.dependencies]
python = "^3.10"
fastapi = "^0.100.0"
[tool.poetry.group.dev.dependencies]
ruff = "^0.3.0"
설치 방법
- 로컬 개발 환경에서의 설치
- 프로덕션(배포) 환경에서의 설치
poetry install --without dev
3단계
Django 프로젝트와 앱 생성
- Poetry 환경 안에서 명령어를 실행해야 하므로 명령어 앞에 'poetry run'을 붙여줌
poetry run django-admin startproject config .
poetry run python manage.py startapp myapp
settings.py 등록
DJANGO_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
]
THIRD_PARTY_APPS = [
]
CUSTOM_APPS = [
]
INSTALLED_APPS = (
DJANGO_APPS + THIRD_PARTY_APPS + CUSTOM_APPS
)
4단계
Poetry 환경에 맞춘 Dockerfile 작성
FROM python:3.13-slim
ENV PYTHONUNBUFFERED=1
ENV PYTHONDONTWRITEBYTECODE=1
WORKDIR /app
RUN apt-get update && apt-get install -y \
curl \
libpq-dev \
gcc \
&& rm -rf /var/lib/apt/lists/*
RUN pip install poetry
RUN poetry config virtualenvs.create false
COPY pyproject.toml poetry.lock /app/
RUN poetry install --without dev --no-root --no-interaction --no-ansi
COPY . /app/
5단계
Docker Compose 설정 및 실행
- 웹 서버와 데이터베이스 등 여러 상자를 한 번에 지휘하고 관리하기 위해
- 최상위 폴더에 docker-compose.yml 파일을 만듬
version: '3.8'
services:
web:
build: .
ports:
- "8000:8000"
command: poetry run python manage.py runserver 0.0.0.0:8000
volumes:
- .:/app
포트 포워딩과 볼륨 동기화
- 컨테이너는 기본적으로 외부와 철저히 단절된 방
- 포트 포워딩(ports)은 이 방에 창문을 뚫어 내 컴퓨터의 브라우저에서 방 안의
- Django 서버로 접속할 수 있게 해주는 개념
- 볼륨(volumes)은 내 컴퓨터의 폴더와 방 안의 폴더를 연결하는 비밀 통로
- 이 통로 덕분에 코드를 한 줄 고칠 때마다 무거운 도커 상자를 부수고 다시 만들 필요 없이
- 저장 즉시 수정 사항이 서버 화면에 반영됨
6단계
자동화 검사 파이프라인 구성
- 마지막으로 코드를 깃허브에 올릴 때마다 봇이 대신 오류를 검사해 주도록 설정하기
- 최상위 폴더에
.github 폴더를 만들고
- 그 안에
workflows 폴더를 만든 뒤, checks.yml 파일을 생성
name: Code Quality Checks & Tests
on:
pull_request:
branches:
- "main"
- "develop"
env:
AWS_ACCESS_KEY_ID: "dummy"
AWS_SECRET_ACCESS_KEY: "dummy"
AWS_STORAGE_BUCKET_NAME: "dummy"
DJANGO_SETTINGS_MODULE: "config.settings"
jobs:
ci:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.12"
- name: Install Poetry
run: |
curl -sSL https://install.python-poetry.org | python3 -
echo "${HOME}/.local/bin" >> $GITHUB_PATH
- name: Cache Poetry dependencies
id: cache-venv
uses: actions/cache@v3
with:
path: ~/.cache/pypoetry/virtualenvs
key: python-3.12-poetry-${{ hashFiles('**/poetry.lock') }}
restore-keys: |
python-3.12-poetry-
- name: Install dependencies
if: steps.cache-venv.outputs.cache-hit != 'true'
run: poetry install --no-root
- name: Create .env file
run: |
echo "${{ secrets.DJANGO_ENVS }}" > .env
- name: Run Ruff (Lint & Import Sorting)
run: poetry run ruff check .
- name: Run Black (Code Formatting)
run: poetry run black . --check
- name: Run Mypy (Type Checking)
run: poetry run mypy .
test:
needs: ci
runs-on: ubuntu-latest
services:
db:
image: postgres:15
ports: ["5432:5432"]
env:
POSTGRES_USER: blog_user
POSTGRES_PASSWORD: blog_password
POSTGRES_DB: blog_db_dev
options: >-
--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
redis:
image: redis:latest
ports: ["6379:6379"]
options: >-
--health-cmd "redis-cli ping" --health-interval 5s --health-timeout 3s --health-retries 5
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.12"
- name: Install Poetry
run: |
curl -sSL https://install.python-poetry.org | python3 -
echo "${HOME}/.local/bin" >> $GITHUB_PATH
- name: Cache Poetry dependencies
uses: actions/cache@v3
with:
path: ~/.cache/pypoetry/virtualenvs
key: python-3.12-poetry-${{ hashFiles('**/poetry.lock') }}
- name: Install dependencies
run: poetry install --no-root
- name: Create .env file
run: echo "${{ secrets.DJANGO_ENVS }}" > .env
- name: Run Django Migration
run: poetry run python manage.py migrate
- name: Run Tests & Coverage
run: |
poetry run coverage run --source='.' manage.py test
echo "Total Coverage Report:"
poetry run coverage report -m
최종 실행
docker-compose up --build