70일차 [ 장고 마지막 날 ]
전기자전거 뺑소니 당한 후로 정신이 좀 없다. 합의금도 받아내야 했고, 오른손잡이인데 오른손이 아파서 뭘 못하겠고, 손이 아프다 못해 팔꿈치까지 내려오는 통증으로 힘들었다. 타자 치는 것도 새끼손가락이 할 걸 넷째손가락이 감당하니 넷째 손가락도 아파질 지경이다. 거기다 이제 새롭게 배웠던 장고도 사실 생소해서 배우기 힘들었다. 하지만 나에겐 지피티가 있어서 그나마 감당할만 했다. 나는 기술적인 설명이 어려우면 항상 비유를 들어달라고 한다. 그러면 아파트 주민 관리라든지, 레스토랑이라든지, 알아서 찰떡으로 설명 해준다. 딱딱한 설명보단 훨씬 나은 것 같다. 그리고 오늘 질문한거 정리해달라면 다 해준다. 진짜 신기한 세상이다. 어떻게 말 하는대로 다 해주지?? 아래는 지피티가 내가 질의응답한 걸 정리해준 것이다.
🐍 Django 개발자가 꼭 알아야 할 웹서버 & WAS, 그리고 Nginx 설정 정리
📌 1. Django 모델 수정 시 DB 테이블 왜 지워야 할까?
Django의 모델은 마치 건축 설계도와 같다.
한 번 생성된 테이블은 이 "옛날 설계도"에 맞춰 이미 지어진 건물이다.
모델을 수정하면 설계도가 바뀌는 것이기 때문에,
이미 만들어진 건물(테이블)과 안 맞는 문제가 생길 수 있다.
🔨 해결 방법
- 설계도 수정 후 makemigrations + migrate 명령어로 자동 반영
- 하지만 구조가 크게 바뀌면 테이블을 삭제하고 재생성하는 것이 더 나을 때도 있다
# 예시: 개발용 초기화 자동화
mysql -u root -proot1234 -h localhost -e "DROP DATABASE IF EXISTS django_db; CREATE DATABASE django_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
python manage.py makemigrations --noinput
python manage.py migrate --noinput
⚙️ 2. 웹서버(Web Server)와 WAS(Web Application Server) 차이
역할 | 정적 파일 처리 (HTML, CSS 등) | 동적 요청 처리 (로그인, DB조회 등) |
비유 | 식당의 웨이터 | 식당의 주방장 |
대표 예시 | Nginx, Apache | Gunicorn, uWSGI, Tomcat |
✅ Django 기준으로 설명하면:
- Nginx: 사용자 요청 받기, 정적 파일 서빙
- Gunicorn/uWSGI: Django 실행, 동적 요청 처리
🛠 3. Gunicorn vs uWSGI
특징 | Python 전용, 사용 쉬움 | 다양한 언어 지원, 설정 강력 |
추천 사용처 | Django, Flask 등 가벼운 서비스 | 대규모 서비스, 세밀한 최적화 필요 시 |
설정 난이도 | 낮음 | 높음 |
- Gunicorn은 간단하고 실무에서도 많이 씀
- uWSGI는 더 많은 기능과 옵션을 제공하지만 복잡함
🧩 4. Nginx + Gunicorn 연동 설정 예시 분석
# nginx
upstream django {
server django_gunicorn:8000;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://django;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /static/ {
alias /app/staticfiles/;
}
}
🌐 해설
upstream | Gunicorn 서버를 django라는 이름으로 정의 |
location / | 동적 요청은 Gunicorn(Django)으로 전달 |
location /static/ | 정적 파일은 Nginx가 직접 서빙 (빠름) |
proxy_set_header | 사용자 실제 IP와 Host 정보를 Django에 전달 |
proxy_redirect off | 리다이렉션 방지 설정 |
✅ 총정리
- Django 모델 수정 시에는 DB 스키마와의 불일치를 조심해야 하며, 초기화 자동화 스크립트를 활용하면 편리하다.
- **웹서버(Nginx)**는 정적 처리, **WAS(Gunicorn/uWSGI)**는 동적 처리 담당
- Gunicorn은 Django에 적합한 가벼운 WAS, uWSGI는 커스터마이징이 필요한 대규모에 적합
- Nginx는 Gunicorn 앞단에서 요청 분배와 정적 서빙을 처리하며, 필수 헤더와 보안 처리를 맡는다.
5. Docker Compose와 Dockerfile의 관계
역할 | 컨테이너 1개를 만드는 방법(설계도) 작성 | 여러 컨테이너를 한 번에 관리하고 조립하는 파일 |
주요 기능 | 컨테이너 이미지를 빌드함 | 컨테이너 여러 개를 띄우고 연결함 |
관계 | Compose가 내부적으로 Dockerfile을 참조해서 이미지를 빌드할 수 있다 | |
비유 | 햄버거 하나 만드는 레시피 | 햄버거 세트 메뉴 조합하는 메뉴판 |
✨ 요약: Dockerfile은 컨테이너 하나를 만드는 설계도,
docker-compose.yml은 여러 컨테이너를 한 세트로 조립하는 매니저다.
6. "파일로 저장하는 DB"가 존재하는가?
✅ 존재한다!
대표적인 "파일 기반 데이터베이스":
SQLite | 초경량 SQL DB, 파일 하나로 전체 데이터 관리 | .db, .sqlite |
DuckDB | 대용량 분석용, 로컬 파일 저장 SQL DB | .duckdb |
TinyDB | JSON 파일 기반 초소형 NoSQL DB | .json |
LevelDB | 키-값 저장 최적화, 구글 개발 | 바이너리 파일 |
✨ 요약: 서버 설치 없이, 파일 하나만으로 데이터베이스를 운영할 수 있는 시스템들도 존재한다.
7. MySQL은 파일형 DB인가?
답변:
MySQL은 서버형 DB다.
다만 데이터를 실제로는 여러 파일로 저장한다.
- MySQL은 항상 mysqld 서버 프로세스가 돌아가야 한다.
- 테이블/데이터는 내부적으로 .frm, .ibd 같은 파일로 쪼개 저장한다.
서버 필요 여부 | ❌ | ✅ |
데이터 저장 방식 | 단일 파일 | 다수 파일 및 디렉토리 |
예시 | SQLite | MySQL, PostgreSQL |
✨ 요약:
MySQL은 "서버처럼 동작"하면서 "파일에 데이터 저장"하는 서버형 데이터베이스다.
✏️ 최종 정리 요약
- Dockerfile = 컨테이너 하나 만드는 법
- docker-compose.yml = 컨테이너 여러 개 조립하고 연결
- 파일 기반 DB(SQLite, DuckDB 등)는 서버 없이 파일로 데이터 관리
- MySQL은 서버형 DB지만 실제 데이터는 여러 파일에 저장