본문 바로가기
컴퓨터과학과

Django + MySQL + Docker에서 첫 앱 만들기(완전 가이드)

by 공부하는노년 2025. 8. 25.
반응형

 

Django + MySQL + Docker에서 첫 앱 만들기(완전 가이드)

0) 전제

  • docker-compose up -d로 web / nginx / db 컨테이너가 동작 중입니다.
  • http://127.0.0.1:8000/admin 로그인까지 확인하셨습니다.

1) 앱 생성

# 프로젝트 루트( docker-compose.yml 이 있는 위치 )에서
docker-compose exec web python manage.py startapp blog
  • 새 디렉터리 app/blog/가 생깁니다.
  • 에러 없이 끝나면 다음 단계로 진행합니다.

2) 모델 작성

app/blog/models.py에 간단한 글(Post) 모델을 정의합니다.

from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ["-created_at"]

    def __str__(self):
        return self.title

포인트

  • ordering으로 최신 글이 먼저 보이도록 했습니다.

3) 앱 등록

app/config/settings.py(또는 app/config/settings/base.py 구조라면 해당 파일)에 INSTALLED_APPS에 blog를 추가합니다.

INSTALLED_APPS = [
    # Django 기본 앱들 …
    "blog",
]
  • 저장 후 다음 단계로 진행합니다.

4) 마이그레이션 반영

docker-compose exec web python manage.py makemigrations
docker-compose exec web python manage.py migrate
  • 두 명령 모두 오류 없이 완료되어야 합니다.
  • 이제 MySQL에 blog_post 테이블이 생성됩니다.

5) 관리자(admin) 등록

app/blog/admin.py에 등록 코드를 추가합니다.

from django.contrib import admin
from .models import Post

@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
    list_display = ("id", "title", "created_at")
    search_fields = ("title", "content")
    list_filter = ("created_at",)

이후 브라우저에서 http://127.0.0.1:8000/admin → Posts 메뉴가 보이면 성공입니다. 여기서 테스트용 글을 2~3개 등록해 두면 다음 단계에서 바로 목록이 출력됩니다.


6) URL과 뷰 작성(목록/상세)

6-1) blog/views.py

from django.shortcuts import get_object_or_404, render
from .models import Post

def post_list(request):
    posts = Post.objects.all()
    return render(request, "blog/post_list.html", {"posts": posts})

def post_detail(request, pk):
    post = get_object_or_404(Post, pk=pk)
    return render(request, "blog/post_detail.html", {"post": post})

6-2) blog/urls.py (신규 파일)

from django.urls import path
from . import views

app_name = "blog"

urlpatterns = [
    path("", views.post_list, name="post_list"),
    path("<int:pk>/", views.post_detail, name="post_detail"),
]

6-3) 프로젝트 urls.py에 include

app/config/urls.py에 Blog URL을 연결합니다.

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path("admin/", admin.site.urls),
    path("blog/", include("blog.urls")),  # ← 추가
]

7) 템플릿 작성

디렉터리를 만들고 두 개의 템플릿을 만듭니다.

# 컨테이너 바깥(호스트)에서 프로젝트 폴더 내 경로에 파일 생성
# 경로 예: app/blog/templates/blog/

7-1) app/blog/templates/blog/post_list.html

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="utf-8">
  <title>블로그</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
  <h1>블로그 글</h1>
  <ul>
    {% for post in posts %}
      <li>
        <a href="{% url 'blog:post_detail' post.pk %}">{{ post.title }}</a>
        <small>{{ post.created_at }}</small>
      </li>
    {% empty %}
      <li>아직 글이 없습니다.</li>
    {% endfor %}
  </ul>
</body>
</html>

7-2) app/blog/templates/blog/post_detail.html

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="utf-8">
  <title>{{ post.title }}</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
  <p><a href="{% url 'blog:post_list' %}">← 목록</a></p>
  <h1>{{ post.title }}</h1>
  <p><small>{{ post.created_at }}</small></p>
  <hr>
  <pre style="white-space:pre-wrap">{{ post.content }}</pre>
</body>
</html>

8) 동작 확인

  1. 브라우저에서 http://127.0.0.1:8000/blog/ 접속
  2. 방금 Admin에서 만든 글 목록이 보이면 성공입니다.
  3. 각 제목을 클릭하면 상세 페이지가 출력됩니다.

9) 정적 파일(선택) – Nginx와 연동하는 기본 흐름

프로젝트에서 정적 파일을 쓰려면:

  1. settings.py에 기본 설정
STATIC_URL = "/static/"
STATIC_ROOT = BASE_DIR / "staticfiles"
  1. 수집
docker-compose exec web python manage.py collectstatic --noinput
  1. nginx.conf에 /static/ 경로를 staticfiles 볼륨으로 매핑(이미 제공된 샘플을 사용 중이라면 기본 설정이 포함되어 있을 수 있습니다).
  2. 컨테이너 재시작
docker-compose restart nginx

10) 자주 쓰는 Docker 명령 모음

# 컨테이너 상태
docker-compose ps

# 웹 컨테이너 쉘
docker-compose exec web bash

# 로그 보기
docker-compose logs -f web
docker-compose logs -f nginx
docker-compose logs -f db

# 재시작 / 중지
docker-compose restart
docker-compose down

11) 트러블슈팅 체크리스트

  • 모델/마이그레이션 에러: makemigrations → migrate 순서 재확인, 모델 필드명 오타 점검
  • 템플릿 경로 문제: templates/blog/파일명.html 경로가 맞는지, 앱 이름과 폴더명이 일치하는지 확인
  • URL 404: config/urls.py에서 include("blog.urls") 추가했는지 확인
  • 정적 파일 미출력: collectstatic 실행 여부, Nginx /static/ 매핑 여부 점검

마무리

여기까지 완료하시면 Docker 환경에서 Django + MySQL로 운영되는 실전 앱 하나가 완성됩니다.
다음으로 원하시면,

  • 목록에 페이지네이션 추가,
  • Bootstrap 디자인 적용,
  • 작성/수정/삭제(CRUD) 뷰 연결,
  • 권한/로그인 연동
    까지 차근차근 확장해 드리겠습니다.

댓글