首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ValueError:在Heroku with Docker,django-pipeline,whitenoise上缺少静态文件清单条目

ValueError:在Heroku with Docker,django-pipeline,whitenoise上缺少静态文件清单条目
EN

Stack Overflow用户
提问于 2021-03-09 00:44:03
回答 1查看 227关注 0票数 0

我正在尝试使用Docker、django-pipeline和whitenoise在Heroku上部署Django项目。容器构建成功,我看到collectstaticcontainer-name/static中生成了预期的文件。但是,在访问任何页面时,我都会收到以下500错误:

代码语言:javascript
复制
ValueError: Missing staticfiles manifest entry for 'pages/images/favicons/apple-touch-icon-57x57.png'

下面是我的settings.pyDockerfileheroku.yml。由于我也在使用django-pipeline,有一件事我不确定,那就是对STATICFILES_STORAGE使用什么设置?我试过了

代码语言:javascript
复制
STATICFILES_STORAGE = 'pipeline.storage.PipelineStorage'

但是这导致文件路径404ing。

任何建议都是值得感谢的。谢谢。

代码语言:javascript
复制
#settings.py
...
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = env.bool("DJANGO_DEBUG", default=False)

ALLOWED_HOSTS = ['.herokuapp.com', 'localhost', '127.0.0.1']

INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.admindocs",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "django.contrib.sites",
    # Third-party
    "allauth",
    "allauth.account",
    "debug_toolbar",
    "django_extensions",
    "pipeline",
    "rest_framework",
    "whitenoise.runserver_nostatic",
    "widget_tweaks",
    # Local
    ...
]
MIDDLEWARE = [
    "debug_toolbar.middleware.DebugToolbarMiddleware",
    "django.middleware.security.SecurityMiddleware",
    "whitenoise.middleware.WhiteNoiseMiddleware",
    ...
]

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.1/howto/static-files/

STATIC_URL = "/static/"
# STATICFILES_DIRS = [str(BASE_DIR.joinpath("code/static"))]
STATIC_ROOT = str(BASE_DIR.joinpath("static"))

MEDIA_URL = "/media/"

MEDIA_ROOT = str(BASE_DIR.joinpath("media"))

# django-pipeline config
STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"
DEBUG_PROPAGATE_EXCEPTIONS = True
STATICFILES_FINDERS = (
    "django.contrib.staticfiles.finders.FileSystemFinder",
    "django.contrib.staticfiles.finders.AppDirectoriesFinder",
    "pipeline.finders.PipelineFinder",
)
...
代码语言:javascript
复制
# 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
COPY . /code/
RUN npm install sass --dev
RUN npm install yuglify --dev
RUN npm install
RUN mkdir static
RUN mkdir staticfiles

# 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
代码语言:javascript
复制
# heroku.yml
setup:
  addons:
  - plan: heroku-postgresql
build:
  docker:
    web: Dockerfile
release:
  image: web
  command:
    - python manage.py collectstatic --noinput
run:
  web: gunicorn config.wsgi

更新

根据ENDEESA对this similar SO post的响应,我将设置更新为以下内容,因为我的静态文件存储在pages/static/pages

代码语言:javascript
复制
STATIC_URL = "/static/"
STATICFILES_DIRS = [str(BASE_DIR.joinpath("pages/static"))]
STATIC_ROOT = str(BASE_DIR.joinpath("static"))

我还注意到我的顶级urls.py文件包含以下行:

代码语言:javascript
复制
urlpatterns += staticfiles_urlpatterns()

据我所知,这对于在开发中提供静态文件很有用,但不应该在生产中使用,所以我将其移动到只有在DEBUG为True时才添加。但是,遗憾的是,错误仍然存在。

更神秘的是,当我跑

代码语言:javascript
复制
python manage.py findstatic <file-path> --verbosity 2

找到该文件:

代码语言:javascript
复制
Found 'images/favicons/apple-touch-icon-57x57.png' here:
  /code/pages/static/images/favicons/apple-touch-icon-57x57.png
  /code/pages/static/images/favicons/apple-touch-icon-57x57.png
Looking in the following locations:
  /code/pages/static
  /code/static
  /usr/local/lib/python3.8/site-packages/django/contrib/admin/static
  /usr/local/lib/python3.8/site-packages/debug_toolbar/static
  /usr/local/lib/python3.8/site-packages/django_extensions/static
  /usr/local/lib/python3.8/site-packages/rest_framework/static

那么,为什么我仍然可以使用ValueError: Missing staticfiles manifest entry

EN

回答 1

Stack Overflow用户

发布于 2021-03-10 18:31:33

已解决

最后,我得出了以下解决方案。我的主要问题是:

  • 静态文件似乎是在释放命令期间收集的,但在我的容器中实际的STATIC_ROOT目录是空的。我不知道为什么。我的解决方案是不在heroku.yml中以发布命令的形式运行collectstatic,而是在Dockerfile.
  • NOTE:中这样做,以便在我的Dockerfilecollectstatic我需要为所有环境变量设置默认值,包括SECRET_KEY,后者我使用了django.core.management.utils中的get_random_secret_key()。感谢illustrating this here.
  • In为我添加到需要默认密钥的settings.pyRyan Knight,我的最终静态文件设置如下所示。
  • 由于我使用的是django-pipeline,因此无法使用whitenoise存储选项正确加载我的js文件。我最终使用的是pipeline.storage.PipelineStorage
  • ,结果我根本不需要设置STATICFILES_DIRS。之前我将其设置为:

代码语言:javascript
复制
STATICFILES_DIRS = [
    str(BASE_DIR.joinpath("pages/static")),
    str(BASE_DIR.joinpath("staticfiles")),]

这两个都是不必要的,因为app_name/static/app_name已经是default place Django will look for static files了,而我实际上并没有在root/staticfiles中存储额外的非应用特定的文件。所以我删除了这个设置。

在Heroku中,我删除了collectstatic.

  • On的release命令在我的heroku.yml应用管理的设置页面中,我为DISABLE_COLLECTSTATIC添加了一个设置为1.

的配置变量

代码语言:javascript
复制
# 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
COPY . /code/
RUN npm install sass --dev
RUN npm install yuglify --dev
RUN npm install

# Install dependencies
COPY Pipfile Pipfile.lock /code/
RUN pip install pipenv && pipenv install --system

# Collect static files here instead of in heroku.yml so they end up in /code/static, as expected in the app
RUN python manage.py collectstatic --noinput
代码语言:javascript
复制
# settings.py
...
from django.core.management.utils import get_random_secret_key
SECRET_KEY = env("DJANGO_SECRET_KEY", default=get_random_secret_key())
...
STATIC_URL = "/static/"
STATIC_ROOT = str(BASE_DIR.joinpath("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",
)
...
代码语言:javascript
复制
# heroku.yml
setup:
  addons:
  - plan: heroku-postgresql
build:
  docker:
    web: Dockerfile
release:
  image: web
run:
  web: gunicorn config.wsgi

项目结构,以防对您有帮助:

代码语言:javascript
复制
config
  settings.py
  ...
pages
  static
    pages
      scss
      js
      images
static
Dockerfile
heroku.yml
docker-compose.yml
...

祝其他与部署之神战斗的人好运。愿机会永远对你有利,不要放弃!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66533760

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档