将 django 应用程序部署到 heroku 时如何解决"FileNotFoundError: [Errno 2] No such file or directory: '/code/static



我正在阅读William S.Vincent的书《Django for Professionals》,我试图将Django应用程序部署到heroku,但在部署该应用程序时静态文件夹位置失败,我使用Dockerwhiteoise包来处理静态文件,这里是文件中的重要信息。设置.py导入dj_database_url导入套接字从pathlib导入路径导入os

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Este cambio es para el despliegue en heroku, ya que hay problemas con los archivos estáticos
# para más información vea: https://devcenter.heroku.com/articles/django-assets
#BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# El entorno, producción vs desarrollo
ENVIRONMENT = os.environ.get('ENVIRONMENT', default='production')
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.environ.get('SECRET_KEY')
# SECURITY WARNING: don't run with debug turned on in production!
# por defecto 0, ya que el proyecto estará pronto en producción
DEBUG = int(os.environ.get('DEBUG', default=0))
ALLOWED_HOSTS = ['aplicacion-de-ventas.herokuapp.com',
'localhost', '127.0.0.1']

# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'whitenoise.runserver_nostatic',
'django.contrib.staticfiles',
'django.contrib.sites',
# 3rd party
'crispy_forms',
'allauth',
'allauth.account',
'allauth.socialaccount',
'allauth.socialaccount.providers.github',
'allauth.socialaccount.providers.google',
'debug_toolbar',
# local apps
'pages.apps.PagesConfig',
'ventas.apps.VentasConfig',
'perfiles.apps.PerfilesConfig',
]
MIDDLEWARE = [
'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
'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',
'debug_toolbar.middleware.DebugToolbarMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware',
]
# Configuración de CACHE
CACHE_MIDDLEWARE_ALIAS = 'default'
CACHE_MIDDLEWARE_SECONDS = 604800
CACHE_MIDDLEWARE_KEY_PREFIX = ''
ROOT_URLCONF = 'clothes_shop_project.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 = 'clothes_shop_project.wsgi.application'

# Database
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'postgres',
'USER': 'postgres',
'PASSWORD': 'postgres',
'HOST': 'db',
'PORT': 5432
}
}

# Password validation
# https://docs.djangoproject.com/en/3.1/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/3.1/topics/i18n/
LANGUAGE_CODE = 'es'
TIME_ZONE = 'America/Lima'
USE_I18N = True
USE_L10N = True
# si esto permanece en False considera correctamente el tiempo de America/Lima
# si esto está en True considera el timezone en UTC
USE_TZ = False
# django crispy_forms
CRISPY_TEMPLATE_PACK = 'bootstrap4'
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.1/howto/static-files/
STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static'), ]
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATICFILES_FINDERS = [
"django.contrib.staticfiles.finders.FileSystemFinder",
"django.contrib.staticfiles.finders.AppDirectoriesFinder",
]

# redirections when a user login or logout of our app
LOGIN_REDIRECT_URL = "pages:bienvenida"
LOGOUT_REDIRECT_URL = "pages:bienvenida"
# configuraciones para enviar correos electrónicos de cambio de contraseña
EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
DEFAULT_FROM_EMAIL = os.environ.get('DEFAULT_FROM_EMAIL')
EMAIL_HOST = os.environ.get('EMAIL_HOST')
EMAIL_HOST_USER = os.environ.get('EMAIL_HOST_USER')
EMAIL_HOST_PASSWORD = (
os.environ.get('EMAIL_HOST_PASSWORD')
)
EMAIL_PORT = os.environ.get('EMAIL_PORT')
EMAIL_USE_TLS = True
# allauth configuration
SITE_ID = 1
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
'allauth.account.auth_backends.AuthenticationBackend',
)
SOCIALACCOUNT_PROVIDERS = {
'google': {
'SCOPE': [
'profile',
'email',
],
'AUTH_PARAMS': {
'access_type': 'online',
}
}
}
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_UNIQUE_EMAIL = True
ACCOUNT_EMAIL_VERIFICATION = 'mandatory'
# django-debug-toolbar
hostname, _, ips = socket.gethostbyname_ex(socket.gethostname())
INTERNAL_IPS = [ip[:-1] + "1" for ip in ips]
# production
if ENVIRONMENT == 'production':
SECURE_BROWSER_XSS_FILTER = True
X_FRAME_OPTIONS = 'DENY'
SECURE_SSL_REDIRECT = True
SECURE_HSTS_SECONDS = 3600
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
SECURE_CONTENT_TYPE_NOSNIFF = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
# Heroku
db_from_env = dj_database_url.config(conn_max_age=500)
DATABASES['default'].update(db_from_env)

docker-compose.yml

version: '3.8'
services:
web:
build: .
# command: python /code/manage.py runserver 0.0.0.0:8001
command: gunicorn clothes_shop_project.wsgi -b 0.0.0.0:8001
environment: 
- ENVIRONMENT=development
- SECRET_KEY=<secret_key>
- DEFAULT_FROM_EMAIL=<email>
- EMAIL_HOST=smtp.sendgrid.net
- EMAIL_HOST_USER=apikey
- EMAIL_HOST_PASSWORD=<email_host_password>
- EMAIL_PORT=<port>
- DEBUG=1
volumes:
- .:/code
ports:
- 8001:8001
depends_on:
- db
db:
image: postgres:11
volumes:
- postgres_data:/var/lib/postgresql/data/
environment:
- "POSTGRES_HOST_AUTH_METHOD=trust"
volumes:
postgres_data:

docker-compose-prod.yml

version: '3.8'
services:
web:
build: .
# command: python /code/manage.py runserver 0.0.0.0:8001
command: gunicorn clothes_shop_project.wsgi -b 0.0.0.0:8001
environment: 
- ENVIRONMENT=production
- SECRET_KEY=71dmqf6x1k^bnns1p!kkld7tq%=p!s)%r&f5h2y@^eq4h8i86$$
- DEFAULT_FROM_EMAIL=luckly083@gmail.com
- EMAIL_HOST=smtp.sendgrid.net
- EMAIL_HOST_USER=apikey
- EMAIL_HOST_PASSWORD=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
- EMAIL_PORT=587
- DEBUG=0
ports:
- 8001:8001
depends_on:
- db
db:
image: postgres:11
environment:
- "POSTGRES_HOST_AUTH_METHOD=trust"

Dockerfile

# Pull base image
FROM python:3.8
# Set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# Set work directory
WORKDIR /code
# Install dependencies
COPY Pipfile Pipfile.lock /code/
RUN pip install --upgrade pip
RUN pip install pipenv && pipenv install --system
# Copy project
COPY . /code/

heroku.yml

setup:
addons:
- plan: heroku-postgresql
build:
docker:
web: Dockerfile
release:
image: web
command:
- python manage.py collectstatic --noinput
run:
web: gunicorn clothes_shop_project.wsgi

问题发生在我执行python manage.py collectstatic --noinput时,控制台显示的错误如下:

2021-03-18T23:01:40.412515+00:00 app[release.7010]: Traceback (most recent call last):
2021-03-18T23:01:40.412541+00:00 app[release.7010]: File "manage.py", line 22, in <module>
2021-03-18T23:01:40.412547+00:00 app[release.7010]: main()
2021-03-18T23:01:40.412548+00:00 app[release.7010]: File "manage.py", line 18, in main
2021-03-18T23:01:40.412644+00:00 app[release.7010]: execute_from_command_line(sys.argv)
2021-03-18T23:01:40.412646+00:00 app[release.7010]: File "/usr/local/lib/python3.8/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
2021-03-18T23:01:40.413128+00:00 app[release.7010]: utility.execute()
2021-03-18T23:01:40.413149+00:00 app[release.7010]: File "/usr/local/lib/python3.8/site-packages/django/core/management/__init__.py", line 395, in execute
2021-03-18T23:01:40.413422+00:00 app[release.7010]: self.fetch_command(subcommand).run_from_argv(self.argv)
2021-03-18T23:01:40.413423+00:00 app[release.7010]: File "/usr/local/lib/python3.8/site-packages/django/core/management/base.py", line 330, in run_from_argv
2021-03-18T23:01:40.413711+00:00 app[release.7010]: self.execute(*args, **cmd_options)
2021-03-18T23:01:40.413811+00:00 app[release.7010]: File "/usr/local/lib/python3.8/site-packages/django/core/management/base.py", line 371, in execute
2021-03-18T23:01:40.414107+00:00 app[release.7010]: output = self.handle(*args, **options)
2021-03-18T23:01:40.414108+00:00 app[release.7010]: File "/usr/local/lib/python3.8/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 194, in handle
2021-03-18T23:01:40.414353+00:00 app[release.7010]: collected = self.collect()
2021-03-18T23:01:40.414354+00:00 app[release.7010]: File "/usr/local/lib/python3.8/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 109, in collect
2021-03-18T23:01:40.414518+00:00 app[release.7010]: for path, storage in finder.list(self.ignore_patterns):
2021-03-18T23:01:40.414519+00:00 app[release.7010]: File "/usr/local/lib/python3.8/site-packages/django/contrib/staticfiles/finders.py", line 130, in list
2021-03-18T23:01:40.414613+00:00 app[release.7010]: for path in utils.get_files(storage, ignore_patterns):
2021-03-18T23:01:40.414614+00:00 app[release.7010]: File "/usr/local/lib/python3.8/site-packages/django/contrib/staticfiles/utils.py", line 23, in get_files
2021-03-18T23:01:40.414811+00:00 app[release.7010]: directories, files = storage.listdir(location)
2021-03-18T23:01:40.414811+00:00 app[release.7010]: File "/usr/local/lib/python3.8/site-packages/django/core/files/storage.py", line 316, in listdir
2021-03-18T23:01:40.414998+00:00 app[release.7010]: for entry in os.scandir(path):
2021-03-18T23:01:40.415096+00:00 app[release.7010]: FileNotFoundError: [Errno 2] No such file or directory: '/code/static'

如果您还没有解决这个问题?这对我很有效。在您的设置.py中,删除以下行:

STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static'), ]
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

并将其替换为

PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_ROOT  =   os.path.join(PROJECT_ROOT, 'staticfiles')

然后创建一个名为"的文件夹;静态";并创建一个文件并将其命名为.anything_you_like,否则它将不会保存。

Ps注意:不要忘记导入os

Ps注意:我会建议你使用白化为你的路径查找

相关内容

最新更新