0

我的 Django 项目使用 Docker、gunicorn 和 whitenoise。我最近更改了设置以准备部署,最值得注意的是为 AWS 托管的媒体文件添加了配置。现在,当我在本地运行项目并且collectstatic静态文件不会在浏览器中更新时。但是,我确实看到了收集静态文件的更改。

我尝试过/仔细检查过的事情:

  • 确保我在容器和静态文件保存/更新的位置之间有一个共享卷
  • collectstatic在我的 Dockerfile 中添加一个步骤
  • 确认我的静态文件设置

是什么django-storages引起了这个问题吗?我认为以前我能够进行 SCSS 更改并通过刷新浏览器来显示它们。但这并没有发生。即使collectstatic在容器内运行也没有效果。

# relevant settings.py

INSTALLED_APPS = [
  ...
  "whitenoise.runserver_nostatic",
  "storages",
  ...
]

MIDDLEWARE = [
  "django.middleware.cache.UpdateCacheMiddleware",
  "django.middleware.security.SecurityMiddleware", 
  "whitenoise.middleware.WhiteNoiseMiddleware",
  ...
]

# AWS config (use in production only)
USE_S3 = env.bool("USE_S3", default=not DEBUG)
if USE_S3:
    AWS_ACCESS_KEY_ID = env.str("AWS_ACCESS_KEY_ID", default="")
    AWS_SECRET_ACCESS_KEY = env.str("AWS_SECRET_ACCESS_KEY", default="")
    AWS_STORAGE_BUCKET_NAME = env.str("AWS_STORAGE_BUCKET_NAME", default="")
    AWS_DEFAULT_ACL = None
    AWS_S3_REGION_NAME = env.str("AWS_S3_REGION_NAME", default="us-east-2")
    AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME
    AWS_S3_OBJECT_PARAMETERS = {
        'CacheControl': 'max-age=86400',
    }
    # S3 Public Media Settings
    PUBLIC_MEDIA_LOCATION = 'media'
    MEDIA_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/{PUBLIC_MEDIA_LOCATION}/'
    # S3 Private Media Settings
    DEFAULT_FILE_STORAGE = 'config.storage_backends.PrivateMediaStorage'
    PRIVATE_MEDIA_LOCATION = 'private'
    PRIVATE_FILE_STORAGE = 'config.storage_backends.PrivateMediaStorage'
else:
    MEDIA_URL = "/media/"
    MEDIA_ROOT = str(BASE_DIR.joinpath("media"))

STATIC_ROOT = str(BASE_DIR.joinpath("staticfiles"))
STATIC_URL = '/static/'
STATICFILES_STORAGE = 'pipeline.storage.PipelineStorage'
DEBUG_PROPAGATE_EXCEPTIONS = True
STATICFILES_FINDERS = (
    "django.contrib.staticfiles.finders.FileSystemFinder",
    "django.contrib.staticfiles.finders.AppDirectoriesFinder",
    "pipeline.finders.PipelineFinder",
)
PIPELINE_YUGLIFY_BINARY = "/usr/local/bin/node"
PIPELINE = {
    "CSS_COMPRESSOR": "pipeline.compressors.yuglify.YuglifyCompressor",
    "COMPILERS": (
        "pipeline.compilers.sass.SASSCompiler",
        "config.compilers.RollupCompiler",
    ),
    "YUGLIFY_BINARY": str(BASE_DIR.joinpath("node_modules/.bin", "yuglify")),
    "SASS_BINARY": str(BASE_DIR.joinpath("node_modules/.bin", "sass")),
    "STYLESHEETS": {
        "twirlmate": {
            "source_filenames": ("pages/scss/styles.scss",),
            "output_filename": "css/styles.css",
        }
    },
    "JS_COMPRESSOR": "pipeline.compressors.NoopCompressor",  # TODO: Update this to jsmin or something better.
    "ROLLUP_BINARY": str(BASE_DIR.joinpath("node_modules/.bin", "rollup")),
    "ROLLUP_ARGUMENTS": ["--config", "--configDebug", "--format", "iife"],
    "DISABLE_WRAPPER": True,
    "JAVASCRIPT": {
        "twirlmate": {
            "source_filenames": (
                "pages/js/core.js",
                "pages/js/file-field.js",
                "pages/js/lazy-loading.js",
                "pages/js/modal.js",
                "pages/js/navigation.js",
                "pages/js/notifications.js",
            ),
            "output_filename": "js/twirlmate.js",
        },
        "components": {
            "source_filenames": ("pages/js/vue/components.rollup.js",),
            "output_filename": "js/components.js",
        },
    },
}
#docker-compose.yml

version: '3.8'

services:
  web:
    build: .
    command: gunicorn config.wsgi -b 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - 8000:8000
    depends_on:
      - db
    environment:
      - "DJANGO_SECRET_KEY=****"
      - "DJANGO_DEBUG=True"
      - "DJANGO_SECURE_SSL_REDIRECT=False"
      - "SECURE_HSTS_SECONDS=0"
      - "SECURE_HSTS_INCLUDE_SUBDOMAINS=False"
      - "SECURE_HSTS_PRELOAD=False"
      - "SESSION_COOKIE_SECURE=False"
      - "CSRF_COOKIE_SECURE=False"
  db:
    image: postgres:11
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    environment:
      - "POSTGRES_HOST_AUTH_METHOD=trust"

volumes:
  postgres_data:
# Dockerfile

# Pull base image
FROM python:3.8

# Set environment variables and build arguments
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

RUN curl -sL https://deb.nodesource.com/setup_12.x | bash -
RUN apt-get install -y nodejs build-essential

# Set working directory
WORKDIR /code
RUN npm install sass --also=dev
RUN npm install yuglify --also=dev
RUN npm install

# Install dependencies
COPY Pipfile Pipfile.lock /code/
# Figure out conditional installation of dev dependencies
# Will need to remove --dev flag for production
RUN pip install pipenv && pipenv install --system --dev

COPY . /code/

# Collect static files
RUN python manage.py collectstatic --noinput

项目结构

twirlmate
├── .babelrc
├── .env
├── .gitignore
├── .pylintrc
├── Dockerfile
├── Makefile
├── Pipfile
├── Pipfile.lock
├── config
│   ├── __init__.py
│   ├── asgi.py
│   ├── compilers.py
│   ├── compressors.py
│   ├── constants.py
│   ├── settings.py
│   ├── storage_backends.py
│   ├── urls.py
│   └── wsgi.py
├── docker-compose.yml
├── heroku.yml
├── manage.py
├── package-lock.json
├── package.json
├── pages
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── static
│   │   └── pages
│   │       ├── css
│   │       │   ├── styles.css
│   │       │   └── styles.css.map
│   │       ├── fonts
│   │       ├── images
│   │       ├── js
│   │       │   └── vue
│   │       │       ├── components
│   │       │       │   ├── cards
│   │       │       │   ├── inputs
│   │       │       │   ├── miniMenus
│   │       │       │   └── modals
│   │       │       ├── components.rollup.js
│   │       │       ├── data
│   │       │       ├── directives
│   │       │       ├── forms
│   │       │       ├── mixins
│   │       │       ├── services
│   │       │       ├── views
│   │       │       └── vue-store.js
│   │       └── scss
│   │           ├── 01-utilities
│   │           ├── 02-vendors
│   │           ├── 03-base
│   │           ├── 04-layout
│   │           ├── 05-components
│   │           ├── 06-pages
│   │           ├── styles.css
│   │           ├── styles.css.map
│   │           └── styles.scss
│   ├── templatetags
│   │   ├── __init__.py
│   │   ├── __pycache__
│   │   ├── css_classes.py
│   │   └── url_paths.py
│   ├── tests
│   │   ├── __init__.py
│   │   └── test_views.py
│   ├── urls.py
│   └── views.py
├── pyproject.toml
├── rollup.config.js
├── staticfiles
│   ├── admin
│   ├── debug_toolbar
│   ├── django_extensions
│   ├── pages
│   │   ├── css
│   │   │   ├── styles.css
│   │   │   └── styles.css.map
│   │   ├── fonts
│   │   ├── images
│   │   ├── js
│   │   │   └── vue
│   │   │       ├── components
│   │   │       │   ├── cards
│   │   │       │   ├── inputs
│   │   │       │   ├── miniMenus
│   │   │       │   └── modals
│   │   │       ├── components.rollup.js
│   │   │       ├── components.rollup.roll.js
│   │   │       ├── data
│   │   │       ├── directives
│   │   │       ├── forms
│   │   │       ├── mixins
│   │   │       ├── views
│   │   │       └── vue-store.js
│   │   └── scss
│   │       ├── 01-utilities
│   │       ├── 02-vendors
│   │       ├── 03-base
│   │       ├── 04-layout
│   │       ├── 05-components
│   │       ├── 06-pages
│   │       ├── styles.css
│   │       ├── styles.css.map
│   │       └── styles.scss
│   └── rest_framework
└── templates
    ├── 403.html
    ├── _base.html
    ├── account
    │   ├── login.html
    │   ├── password_change.html
    │   ├── password_change_done.html
    │   ├── password_reset.html
    │   ├── password_reset_done.html
    │   ├── password_reset_from_key.html
    │   ├── password_reset_from_key_done.html
    │   └── signup.html
    ├── emails
    │   ├── duet_invitation.html
    │   └── duet_invitation.txt
    ├── includes
    │   ├── _favicons.html
    │   ├── _footer.html
    │   ├── _header.html
    │   └── forms
    │       ├── _widgets.html
    │       └── attrs.html
    ├── index.html
    ├── pages
    │   ├── for_coaches.html
    │   ├── for_directors.html
    │   └── home.html
    ├── registration
    │   ├── account-settings.password-change-done.html
    │   ├── account-settings.password-change.html
    │   ├── account-settings.profile-list.html
    │   └── privacy-policy.html
    └── studios
        ├── _studio_admin_base.html
        ├── my_studios.html
        ├── staff_list.html
        ├── studio_create.html
        ├── studio_detail.admin.html
        ├── studio_detail.html
        ├── studio_join.html
        ├── studio_list.html
        ├── studio_update.html
        └── team_list.html

index.html,所有其他模板都继承自该文件

{% load static pipeline %}

<!doctype html>
<html class="no-js" lang="en">

<head>
  ... other various meta tags ...
  {% stylesheet 'twirlmate' %}
  <!-- the above produces the path: /static/pages/scss/styles.css -->

  {% block styles %}{% endblock %}
  {% block extrastyles %}{% endblock %}
</head>

<body class="{% block body-class %}{% endblock %}" {% block body-attributes %}{% endblock %}>
  <div class="main-wrapper" data-target="main-wrapper">

    <a class="skip-to-main" href="#main">Skip to main content</a>

    {% block header %}{% endblock header %}
    {% block notifications %}{% endblock notifications %}
    {% block main %}{% endblock main %}
    {% block footer %}{% endblock footer %}
  </div>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
  {% javascript 'twirlmate' %}
  {% javascript 'components' %}
  {% block scripts %}{% endblock scripts %}
  {% block extrascripts %}{% endblock extrascripts %}
</body>
</html>

解决了

事实证明,有一个重复的、陈旧的文件具有相同的名称和相同的路径。模板正在寻找/static/pages/scss/styles.css,它以更新的形式存在于我的根静态目录中,正确的位置。但是pages/static/pages/scss/styles.css在之前对settings.py. 不知何故,我猜该文件被反复拉入并覆盖更新版本。一旦我删除了陈旧的文件,一切都得到了修复。

4

0 回答 0