반응형
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) 동작 확인
- 브라우저에서 http://127.0.0.1:8000/blog/ 접속
- 방금 Admin에서 만든 글 목록이 보이면 성공입니다.
- 각 제목을 클릭하면 상세 페이지가 출력됩니다.
9) 정적 파일(선택) – Nginx와 연동하는 기본 흐름
프로젝트에서 정적 파일을 쓰려면:
- settings.py에 기본 설정
STATIC_URL = "/static/"
STATIC_ROOT = BASE_DIR / "staticfiles"
- 수집
docker-compose exec web python manage.py collectstatic --noinput
- nginx.conf에 /static/ 경로를 staticfiles 볼륨으로 매핑(이미 제공된 샘플을 사용 중이라면 기본 설정이 포함되어 있을 수 있습니다).
- 컨테이너 재시작
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) 뷰 연결,
- 권한/로그인 연동
까지 차근차근 확장해 드리겠습니다.
'컴퓨터과학과' 카테고리의 다른 글
| Git, 최근 상태로 복구 (0) | 2025.08.31 |
|---|---|
| docker ps와 docker compose ps (4) | 2025.08.26 |
| Docker 구조 속에서의 MySQL (1) | 2025.08.24 |
| 클라우드 실습 환경 구성: 계정 생성 (3) | 2025.08.12 |
| 시니어를 위한 클라우드 이해하기 – PPT 대본 (6) | 2025.08.11 |
댓글