3

我正在尝试向我在 Heroku 上部署的 Django 应用程序添加一个静态文件目录,以包含 javascript、css 等。

存储是使用 AWS S3 完成的,我知道这部分工作正常,因为在尝试添加此静态目录之前,命令heroku run python manage.py collectstatic运行良好,将所有管理站点的资产放入我的 AWS S3 存储桶中。

基本上,我在项目的主应用程序(称为“核心”)的同一级别添加了一个名为“静态”的目录。我希望当我运行 collectstatic 时,这个目录中的文件同样会放在我的 AWS S3 存储桶中,在“静态”下。

但这就是我尝试在 Heroku 上部署应用程序时得到的结果......

 (primedminds-FA7a2hIW) bash-3.2$ git push heroku master
 Counting objects: 2, done.
 Delta compression using up to 4 threads.
 Compressing objects: 100% (2/2), done.
 Writing objects: 100% (2/2), 236 bytes | 236.00 KiB/s, done.
 Total 2 (delta 1), reused 0 (delta 0)
 remote: Compressing source files... done.
 remote: Building source:
 remote: 
 remote: -----> Python app detected
 remote:  !     The latest version of Python 3.6 is python-3.6.6 (you are using python-3.6.5, which is unsupported).
 remote:  !     We recommend upgrading by specifying the latest version (python-3.6.6).
 remote:        Learn More: https://devcenter.heroku.com/articles/python-runtimes
 remote:        Skipping installation, as Pipfile.lock hasn't changed since last deploy.
 remote: -----> $ python manage.py collectstatic --noinput
 remote:        /app/.heroku/python/lib/python3.6/site-packages/psycopg2/__init__.py:144: UserWarning: The psycopg2 wheel package will be renamed from release 2.8; in order to keep installing from binary please use "pip install psycopg2-binary" instead. For details see: <http://initd.org/psycopg/docs/install.html#binary-install-from-pypi>.
 remote:          """)
 remote:        Traceback (most recent call last):
 remote:          File "manage.py", line 10, in <module>
 remote:            execute_from_command_line(sys.argv)
 remote:          File "/app/.heroku/python/lib/python3.6/site-packages/django/core/management/__init__.py", line 371, in execute_from_command_line
 remote:            utility.execute()
 remote:          File "/app/.heroku/python/lib/python3.6/site-packages/django/core/management/__init__.py", line 365, in execute
 remote:            self.fetch_command(subcommand).run_from_argv(self.argv)
 remote:          File "/app/.heroku/python/lib/python3.6/site-packages/django/core/management/base.py", line 288, in run_from_argv
 remote:            self.execute(*args, **cmd_options)
 remote:          File "/app/.heroku/python/lib/python3.6/site-packages/django/core/management/base.py", line 335, in execute
 remote:            output = self.handle(*args, **options)
 remote:          File "/app/.heroku/python/lib/python3.6/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 189, in handle
 remote:            collected = self.collect()
 remote:          File "/app/.heroku/python/lib/python3.6/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 105, in collect
 remote:            for path, storage in finder.list(self.ignore_patterns):
 remote:          File "/app/.heroku/python/lib/python3.6/site-packages/django/contrib/staticfiles/finders.py", line 125, in list
 remote:            for path in utils.get_files(storage, ignore_patterns):
 remote:          File "/app/.heroku/python/lib/python3.6/site-packages/django/contrib/staticfiles/utils.py", line 28, in get_files
 remote:            directories, files = storage.listdir(location)
 remote:          File "/app/.heroku/python/lib/python3.6/site-packages/django/core/files/storage.py", line 313, in listdir
 remote:            for entry in os.listdir(path):
 remote:        FileNotFoundError: [Errno 2] No such file or directory: '/tmp/build_c0914e5498ba1b53e00fb3adb7ce14d8/static'
 remote: 
 remote:  !     Error while running '$ python manage.py collectstatic --noinput'.
 remote:        See traceback above for details.
 remote: 
 remote:        You may need to update application code to resolve this error.
 remote:        Or, you can disable collectstatic for this application:
 remote: 
 remote:           $ heroku config:set DISABLE_COLLECTSTATIC=1
 remote: 
 remote:        https://devcenter.heroku.com/articles/django-assets
 remote:  !     Push rejected, failed to compile Python app.
 remote: 
 remote:  !     Push failed
 remote: Verifying deploy...
 remote: 
 remote: !  Push rejected to primedminds.
 remote: 
 To https://git.heroku.com/primedminds.git
  ! [remote rejected] master -> master (pre-receive hook declined)
 error: failed to push some refs to 'https://git.heroku.com/primedminds.git'

当我手动执行 collectstatic 命令时,它会抱怨另一个丢失的目录。请注意,我没有名为“app”的应用程序,并且在我的设置文件中没有提及任何“应用程序”:

(primedminds-FA7a2hIW) bash-3.2$ heroku run python manage.py collectstatic
Running python manage.py collectstatic on ⬢ primedminds... up, run.7871 (Free)
/app/.heroku/python/lib/python3.6/site-packages/psycopg2/__init__.py:144: UserWarning: The psycopg2 wheel package will be renamed from release 2.8; in order to keep installing from binary please use "pip install psycopg2-binary" instead. For details see: <http://initd.org/psycopg/docs/install.html#binary-install-from-pypi>.
  """)

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 10, in <module>
execute_from_command_line(sys.argv)
  File "/app/.heroku/python/lib/python3.6/site-packages/django/core/management/__init__.py", line 371, in execute_from_command_line
utility.execute()
  File "/app/.heroku/python/lib/python3.6/site-packages/django/core/management/__init__.py", line 365, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/app/.heroku/python/lib/python3.6/site-packages/django/core/management/base.py", line 288, in run_from_argv
self.execute(*args, **cmd_options)
  File "/app/.heroku/python/lib/python3.6/site-packages/django/core/management/base.py", line 335, in execute
output = self.handle(*args, **options)
  File "/app/.heroku/python/lib/python3.6/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 189, in handle
collected = self.collect()
  File "/app/.heroku/python/lib/python3.6/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 105, in collect
for path, storage in finder.list(self.ignore_patterns):
  File "/app/.heroku/python/lib/python3.6/site-packages/django/contrib/staticfiles/finders.py", line 125, in list
for path in utils.get_files(storage, ignore_patterns):
  File "/app/.heroku/python/lib/python3.6/site-packages/django/contrib/staticfiles/utils.py", line 28, in get_files
directories, files = storage.listdir(location)
  File "/app/.heroku/python/lib/python3.6/site-packages/django/core/files/storage.py", line 313, in listdir
for entry in os.listdir(path):
FileNotFoundError: [Errno 2] No such file or directory: '/app/static’

这是我的 settings.py 文件:

"""
Django settings for primedminds project.

Generated by 'django-admin startproject' using Django 1.9.

For more information on this file, see
https://docs.djangoproject.com/en/1.9/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.9/ref/settings/
"""

import os
import socket
import django_heroku

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = ‘&lt;redacted>'

# SECURITY WARNING: don't run with debug turned on in production!
if socket.gethostname().endswith('.local'): # True in your local computer
    DEBUG = True
    ALLOWED_HOSTS = ['localhost', '127.0.0.1',]
else:
    DEBUG = False
    ALLOWED_HOSTS = ['.herokuapp.com', 'primedminds.com',]
    #ALLOWED_HOSTS = ['*']

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        'django': {
            'handlers': ['console'],
            'level': os.getenv('DJANGO_LOG_LEVEL', 'DEBUG'),
        },
    },
}

# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'import_export',
    'storages',
    'core',
]

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 = 'primedminds.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(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 = 'primedminds.wsgi.application'


# Database
# https://docs.djangoproject.com/en/1.9/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': os.environ['DATABASE_NAME'],
        'USER': os.environ['DATABASE_USER'],
        'PASSWORD': os.environ['DATABASE_PASSWORD'],
        'HOST': '',
        'PORT': '',
    }
}


# Password validation
# https://docs.djangoproject.com/en/1.9/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/1.9/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'America/Los_Angeles'

USE_I18N = True

USE_L10N = True

USE_TZ = True


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

STATIC_URL = '/static/'
STATIC_ROOT = os.path.normpath(os.path.join(BASE_DIR, 'static'))
STATICFILES_DIRS = [
    os.path.normpath(os.path.join(BASE_DIR, 'static')),
]

# AWS S3

AWS_ACCESS_KEY_ID = os.environ['AWS_ACCESS_KEY_ID']
AWS_SECRET_ACCESS_KEY = os.environ['AWS_SECRET_ACCESS_KEY']
AWS_STORAGE_BUCKET_NAME = 'primedminds'
AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME

AWS_S3_OBJECT_PARAMETERS = {
    'CacheControl': 'max-age=86400',
}

AWS_LOCATION = 'static'
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
DEFAULT_FILE_STORAGE = 'primedminds.storage_backends.MediaStorage'
STATIC_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, AWS_LOCATION)

#ADMIN_MEDIA_PREFIX = STATIC_URL + 'admin/'



# Import export
#IMPORT_EXPORT_USE_TRANSACTIONS = True

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

# Configure Django App for Heroku.
#django_heroku.settings(locals(), staticfiles=True)
django_heroku.settings(locals())

更新1: 我忘记了我已经设置了一个.gitignore文件staticstaticfiles列出了。所以它表现得好像没有任何文件要上传。一旦我从其中删除了这些行,.gitignore它就会继续进行。

现在问题变成了为什么文件没有像我预期的那样保存到 AWS S3 存储桶中。相反,它们似乎要进入staticfiles/tmp 下的目录。这是正在发生的事情:

(primedminds-FA7a2hIW) bash-3.2$ git push heroku master
Counting objects: 6, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (6/6), 586 bytes | 586.00 KiB/s, done.
Total 6 (delta 3), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote: 
remote: -----> Python app detected
remote:  !     The latest version of Python 3.6 is python-3.6.6 (you are using python-3.6.5, which is unsupported).
remote:  !     We recommend upgrading by specifying the latest version (python-3.6.6).
remote:        Learn More: https://devcenter.heroku.com/articles/python-runtimes
remote:        Skipping installation, as Pipfile.lock hasn't changed since last deploy.
remote: -----> $ python manage.py collectstatic --noinput
remote:        /app/.heroku/python/lib/python3.6/site-packages/psycopg2/__init__.py:144: UserWarning: The psycopg2 wheel package will be renamed from release 2.8; in order to keep installing from binary please use "pip install psycopg2-binary" instead. For details see: <http://initd.org/psycopg/docs/install.html#binary-install-from-pypi>.
remote:          """)
remote:        148 static files copied to '/tmp/build_53bed4ea57eaa119caf33247adadfed7/staticfiles', 178 post-processed.
remote: 
remote: -----> Discovering process types
remote:        Procfile declares types -> web
remote: 
remote: -----> Compressing...
remote:        Done: 193.6M
remote: -----> Launching...
remote:        Released v85
remote:        https://primedminds.herokuapp.com/ deployed to Heroku
remote: 
remote: Verifying deploy... done.
To https://git.heroku.com/primedminds.git
   fc1cde0..0033cfe  master -> master

更新 2: 事实证明,它没有保存到 AWS 的至少一个原因是因为它想使用 WhiteNoise 本地文件存储 ( whitenoise.storage.CompressedManifestStaticFilesStorage) 而不是我在我的设置文件中设置的 AWS 存储中间件:

STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage’

罪魁祸首是设置文件末尾的这一行:

django_heroku.settings(locals())

那条线覆盖了我的STATICFILES_STORAGE变量。所以我把它改成:

django_heroku.settings(locals(), staticfiles=False)

我认为这会解决它,但 collectstatic 仍然没有将我拥有的文件放入STATICFILES_DIRS我的 AWS S3 存储桶中。我在 Heroku 服务器上运行了这个命令:

django-admin collectstatic --settings=primedminds.settings

并得到以下输出:

~ $ django-admin collectstatic  --settings=primedminds.settings
/app/.heroku/python/lib/python3.6/site-packages/psycopg2/__init__.py:144: UserWarning: The psycopg2 wheel package will be renamed from release 2.8; in order to keep installing from binary please use "pip install psycopg2-binary" instead. For details see: <http://initd.org/psycopg/docs/install.html#binary-install-from-pypi>.
  """)

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

0 static files copied, 148 unmodified.

至少现在它不仅仅是在本地复制文件。但仍然没有文件复制到 AWS。我也用--clear旗帜试过,但没有骰子。

[顺便说一句,我不得不使用django-admin命令,而不是python manage.py collectstatic,因为后一个命令由于某种原因没有获取项目设置文件!]

这已经很长时间了,以至于我现在可能只是在自言自语,但是为了记录,我现在面临的问题仍然是,为什么 collectstatic 没有像我预期的那样表现,把我拥有的文件在我STATICFILES_DIRS的 AWS S3 存储桶中?

4

0 回答 0