django에서 collectstatic 명령으로 static 파일 수집시 에러
안녕하세요, django를 공부하는 중에 해결이 안되는 부분이 있어서 여쭤봅니다!
점프 투 장고 에서 python manage.py collectstatic
, 명령어를 이용해 django 웹서비스에 admin으로 접속할 때 CSS파일을 가져올 수 있게 하려고 하면... 예외가 발생하는데요,
일단 전 현재 Ubuntu 20.04.4
버전을 사용하고 있고 '점프 투 장고' 책에서 사용한 Nginx
와 Gunicorn
을 사용하고있습니다.
에러가 발생하는 부분을 살펴보자면,
You have requested to collect static files at the destination
location as specified in your settings.
This will overwrite existing files!
Are you sure you want to do this?
Type 'yes' to continue, or 'no' to cancel: yes
Traceback (most recent call last):
File "manage.py", line 22, in <module>
main()
File "manage.py", line 18, in main
execute_from_command_line(sys.argv)
File "/home/devadmin/venvs/bio_platform/lib/python3.8/site-packages/django/core/management/__init__.py", line 446, in execute_from_command_line
utility.execute()
File "/home/devadmin/venvs/bio_platform/lib/python3.8/site-packages/django/core/management/__init__.py", line 440, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/devadmin/venvs/bio_platform/lib/python3.8/site-packages/django/core/management/base.py", line 414, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/devadmin/venvs/bio_platform/lib/python3.8/site-packages/django/core/management/base.py", line 460, in execute
output = self.handle(*args, **options)
File "/home/devadmin/venvs/bio_platform/lib/python3.8/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 209, in handle
collected = self.collect()
File "/home/devadmin/venvs/bio_platform/lib/python3.8/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 135, in collect
handler(path, prefixed_path, storage)
File "/home/devadmin/venvs/bio_platform/lib/python3.8/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 368, in copy_file
if not self.delete_file(path, prefixed_path, source_storage):
File "/home/devadmin/venvs/bio_platform/lib/python3.8/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 278, in delete_file
if self.storage.exists(prefixed_path):
File "/home/devadmin/venvs/bio_platform/lib/python3.8/site-packages/django/core/files/storage.py", line 362, in exists
return os.path.lexists(self.path(name))
File "/home/devadmin/venvs/bio_platform/lib/python3.8/site-packages/django/contrib/staticfiles/storage.py", line 39, in path
raise ImproperlyConfigured(
django.core.exceptions.ImproperlyConfigured: You're using the staticfiles app without having set the STATIC_ROOT setting to a filesystem path.
구글링도 해보고 STACKOVERFLOW도 뒤져봤는데요, STATIC_ROOT가 제대로 설정되어있지 않을때 발생하는 예외라고 하더군요,
일단 프로젝의 디렉토리 구성은 아래와 같습니다 :
└── bio_platform
├── common
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-310.pyc
│ │ ├── __init__.cpython-38.pyc
│ │ ├── __init__.cpython-39.pyc
│ │ ├── admin.cpython-310.pyc
│ │ ├── admin.cpython-38.pyc
│ │ ├── admin.cpython-39.pyc
│ │ ├── apps.cpython-310.pyc
│ │ ├── apps.cpython-38.pyc
│ │ ├── apps.cpython-39.pyc
│ │ ├── forms.cpython-310.pyc
│ │ ├── forms.cpython-38.pyc
│ │ ├── forms.cpython-39.pyc
│ │ ├── models.cpython-310.pyc
│ │ ├── models.cpython-38.pyc
│ │ ├── models.cpython-39.pyc
│ │ ├── urls.cpython-310.pyc
│ │ ├── urls.cpython-38.pyc
│ │ ├── urls.cpython-39.pyc
│ │ ├── views.cpython-310.pyc
│ │ ├── views.cpython-38.pyc
│ │ └── views.cpython-39.pyc
│ ├── admin.py
│ ├── apps.py
│ ├── forms.py
│ ├── migrations
│ │ ├── __init__.py
│ │ └── __pycache__
│ ├── models.py
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── config
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-310.pyc
│ │ ├── __init__.cpython-38.pyc
│ │ ├── __init__.cpython-39.pyc
│ │ ├── settings.cpython-310.pyc
│ │ ├── settings.cpython-38.pyc
│ │ ├── settings.cpython-39.pyc
│ │ ├── urls.cpython-310.pyc
│ │ ├── urls.cpython-38.pyc
│ │ ├── urls.cpython-39.pyc
│ │ ├── wsgi.cpython-310.pyc
│ │ ├── wsgi.cpython-38.pyc
│ │ └── wsgi.cpython-39.pyc
│ ├── asgi.py
│ ├── settings
│ │ ├── __pycache__
│ │ ├── base.py
│ │ ├── local.py
│ │ └── prod.py
│ ├── urls.py
│ └── wsgi.py
├── db.sqlite3
├── manage.py
├── node_modules
│ └── bootstrap
│ ├── LICENSE
│ ├── README.md
│ ├── dist
│ ├── js
│ ├── package.json
│ └── scss
├── package-lock.json
├── pybo
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-310.pyc
│ │ ├── __init__.cpython-38.pyc
│ │ ├── __init__.cpython-39.pyc
│ │ ├── admin.cpython-310.pyc
│ │ ├── admin.cpython-38.pyc
│ │ ├── admin.cpython-39.pyc
│ │ ├── apps.cpython-310.pyc
│ │ ├── apps.cpython-38.pyc
│ │ ├── apps.cpython-39.pyc
│ │ ├── forms.cpython-310.pyc
│ │ ├── forms.cpython-38.pyc
│ │ ├── forms.cpython-39.pyc
│ │ ├── models.cpython-310.pyc
│ │ ├── models.cpython-38.pyc
│ │ ├── models.cpython-39.pyc
│ │ ├── urls.cpython-310.pyc
│ │ ├── urls.cpython-38.pyc
│ │ ├── urls.cpython-39.pyc
│ │ └── views.cpython-310.pyc
│ ├── admin.py
│ ├── apps.py
│ ├── forms.py
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ ├── 0002_question_author.py
│ │ ├── 0003_answer_author.py
│ │ ├── 0004_answer_modify_date_question_modify_date.py
│ │ ├── 0005_comment.py
│ │ ├── 0006_answer_voter_question_voter_alter_answer_author_and_more.py
│ │ ├── 0007_auto_20220411_1325.py
│ │ ├── __init__.py
│ │ └── __pycache__
│ ├── models.py
│ ├── templatetags
│ │ ├── __pycache__
│ │ └── pybo_filter.py
│ ├── tests.py
│ ├── urls.py
│ └── views
│ ├── __pycache__
│ ├── answer_views.py
│ ├── base_views.py
│ ├── comment_views.py
│ ├── question_views.py
│ └── vote_views.py
├── static
│ ├── bootstrap.min.css
│ ├── bootstrap.min.js
│ ├── jquery-3.6.0.min.js
│ └── style.css
├── templates
│ ├── base.html
│ ├── common
│ │ ├── login.html
│ │ └── signup.html
│ ├── form_errors.html
│ ├── navbar.html
│ └── pybo
│ ├── answer_form.html
│ ├── comment_form.html
│ ├── question_detail.html
│ ├── question_form.html
│ └── question_list.html
└── winehq.key
점프 투 장고에 나오는 것 처럼 세팅파일은 아래와 같이 분리해둔 상태고,
├── settings
│ │ ├── __pycache__
│ │ ├── base.py
│ │ ├── local.py
│ │ └── prod.py
아래 세팅파일들의 풀 코드를 공유해드립니다. (IP부분은 블랭크 처리했습니다.).
base.py
"""
Django settings for config project.
Generated by 'django-admin startproject' using Django 4.0.3.
For more information on this file, see
https://docs.djangoproject.com/en/4.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.0/ref/settings/
"""
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'blank' #private part
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ['blank'] #private part
# Application definition
INSTALLED_APPS = [
'common.apps.CommonConfig',
'pybo.apps.PyboConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'config.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'config.wsgi.application'
# Database
# https://docs.djangoproject.com/en/4.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# Password validation
# https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/4.0/topics/i18n/
LANGUAGE_CODE = 'ko-kr'
TIME_ZONE = 'Asia/Seoul'
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.0/howto/static-files/
STATIC_URL = 'static/'
#STATIC_ROOT = os.path.join(BASE_DIR,'static')
STATICFILES_DIRS = [
BASE_DIR / 'static',
]
# Default primary key field type
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
LOGIN_REDIRECT_URL = '/'
LOGOUT_REDIRECT_URL = '/'
local.py
from .base import *
ALLOWED_HOSTS = []
prod.py
from .base import *
import os
ALLOWED_HOSTS = ['blank'] #private part
STATIC_URL = 'static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
#STATIC_ROOT = BASE_DIR / 'static/'
STATICFILES_DIRS = []
# concept addon
일단 추측으로는 STATIC ROOT
를 설정해도 경로를 제대로 인식하지 못하고 있는 것이라 생각하고 이것 저것 바꿔보고 있는데, 신통치는 않더군요.
아래는 nignx 서버 자동 구성을 위한 bio_platform.service
파일의 코드입니다.
bio_platform.service
server {
listen 80;
server_name blank; #private part
location = /favicon.ico { access_log off; log_not_found off; }
location /static {
alias /home/devadmin/projects/bio_platform/static;
}
location / {
include proxy_params;
proxy_pass http://unix:/tmp/gunicorn.sock;
}
}
일단 구글링해서 시도해본 방법으로는:
내가 해본 방법
STATIC_ROOT 하고 STATIC_URL 변수를 prod.py에 지정해주기,
STATIC_ROOT 하고 STATIC_URL 변수를 base.py에 지정해주기,
등인데요, import os를 통해서 변수를 지정하는 방법도 있고 이것저것 해봤는데 django.core.exceptions.ImproperlyConfigured: You're using the staticfiles app without having set the STATIC_ROOT setting to a filesystem path.
는 여전히 절 괴롭히더군요...
이제는 STATIC_ROOT 또는 STATIC_URL, STATICFILES_DIR 변수를 정확히 어디에 집어넣어야 해결될지 감이 잡히지 않습니다...
혹시 비슷한 경우를 겪으신 분이 있을까요?
lackdoy 님 1736
M 2022년 4월 20일 10:47 오전