NAS에서 블로그를 시작하며 나눈 역할
Python을 취미로 배우다가 직접 만든 사이트를 운영하고 싶어졌고, 사용 중이던 NAS에 Django 블로그를 올리기 시작했습니다. Nginx, Gunicorn, PostgreSQL을 모두 서버라고만 부르면 오류가 났을 때 확인할 부분이 모호해집니다. 지금 프로젝트를 기준으로 역할을 나누는 기준은 요청이 어디에서 끝나는가입니다.
이 글의 경로와 포트는 2026년 9월 22일 저장소의 개발·운영 Compose와 Nginx 설정을 대조한 값입니다. NAS의 DSM 역방향 프록시와 실제로 로드된 운영 설정까지 새로 조사한 결과는 아닙니다.
동적 페이지와 파일 요청은 다른 길로 간다
운영 Compose에는 web, db, nginx, pgadmin 서비스가 있습니다. 브라우저에 보이는 블로그 기능은 앞의 세 서비스가 맡고, pgAdmin은 별도의 DB 관리 도구입니다.
게시글 요청 → Nginx → myapp_web:8000 → Gunicorn → Django → PostgreSQL
정적 파일 요청 /static/... → Nginx → /var/www/static/...
업로드 파일 요청 /media/... → Nginx → /var/www/media/...
Nginx는 글의 공개 여부나 내용 검토 상태를 판단하지 않습니다. 글 요청을 Django에 전달하고, Django가 URL에 맞는 뷰와 조회 조건을 선택합니다. Gunicorn은 Django의 WSGI 애플리케이션을 실행하는 프로세스이며 DB 서버가 아닙니다. PostgreSQL에는 글·카테고리 같은 데이터가 저장되고, 업로드 이미지 파일 자체는 media 저장소에 따로 남습니다.
현재 Nginx 파일에는 /ads.txt의 정확한 경로 규칙도 있습니다. 따라서 모든 요청이 단순히 / 프록시를 거쳐 Django로 간다고 생각하면 파일 오류를 엉뚱한 곳에서 찾게 됩니다.
개발과 운영을 구분하는 표
| 확인 항목 | 개발 Compose | 운영 Compose |
|---|---|---|
| 웹 실행 | runserver, 호스트 8000번 연결 |
Gunicorn, 내부 8000번 |
| Nginx | 서비스 없음 | 호스트 8080 → 컨테이너 80 |
| DB | postgres:16, 호스트 5433 → 내부 5432 |
postgres:16, DB 호스트 포트 매핑 없음 |
| 소스 코드 | /app에 읽기·쓰기 바인드 |
/app에 읽기 전용 바인드 |
| DB 보관 | pgdata_dev |
pgdata |
| 정적 파일 | 개발 서버와 설정 확인 필요 | web·nginx가 같은 named volume 공유 |
이 표는 저장소에 선언된 연결입니다. 호스트 8080번이 인터넷에 그대로 공개된다는 뜻은 아닙니다. 외부 HTTPS, NAS 방화벽, 공유기 전달 규칙은 별도로 확인해야 합니다. 또한 개발 설정의 static_volume은 /app/static에 연결되고, Django의 기본 STATIC_ROOT는 /app/staticfiles입니다. 개발에서 보이는 CSS가 운영 수집·공유 경로까지 증명하지는 않습니다.
환경이 같아 보이는데 결과가 다를 때
Docker 이미지가 같아도 환경 변수, 바인드 마운트, 기존 DB 데이터, 이미지 태그가 실제로 가리키는 버전은 다를 수 있습니다. 이 프로젝트처럼 실행할 때 소스를 마운트하면 이미지에 복사된 코드보다 마운트된 코드가 사용됩니다. “이미지를 다시 만들었으니 모든 코드가 바뀌었다”는 판단도 실행 설정을 함께 봐야 합니다.
다음은 프로젝트 루트에서 실행하는 개발 환경 조회입니다. 컨테이너를 새로 시작하지 않습니다.
docker compose -f .\docker\dev\docker-compose.dev.yml config --quiet
docker compose -f .\docker\dev\docker-compose.dev.yml ps
첫 명령이 성공하면 설정 해석이 가능하다는 뜻입니다. 두 번째에서 db만 보이면 웹까지 실행된 상태라고 판단하지 않습니다. healthy도 그 서비스에 지정한 검사만 통과했다는 뜻이지, 글쓰기와 로그인까지 확인했다는 뜻은 아닙니다.
증상에서 출발하는 확인 순서
| 증상 | 우선 대조할 연결 | 다음 확인 |
|---|---|---|
| 전체 접속 실패 | 도메인·HTTPS·NAS 전달 | Nginx 포트와 컨테이너 상태 |
| 502 응답 | Nginx → web:8000 | Gunicorn 시작 실패와 같은 네트워크 여부 |
| 글은 보이는데 CSS만 404 | /static/ → 공유 volume |
collectstatic 결과와 alias |
| 페이지에서 DB 오류 | web → db:5432 | 연결 설정·인증·migration |
| 이미지 일부만 없음 | /media/ → 저장 파일 |
파일 존재·대소문자·권한 |
브라우저의 요청 URL과 응답 코드, 해당 시각의 로그를 같이 기록하면 조사 범위가 줄어듭니다. 502만 보고 DB volume을 지우거나, CSS 오류 때문에 모델을 다시 만드는 식의 조치는 원인과 연결되지 않습니다.
컨테이너 이름 대신 Compose 서비스 이름으로 통신하는 원리는 Docker 네트워크 문서에서 확인할 수 있습니다. 이어서 설치 후 실행 환경 확인, Compose 연결과 볼륨 순서로 살펴보면 이 표의 각 연결을 직접 점검할 수 있습니다.
댓글 0
로그인 없이 궁금한 점이나 의견을 남겨주세요.
아직 댓글이 없습니다. 첫 의견을 남겨주세요.