본 문서는 패스트캠퍼스 ‘Web-Programming School’ 수업 자료를 바탕으로 작성되었습니다.
Static file 와 Media file
Static file
(css,image,js)은 웹 서비스에 사용하려고 미리 준비해 놓은 정적 파일이다. 서비스 중에도 수시로 추가되거나 변경될 수 있다.
Media file
은 사용자가 웹에 업로드하는 파일이다. 파일자체는 정적이지만, 언제 제공되고 필요한지에 대해선 알 수 없다.
# config/settings.py
# Static
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(ROOT_DIR, '.static')
# Media (User-uploaded files)
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(ROOT_DIR, '.media')
STATIC_DIR = os.path.join(BASE_DIR, 'static')
STATICFILES_DIRS = [
STATIC_DIR,
]
STATIC_URL
: 웹 페이지에서 사용할 정적 파일의 최상위 URL 경로(URL만 존재)STATIC_ROOT
: Django 프로젝트에서 사용하는 모든 정적 파일을 한곳에 모아넣은 경로.DEBUG
가True
이면STATIC_ROOT
설정 작용되지 않음. 웹 서버에서 접근하여 정적파일을 제공하는 곳STATICFILES_DIRS
: 개발 단계에서 사용하는 정적파일 경로 지정하는 설정 항목. list나 tuple 로 작성해야 한다.MEDIA_ROOT
: 업로드가 끝난 파일을 배치할 최상위 경로 지정하는 설정 항목MEDIA_URL
:STATIC_URL
과 비슷한 역할
Django에서 정적파일 제공 기능(개발단계)
- 로컬 서버에서
static url
(static/photo/.jpg)로 접근하면 해당 이미지파일을 제대로 볼 수 있다. 그러나media/
url로 접근한 경우 Page not found 에러가 발생한다. 왜냐하면 Django에서 media file에 대한 처리는urls.py
에static
메소드를 사용해서 정적 파일을 제공하도록 하지만 static file은 아래와 같은 설정이 없어도 제공되도록 설정되어있다.
# config/urls.py
from django.contrib import admin
from django.urls import path, re_path
from config.views import serve_media
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
path('admin/', admin.site.urls),
]
urlpatterns += static(
settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT,
)
동작원리
# config/urls.py
from django.contrib import admin
from django.urls import path, re_path
from config.views import serve_media
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
path('admin/', admin.site.urls),
re_path(r'media/(?P<path>.*)$', serve_media),
]
# config/settings.py
def serve_media(request, path):
# path에는 미디어 파일의 경로가 주어짐
# 주어진 미디어파일의 경로를 setttings.MEIDA_ROOT를 기준으로해서
# 해당 파일을 리턴해주는 view함수 구현
media_file = os.path.join(settings.MEDIA_ROOT, path)
# rb - 이진파일을 읽기전용 모드로 열기
return FileResponse(open(media_file, 'rb'))
FileResponse
: 바이너리 파일에 최적화된StreamingHttpResponse
의 하위 객채StreamingHttpResponse
: 장고에서 브라우저로부터의 응답을 스트리밍하는데 사용한다. / 큰 파일을 브라우저에 스트리밍할 때 유용- 이렇게 실행을 하면, 이진파일을 그대로 출력하기 때문에 제대로 된 이미지 파일을 볼 수 없다. 이를 위해, 이미지 파일의 형식을 함께 전달해줘야 한다.
def serve_media(request, path):
media_file = os.path.join(settings.MEDIA_ROOT, path)
content_type = mimetypes.guest_type(path)
return FileResponse(open(media_file, 'rb'),
content_type=content_type)
웹 서버
# 일반적인 runserver
- 브라우저 -> runserver -> Django
# Deploy
Browser -> EC2 -> Nginx -> uWSGI -> Django
Browser (/static/,/media/)-> EC2 -> Nginx
서버 Media
DEBUG = False
를 하는 경우엔static/
과media/
url 모두가 이미지처리를 제대로 하지 못한다.- 정적파일의 경우 웹 서버 Nginx가 처리하는게 빠르기 때문에 이러한 설정을 따로 지정해야한다.
<!-- ec2-deploy/.config/nginx-app.conf -->
server {
listen 80;
server_name *.amazonaws.com;
charset utf-8;
client_max_body_size 128M;
location / {
uwsgi_pass unix:///tmp/app.sock;
include uwsgi_params;
}
location /media/ {
alias /srv/ec2-deploy/.media/;
}
}
- 설정파일 설정 후
http://ec2-13-125-207-76.ap-northeast-2.compute.amazonaws.com/media/photo/<이미지파일>
접속 하면 404 에러가 아닌 이미지를 볼 수 있다.
서버 Static
collectstatic
staitc
파일은 애플리케이션을 구성할 때 생성되는 파일이다.- app/static 파일의 경우 ec2-deploy 프로젝트를 위해 존재하는 파일이다. 이 외에도 여러곳에
static
폴더가 있다. (ex django.contrib.admin.static파일이 존재) 이러한 파일을 개별적으로 추가해서 사용하는 것은 번거롭다. 그래서static
파일을 한 곳에 모아서 관리해보자.
>> ./manage.py collectstatic
collectsatic
: 기본값은 STATICFILES_DIRS 및 INSTALLED_APPS 설정에 지정된 앱의 모든static
디렉토리를 찾는다. 명령이 실행 된후에는 STATICFILES_STORAGE의 post_process () 메소드를 호출하고 관리 명령에 의해 발견 된 경로 목록을 전달한다.- 명령어 실행 후에는
config/settings.py
에 설정한STATIC_ROOT
에 모든 static 파일이 존재하는.static
디렉토리가 생성된다. .gitignore
에 버전관리와 관련없는.static
파일을 추가하자
nginx-app.conf 설정
server {
listen 80;
server_name *.amazonaws.com;
charset utf-8;
client_max_body_size 128M;
location / {
uwsgi_pass unix:///tmp/app.sock;
include uwsgi_params;
}
location /media/ {
alias /srv/ec2-deploy/.media/;
}
location /static/ {
alais /srv/ec2-deploy/.static/;
}
}
- 설정 후
http://ec2-13-125-213-17.ap-northeast-2.compute.amazonaws.com/static/< 이미지파일>
으로 접속하면 이미지파일이 제대로 출력된다.
deploy.sh
# 그환경에 있는 bash를 사용해라
#!/usr/bin/env bash
export DJANGO_SETTINGS_MODULE=config.settings.production
# Nginx에 존재하던 모든 enabled서버 설정 링크 삭제
sudo rm -rf /ect/nginx/sites-enabled/*
# 프로젝트의 Nginx 설정 (nginx-app.conf)
sudo cp -f /srv/ec2-deploy/.config/nginx-app.conf /etc/nginx/sites-available/nginx-app.conf
sudo ln -sf /ect/nginx/sites-available/nginx-app.conf /etc/nginx/sites-enabled/nginx.conf
sudo cp -f /srv/ec2-deploy/.config/uwsgi.service /etc/systemd/system/uwsgi.service
cd /srv/ec2-deploy/app
# ubuntu 유저로 collectstatic 명령어를 실행 (deploy 스크립트가 root로 설정되서)
/bin/bash -c \
'/home/ubuntu/.pyenv/versions/fc-ec2-deploy/bin/python \
/srv/ec2-deploy/app/manage.py collectstatic --noinput' ubuntu
sudo systemctl enable uwsgi
sudo systemctl daemon-reload
sudo systemctl restart uwsgi nginx
- 매번 scp로 복사하고 셋팅을 위해 명령어 치는 것이 불편해서 쉘 스크립트로 정리
- 이 경우,
chmod -R 755 deploy.sh
설정을 통해 실행 권한을 주자