본문 바로가기
개발자모드/혼자공부하는파이썬

[파이썬/장고#38] 서버환경에서 디버그 모드 끄기(DEBUG=False), 사용자 404 오류 페이지 만들기

by 요니L 2022. 10. 31.

 

 

장고의 환경설정 파일에는 DEBUG라는 항목이 있다. 기본값은 DEBUG = True 이다. 하지만 장고 공식 문서에는 '운영 환경에서 DEBUG는 반드시 False로 해야 한다' 라고 되어 있다. 장고는 실행 도중 오류가 발생하면 DEBUG = True인 경우 오류 내용을 화면에 상세하게 출력한다. 이때 settings.py 파일과 urls.py 파일에 설정한 항목이 노출된다. 이 말은 DEBUG=True 상태로 운영하면 오류 발생 시 서버 정보가 노출된다는 말과 같다. 이것은 서버 해킹 등의 나쁜 결과를 초래할 수 있다. 따라서 운영 환경에서는 반드시 DEBUG 항목을 False로 설정해야 한다. 

 


DEBUG 설정하기

 

(1단계) DEBUG 항목을 False로 설정

 

서버의 환경설정 파일인 prod.py 파일을 아래와 같이 수정한다. 그리고 git 을 이용하여 변경 내역을 서버에 적용(cmd)한다.

 

# D:\projects\mysite\config\settings\prod.py (수정)

from .base import *

ALLOWED_HOSTS = ['3.35.154.72']
STATIC_ROOT = BASE_DIR / 'static/'
STATICFILES_DIRS = []
DEBUG = False

 

로컬 cmd에서 git 커밋처리

(mysite) D:\projects\mysite>git add *
(mysite) D:\projects\mysite>git commit -m "디버그 설정"
[master fac958e] 디버그 설정
 1 file changed, 1 insertion(+)

(mysite) D:\projects\mysite>git push
Enumerating objects: 9, done.
Counting objects: 100% (9/9), done.
Delta compression using up to 6 threads
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 430 bytes | 430.00 KiB/s, done.
Total 5 (delta 4), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (4/4), completed with 4 local objects.
To https://github.com/Yoni33333/pybo.git
   61fb4bc..fac958e  master -> master

(mysite) D:\projects\mysite>

 

▶ 운영서버에서 git pull

 

 

(2단계) DEBUG 항목의 차이점 확인하기 

 

이렇게 DEBUG 설정을 변경하면 어떤 차이가 생길까? 우선 개발 환경에서 존재하지 않는 페이지로 접속해 보자.

 

우선 서버 기동 : (mysite) D:\projects\mysite>python manage.py runserver

 

 

http://localhost:8000/hello 로 접속

 

개발환경에서 존재하지 않는 페이지로 이동한 경우 오류메시지

 

개발환경은 DEBUG = True로 설정되어 있으므로 많은 정보가 표시된다. 404 오류에서 urls.py파일에 설정한 내용이 노출된다. 이번에는 서버 환경에서 다음처럼 존재하지 않는 페이지로 접속해 보자.

 

404 오류가 발생하지만, 'Not Found'만 보이고 아무런 정보도 표시되지 않는다.

 

 

★ 페이지가 변경되지 않는다면 Gunicorn 다시 실행

(mysite) ubuntu@ip-172-26-8-122:~/projects/mysite$ gunicorn --bind unix:/tmp/gunicorn.sock config.wsgi:application

 

 

 

 


404 오류 페이지 만들기

 

다음은 구글에서 없는 페이지를 요청하면 404 오류 서비스를 어떻게 보여주는지 보여주는 화면이다. 최소한 이런 식으로 사용자에게 404 오류 페이지를 보여줘야 '서비스답다' 라고 할 수 있다.

 

구글의 404 오류페이지 화면

 

이번에는 404 오류 페이지를 '서비스답게' 표시하는 방법을 알아본다.

 

 

(1단계) handler404 변수 설정하기 

 

config/urls.py 파일에 handle404라는 변수를 다음처럼 추가한다.

 

# D:\projects\mysite\config\urls.py

from django.contrib import admin
from django.urls import path, include
from pybo.views import base_views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('pybo/', include('pybo.urls')),
    path('common/', include('common.urls')),
    path('', base_views.index, name='index') # / 페이지에 해당하는 urlpatterns
]

handler404 = 'common.views.page_not_found'

 

config/urls.py 파일에 handler404 변수를 설정하면 404 오류 발생 시 사용자가 정의한 뷰 함수를 호출하게 된다. 따라서 404 오류가 발생하면 위에 정의한 대로 common/views.py 파일의 page_not_found 함수가 호출된다. 

 

※ handler404 변수는 반드시 config/urls.py에 등록해야 한다. 만약 common/urls.py에 등록할 경우 정상 작동하지 않는다.

 

 

(2단계) page_not_found 함수 추가하기

 

common/views.py에 page_not_found 함수를 추가한다.

 

# D:\projects\mysite\common\views.py

from django.contrib.auth import authenticate, login
from django.shortcuts import render, redirect
from common.forms import UserForm


# Create your views here.
def signup(request):
    """
    회원가입
    """
    if request.method == "POST":
        form = UserForm(request.POST)
        if form.is_valid():
            form.save()
            username = form.cleaned_data.get('username')
            raw_password = form.cleaned_data.get('password1')
            user = authenticate(username=username, password=raw_password)
            login(request, user)
            return redirect('index')
    else:
        form = UserForm()
    return render(request, 'common/signup.html', {'form': form})


def page_not_found(request, exception):
    """
    404 Page not found
    """
    return render(request, 'common/404.html', {})

 

page_not_found 함수는 request 외에 exception이라는 매개변수를 하나 더 받음에 주의하자. 

 

 

(3단계) 404 템플릿 작성하기 

 

common/404.html 템플릿 파일을 새로 작성한다.

 

# D:\projects\mysite\templates\common\404.html (New)

{% extends "base.html" %}
{% block content %}
<div class="container">
    <div class="row justify-content-center">
        <div class="col-12 text-center">
            <span class="display-1 d-block">404</span>
            <div class="mb-4 lead">페이지를 찾을 수 없습니다.</div>
            <a href="/" class="btn btn-link">홈으로 돌아가기</a>
        </div>
    </div>
</div>
{% endblock %}

 

변경한 내용을 git을 이용하여 서버에 적용

 

 

 

(4단계) 서버에서 404 오류 확인하기

 

서버에 적용한 후 Gunicorn을 재실행하면 웹 브라우저에서 다음과 같이 존재하지 않는 URL을 호출했을 때 변경된 404 화면을 볼 수 있다. 

 

* gunicorn 실행

~/projects/mysite> gunicorn --bind unix:/tmp/gunicorn.sock config.wsgi:application

 

(mysite) ubuntu@ip-172-26-8-122:~/projects/mysite$ gunicorn --bind unix:/tmp/gunicorn.sock config.wsgi:application
[2022-10-31 09:47:13 +0900] [168333] [INFO] Starting gunicorn 20.1.0
[2022-10-31 09:47:13 +0900] [168333] [INFO] Listening at: unix:/tmp/gunicorn.sock (168333)
[2022-10-31 09:47:13 +0900] [168333] [INFO] Using worker: sync
[2022-10-31 09:47:13 +0900] [168335] [INFO] Booting worker with pid: 168335

 

 

 

 

하지만 개발 환경에서는 위처럼 404 페이지를 생성하더라도 여전히 장고가 제공하는 404 페이지가 보인다. 왜냐하면 개발환경은 DEBUG=True로 설정되어 있기 때문이다. DEBUG가 True인 경우에는 사용자가 404페이지를 직접 만들더라도 장고의 기본 404 페이지가 호출된다.

 

 


 

여기까지.

 

 

 

 

 

댓글