2026/04/01 Promise - 2

김기훈·2026년 4월 1일

TIL

목록 보기
181/194
post-thumbnail

프로젝트 세팅


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 및 품질 검사 도구 설치

# 실제 서비스 운영에 반드시 필요한 핵심 프레임워크인 Django를 패키지 목록에 추가하고 설치합니다.
poetry add django

# 띄어쓰기와 줄바꿈을 자동으로 맞춰주는 포맷터 도구인 Black을 개발 전용 그룹에 추가합니다.
poetry add --group dev black

# 불필요한 코드나 문법 오류를 빠르게 찾아주는 린터 도구인 Ruff를 개발 전용 그룹에 추가합니다.
poetry add --group dev ruff

# 변수나 함수의 자료형이 올바른지 정밀하게 검사해 주는 타입 체커인 Mypy를 개발 전용 그룹에 추가합니다.
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"

# [dev 그룹 의존성] - --group dev 옵션으로 추가된 개발용 패키지
[tool.poetry.group.dev.dependencies]
ruff = "^0.3.0"  # ruff가 여기에 추가됩니다.

설치 방법

  • 로컬 개발 환경에서의 설치
    • poetry install
  • 프로덕션(배포) 환경에서의 설치
    • poetry install --without dev

3단계


Django 프로젝트와 앱 생성

  • Poetry 환경 안에서 명령어를 실행해야 하므로 명령어 앞에 'poetry run'을 붙여줌
# Poetry의 가상환경 안에서 django-admin 도구를 꺼내 'config'라는 뼈대(프로젝트)를 현재 폴더(.)에 생성합니다.
poetry run django-admin startproject config .

# 프로젝트 통제 스크립트인 manage.py를 실행하여 'myapp'이라는 새로운 기능(앱) 폴더를 생성합니다.
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 작성

# 파이썬 3.13 버전의 가벼운(slim) 운영체제를 기본 바탕으로 가져옵니다. 
FROM python:3.13-slim

# 파이썬 출력을 버퍼링하지 않고 콘솔에 즉시 출력하도록 설정하여 로그 확인을 쉽게 합니다.
ENV PYTHONUNBUFFERED=1

# 파이썬이 불필요한 바이트코드(.pyc) 파일을 생성하지 않도록 강제하여 컨테이너 용량을 아낍니다.
ENV PYTHONDONTWRITEBYTECODE=1

# 컨테이너 내부에서 작업이 이루어질 기본 디렉토리를 /app으로 지정합니다.
WORKDIR /app

# 운영체제 패키지 목록을 업데이트하고 데이터베이스 연결 등에 필요한 필수 시스템 패키지들을 설치합니다.
RUN apt-get update && apt-get install -y \
    # 인터넷에서 데이터를 다운로드하기 위한 도구입니다.
    curl \
    # 포스트그레SQL 데이터베이스와 파이썬을 연결할 때 필요한 핵심 라이브러리입니다.
    libpq-dev \
    # C 언어로 작성된 파이썬 패키지를 설치할 때 필요한 컴파일러입니다.
    gcc \
    # 설치가 끝난 후 불필요해진 임시 파일(캐시)을 삭제하여 도커 이미지 크기를 대폭 줄입니다.
    && rm -rf /var/lib/apt/lists/*

# 파이썬 기본 패키지 관리자를 사용하여 Poetry를 전역으로 깔끔하게 설치합니다.
RUN pip install poetry

# 도커 자체가 이미 격리된 공간이므로, Poetry가 내부에 또 가상환경을 만들지 않도록 설정을 끕니다.
RUN poetry config virtualenvs.create false

# 패키지 명세서와 자물쇠 파일을 소스 코드보다 먼저 복사하여 도커의 캐시 기능을 최대한 활용합니다.
COPY pyproject.toml poetry.lock /app/

# 명세서를 읽어 의존성 패키지들을 설치하되, 개발용 도구를 제외하고 사용자 묻기 및 색상 출력을 무시합니다.
RUN poetry install --without dev --no-root --no-interaction --no-ansi

# 나머지 모든 프로젝트 소스 코드를 도커 컨테이너 내부의 /app 디렉토리로 마저 복사합니다.
COPY . /app/

5단계

Docker Compose 설정 및 실행

  • 웹 서버와 데이터베이스 등 여러 상자를 한 번에 지휘하고 관리하기 위해
    • 최상위 폴더에 docker-compose.yml 파일을 만듬
# Docker Compose 파일의 문법 버전을 3.8로 사용하겠다고 선언합니다.
version: '3.8'

# 우리가 띄워서 관리할 서비스(컨테이너 상자)들의 목록을 정의하는 구역입니다.
services:
  # 'web'이라는 이름표를 단 서비스를 정의하며, 이것이 우리의 Django 웹 서버가 됩니다.
  web:
    # 현재 폴더(.)에 있는 Dockerfile을 읽어들여서 컨테이너 이미지를 직접 조립하라고 지시합니다.
    build: .
    # 내 컴퓨터의 포트와 컨테이너 내부의 포트를 서로 연결해 줍니다.
    ports:
      # 앞의 8000은 내 컴퓨터(호스트)의 주소이고, 뒤의 8000은 컨테이너 내부의 주소를 의미합니다.
      - "8000:8000"
    # 컨테이너가 켜질 때 최종적으로 실행할 명령어를 지정하여 Django 개발용 서버를 작동시킵니다.
    command: poetry run python manage.py runserver 0.0.0.0:8000
    # 내 컴퓨터의 코드를 수정했을 때 컨테이너 내부에도 즉시 반영되도록 폴더를 연결합니다.
    volumes:
      # 내 컴퓨터의 현재 폴더(.)와 컨테이너 내부의 /app 폴더를 거울처럼 실시간으로 동기화합니다.
      - .:/app

포트 포워딩과 볼륨 동기화

  • 컨테이너는 기본적으로 외부와 철저히 단절된 방
    • 포트 포워딩(ports)은 이 방에 창문을 뚫어 내 컴퓨터의 브라우저에서 방 안의
      • Django 서버로 접속할 수 있게 해주는 개념
    • 볼륨(volumes)은 내 컴퓨터의 폴더와 방 안의 폴더를 연결하는 비밀 통로
      • 이 통로 덕분에 코드를 한 줄 고칠 때마다 무거운 도커 상자를 부수고 다시 만들 필요 없이
      • 저장 즉시 수정 사항이 서버 화면에 반영됨

6단계

자동화 검사 파이프라인 구성

  • 마지막으로 코드를 깃허브에 올릴 때마다 봇이 대신 오류를 검사해 주도록 설정하기
    • 최상위 폴더에 .github 폴더를 만들고
    • 그 안에 workflows 폴더를 만든 뒤, checks.yml 파일을 생성
# 깃허브 액션 탭에서 이 자동화 작업이 어떤 이름으로 보일지 결정합니다.
name: Code Quality Checks & Tests

# 이 자동화 스크립트가 언제 스스로 작동해야 하는지 조건을 설정하는 구역입니다.
on:
  # 누군가 자신이 짠 코드를 메인 코드에 합쳐달라고 요청(PR)을 올렸을 때 발동하게 합니다.
  pull_request:
    # 모든 요청이 아니라, 아래 지정된 중요한 브랜치로 들어올 때만 작동하게 제한합니다.
    branches:
      # 실제 서비스로 배포되는 main 브랜치로 향하는 요청일 때 검사를 수행합니다.
      - "main"
      # 개발 테스트용인 develop 브랜치로 향하는 요청일 때 검사를 수행합니다.
      - "develop"

# 아래에 정의될 모든 작업 단계에서 공통으로 쓰일 전역 환경 변수를 선언합니다.
env:
  # 봇이 검사를 수행할 때 에러가 나지 않도록 가짜 아마존 접속 키를 부여합니다.
  AWS_ACCESS_KEY_ID: "dummy"
  # 봇이 사용할 가짜 비밀 키를 부여하여 코드가 도중에 멈추지 않게 방지합니다.
  AWS_SECRET_ACCESS_KEY: "dummy"
  # 봇이 참고할 가짜 클라우드 저장소 이름을 지정해 줍니다.
  AWS_STORAGE_BUCKET_NAME: "dummy"
  # 장고 프레임워크가 무조건 우리의 설정 파일(config.settings)을 바라보고 켜지도록 강제합니다.
  DJANGO_SETTINGS_MODULE: "config.settings"

# 조건이 만족되었을 때 깃허브 서버(가상 머신)가 순서대로 수행할 작업들의 목록입니다.
jobs:
  # 코드 스타일과 문법을 검사하는 첫 번째 작업 그룹의 이름을 'ci'로 명명합니다.
  ci:
    # 이 작업 그룹을 깃허브가 제공하는 가장 최신 버전의 우분투 리눅스 컴퓨터에서 실행합니다.
    runs-on: ubuntu-latest
    # 'ci' 작업 그룹 안에서 하나씩 차례대로 실행될 구체적인 행동(단계)들입니다.
    steps:
      # 깃허브 저장소에 올라와 있는 우리 프로젝트 코드를 가상 머신 안으로 다운로드받습니다.
      - name: Checkout code
        # 깃허브 공식 코드 다운로드 프로그램(액션) v3 버전을 가져다 씁니다.
        uses: actions/checkout@v3

      # 우리가 코드를 짤 때 썼던 것과 똑같은 파이썬 환경을 가상 머신에 세팅합니다.
      - name: Set up Python
        # 깃허브 공식 파이썬 설치 프로그램 v4 버전을 사용합니다.
        uses: actions/setup-python@v4
        # 파이썬 버전을 우리가 사용하는 3.12로 정확하게 지정해 줍니다.
        with:
          python-version: "3.12"

      # 봇 컴퓨터에 의존성 관리 도구인 Poetry를 설치하는 단계입니다.
      - name: Install Poetry
        # 공식 웹사이트에서 설치 파일을 받아 실행하고, 시스템 경로에 등록하여 봇이 명령어를 알아듣게 합니다.
        run: |
          curl -sSL https://install.python-poetry.org | python3 -
          echo "${HOME}/.local/bin" >> $GITHUB_PATH

      # 매번 패키지를 다운받으면 오래 걸리므로 기존 설치본을 기억해두는 캐시 단계입니다.
      - name: Cache Poetry dependencies
        # 다른 단계에서 이 결과를 물어볼 수 있도록 'cache-venv'라는 이름표를 붙여줍니다.
        id: cache-venv
        # 깃허브 공식 캐시 저장 프로그램 v3 버전을 사용합니다.
        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

      # 데이터베이스 비밀번호 등이 담겨야 할 임시 환경 변수 파일(.env)을 봇 컴퓨터에 만들어줍니다.
      - name: Create .env file
        # 깃허브 보안 저장소에 숨겨둔 텍스트를 가져와서 .env 파일 안에 쏟아붓습니다.
        run: |
          echo "${{ secrets.DJANGO_ENVS }}" > .env

      # 불필요한 코드나 파이썬 문법 오류가 없는지 빠르게 검사하는 단계입니다.
      - name: Run Ruff (Lint & Import Sorting)
        # 가상환경 안에서 ruff를 실행하여 프로젝트 전체를 매서운 눈으로 검사하게 합니다.
        run: poetry run ruff check .

      # 개발자마다 다른 띄어쓰기나 줄바꿈 스타일이 규칙에 맞는지 확인하는 단계입니다.
      - name: Run Black (Code Formatting)
        # 코드를 실제로 고치지는 말고(--check), 규칙을 어긴 곳이 있으면 에러를 내서 알려주게 합니다.
        run: poetry run black . --check

      # 변수나 함수에 엉뚱한 종류의 데이터가 들어가지 않는지 정밀하게 자료형을 검사합니다.
      - name: Run Mypy (Type Checking)
        # mypy를 켜고 프로젝트 전체 코드를 꼼꼼히 분석하도록 지시합니다.
        run: poetry run mypy .

  # 문법 검사가 끝난 뒤, 우리가 짠 코드가 잘 동작하는지 가짜 데이터로 시뮬레이션 하는 두 번째 작업 그룹입니다.
  test:
    # 앞선 'ci' 작업이 성공적으로 에러 없이 끝났을 때만 이 테스트 작업을 시작하도록 조건을 겁니다.
    needs: ci
    # 이 작업 역시 가장 최신 버전의 우분투 리눅스 컴퓨터를 새로 빌려서 실행합니다.
    runs-on: ubuntu-latest
    # 테스트 코드를 돌릴 때 백그라운드에서 켜져 있어야 하는 보조 프로그램(DB 등)들을 띄워줍니다.
    services:
      # 'db'라는 이름으로 포스트그레SQL 데이터베이스 15 버전 보조 컨테이너를 켭니다.
      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'라는 이름의 최신 버전 캐시 서버 컨테이너도 켭니다.
      redis:
        image: redis:latest
        ports: ["6379:6379"]
        options: >-
          --health-cmd "redis-cli ping" --health-interval 5s --health-timeout 3s --health-retries 5

    # 'test' 작업 그룹 내에서 순서대로 진행될 코드 다운로드 및 테스트 실행 과정입니다.
    steps:
      # 새로운 봇 컴퓨터를 배정받았으므로 다시 한번 프로젝트 코드를 다운로드합니다.
      - name: Checkout code
        uses: actions/checkout@v3

      # 새로운 봇 컴퓨터에 동일하게 파이썬 3.12를 세팅해 줍니다.
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: "3.12"

      # 의존성 관리 도구인 Poetry를 한 번 더 설치하고 시스템 경로에 등록합니다.
      - name: Install Poetry
        run: |
          curl -sSL https://install.python-poetry.org | python3 -
          echo "${HOME}/.local/bin" >> $GITHUB_PATH

      # 앞선 'ci' 작업에서 만들어둔 캐시가 있다면 이 단계에서 쏙 빼와서 설치 시간을 대폭 줄입니다.
      - 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
        # 장고의 마이그레이션 명령어를 실행하여 DB 스키마를 동기화합니다.
        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

profile
안녕하세요.

0개의 댓글