3

Heroku にデプロイしている Django アプリに、javascript、css などを含めるために、ファイルの静的ディレクトリを追加しようとしています。

heroku run python manage.py collectstaticストレージは AWS S3 で行われています。この静的ディレクトリを追加しようとする前に、コマンドが正常に機能し、管理サイトのすべてのアセットが AWS S3 バケットに配置された ため、この部分が機能していることがわかります。

基本的に、「コア」と呼ばれるプロジェクトのメイン アプリケーションと同じレベルに「static」というディレクトリを追加しました。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 コマンドを手動で実行すると、別の欠落しているディレクトリが表示されます。「アプリ」という名前のアプリはなく、設定ファイルに「アプリ」についての言及がないことに注意してください。

(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 に保存されなかった理由の少なくとも 1 つはwhitenoise.storage.CompressedManifestStaticFilesStorage、設定ファイルで設定した AWS ストレージ ミドルウェアではなく、WhiteNoise ローカル ファイル ストレージ ( )を使用したかったためであることが判明しました。

STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage’

原因は、設定ファイルの末尾にある次の行でした。

django_heroku.settings(locals())

STATICFILES_STORAGEその行は私の変数をオーバーライドします。だから私はそれを次のように変更しました:

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

これで解決すると思っていましたが、collectstatic はまだSTATICFILES_DIRSAWS 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